]> git.tdb.fi Git - r2c2.git/commitdiff
New approach for displaying track state
authorMikko Rasa <tdb@tdb.fi>
Sat, 20 Jul 2013 16:03:17 +0000 (19:03 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sat, 20 Jul 2013 16:03:17 +0000 (19:03 +0300)
Paths can now be displayed over either rail in addition to the center of
the track.  Track circuit and allocation state are displayed separately,
allowing more information to be shown.

Instead of pre-creating a path for each track, only create them as needed.
Local controller objects are much more manageable than bundling everything
into one giant class.

22 files changed:
source/3d/allocation.cpp [new file with mode: 0644]
source/3d/allocation.h [new file with mode: 0644]
source/3d/layout.cpp
source/3d/layout.h
source/3d/path.cpp
source/3d/path.h
source/3d/track.cpp
source/3d/track.h
source/3d/trackcircuit.cpp [new file with mode: 0644]
source/3d/trackcircuit.h [new file with mode: 0644]
source/3d/tracktype.cpp
source/3d/tracktype.h
source/3d/utility.cpp [new file with mode: 0644]
source/3d/utility.h [new file with mode: 0644]
source/designer/designer.cpp
source/designer/designer.h
source/engineer/engineer.cpp
source/engineer/engineer.h
source/libr2c2/catalogue.cpp
source/libr2c2/catalogue.h
source/libr2c2/trackchain.cpp
source/libr2c2/trackchain.h

diff --git a/source/3d/allocation.cpp b/source/3d/allocation.cpp
new file mode 100644 (file)
index 0000000..4bafb11
--- /dev/null
@@ -0,0 +1,74 @@
+#include "libr2c2/block.h"
+#include "allocation.h"
+#include "layout.h"
+#include "path.h"
+#include "track.h"
+
+using namespace Msp;
+
+namespace R2C2 {
+
+Allocation3D::Allocation3D(Layout3D &l, Train &t):
+       Utility3D(l),
+       train(t)
+{
+       layout.get_layout().signal_block_reserved.connect(sigc::mem_fun(this, &Allocation3D::block_reserved));
+       train.signal_advanced.connect(sigc::mem_fun(this, &Allocation3D::train_advanced));
+}
+
+void Allocation3D::set_color(const GL::Color &c)
+{
+       color = c;
+       for(PathMap::const_iterator i=paths.begin(); i!=paths.end(); ++i)
+       {
+               float intensity = 0.5+train.get_block_allocator().is_block_current(*i->first)*0.5;
+               for(PathList::const_iterator j=i->second.begin(); j!=i->second.end(); ++j)
+                       (*j)->set_color(color*intensity);
+       }
+}
+
+void Allocation3D::block_reserved(Block &block, Train *t)
+{
+       if(t && t!=&train)
+               return;
+
+       if(t)
+       {
+               if(paths.count(&block))
+                       return;
+
+               PathList &bpaths = paths[&block];
+               const Block::TrackSet &tracks = block.get_tracks();
+               for(Block::TrackSet::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
+               {
+                       Path3D *path = new Path3D(layout.get<Track3D>(**i));
+                       bpaths.push_back(path);
+                       path->set_layer(1);
+                       float intensity = 0.5+train.get_block_allocator().is_block_current(block)*0.5;
+                       path->set_color(color*intensity);
+                       path->set_automatic();
+               }
+       }
+       else
+       {
+               PathMap::iterator i = paths.find(&block);
+               if(i==paths.end())
+                       return;
+
+               for(PathList::iterator j=i->second.begin(); j!=i->second.end(); ++j)
+                       delete *j;
+               paths.erase(i);
+       }
+}
+
+void Allocation3D::train_advanced(Block &block)
+{
+       PathMap::iterator i = paths.find(&block);
+       if(i==paths.end())
+               return;
+
+       for(PathList::iterator j=i->second.begin(); j!=i->second.end(); ++j)
+               (*j)->set_color(color);
+}
+
+} // namespace R2C2
diff --git a/source/3d/allocation.h b/source/3d/allocation.h
new file mode 100644 (file)
index 0000000..87ea309
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef R2C2_3D_ALLOCATION_H_
+#define R2C2_3D_ALLOCATION_H_
+
+#include <msp/gl/color.h>
+#include "libr2c2/train.h"
+#include "utility.h"
+
+namespace R2C2 {
+
+class Layout3D;
+class Path3D;
+
+class Allocation3D: public Utility3D, public sigc::trackable
+{
+private:
+       typedef std::list<Path3D *> PathList;
+       typedef std::map<Block *, PathList> PathMap;
+
+       Train &train;
+       Msp::GL::Color color;
+       PathMap paths;
+
+public:
+       Allocation3D(Layout3D &, Train &);
+
+       void set_color(const Msp::GL::Color &);
+
+private:
+       void block_reserved(Block &, Train *);
+       void train_advanced(Block &);
+};
+
+} // namespace R2C2
+
+#endif
index 1bbbed825bb68f493547046fa8051a60fbdb8b1b..72e5052e6689c5f2058b83b5d9e03c75098bf895 100644 (file)
@@ -2,6 +2,7 @@
 #include "layout.h"
 #include "signal.h"
 #include "track.h"
+#include "utility.h"
 #include "vehicle.h"
 
 using namespace std;
@@ -27,6 +28,8 @@ Layout3D::Layout3D(Layout &l):
 
 Layout3D::~Layout3D()
 {
+       while(!utilities.empty())
+               delete *utilities.begin();
        while(!objects.empty())
                delete objects.begin()->second;
 }
@@ -57,6 +60,16 @@ void Layout3D::remove(Object3D &o)
        objects.erase(&o.get_object());
 }
 
+void Layout3D::add(Utility3D &u)
+{
+       utilities.insert(&u);
+}
+
+void Layout3D::remove(Utility3D &u)
+{
+       utilities.erase(&u);
+}
+
 void Layout3D::object_added(Object &o)
 {
        if(Track *t = dynamic_cast<Track *>(&o))
index df414f2578b0cc5f85ffe7a88f01f1ffb4e87ad3..d5aad2634fbbe2343f4f2d38027347b531957f2b 100644 (file)
@@ -12,6 +12,7 @@
 namespace R2C2 {
 
 class Object3D;
+class Utility3D;
 
 class Layout3D: public sigc::trackable
 {
@@ -22,6 +23,7 @@ private:
        Layout &layout;
        Catalogue3D catalogue;
        ObjectMap objects;
+       std::set<Utility3D *> utilities;
        Msp::GL::InstanceScene scene;
        Msp::GL::SimpleScene ep_scene;
        Msp::GL::InstanceScene path_scene;
@@ -46,6 +48,9 @@ public:
        T &get(Object &o) const
        { return dynamic_cast<T &>(get(o)); }
 
+       void add(Utility3D &);
+       void remove(Utility3D &);
+
        Msp::GL::Scene &get_scene() { return scene; }
        Msp::GL::Scene &get_endpoint_scene() { return ep_scene; }
        Msp::GL::Scene &get_path_scene() { return path_scene; }
index 816631b8307a8f289f436e41c0f7e71d17b1f577..f9e51f4974a790efa0fb51e141ee7256efebbd85 100644 (file)
@@ -12,17 +12,24 @@ using namespace Msp;
 namespace R2C2 {
 
 Path3D::Path3D(const Track3D &t):
+       Utility3D(t.get_layout()),
        track(t),
-       paths(0),
+       path(t.get_track().get_active_path()),
+       side(0),
        automatic(true),
+       mesh(0),
        z_offs(0)
 {
-       track.get_layout().get_path_scene().add(*this);
+       update_mesh();
+
+       layout.get_path_scene().add(*this);
+       if(track.get_track().get_type().is_turnout())
+               track.get_track().signal_path_changed.connect(sigc::mem_fun(this, &Path3D::path_changed));
 }
 
 Path3D::~Path3D()
 {
-       track.get_layout().get_path_scene().remove(*this);
+       layout.get_path_scene().remove(*this);
 }
 
 void Path3D::set_automatic()
@@ -30,20 +37,19 @@ void Path3D::set_automatic()
        automatic = true;
 }
 
-void Path3D::set_path(unsigned p)
+void Path3D::set_path(int p)
 {
-       if(!(track.get_track().get_type().get_paths()&(1<<p)))
+       if(p>=0 && !(track.get_track().get_type().get_paths()&(1<<p)))
                throw invalid_argument("Path3D::set_path");
        automatic = false;
-       paths = 1<<p;
+       path = p;
+       update_mesh();
 }
 
-void Path3D::set_mask(unsigned p)
+void Path3D::set_side(int s)
 {
-       if(p&~track.get_track().get_type().get_paths())
-               throw invalid_argument("Path3D::set_mask");
-       automatic = false;
-       paths = p;
+       side = (s<0 ? -1 : s>0 ? 1 : 0);
+       update_mesh();
 }
 
 void Path3D::set_color(const GL::Color &c)
@@ -53,7 +59,21 @@ void Path3D::set_color(const GL::Color &c)
 
 void Path3D::set_layer(float l)
 {
-       z_offs = l*track.get_track().get_layout().get_catalogue().get_gauge()*0.01;
+       z_offs = l*layout.get_layout().get_catalogue().get_gauge()*0.01;
+}
+
+void Path3D::path_changed(unsigned p)
+{
+       if(automatic)
+       {
+               path = p;
+               update_mesh();
+       }
+}
+
+void Path3D::update_mesh()
+{
+       mesh = &track.get_type().get_path_mesh(path, side);
 }
 
 long Path3D::get_instance_key() const
@@ -65,19 +85,12 @@ void Path3D::render(GL::Renderer &renderer, const GL::Tag &tag) const
 {
        if(tag=="unlit")
        {
-               unsigned mask = (automatic ? 1<<track.get_track().get_active_path() : paths);
-               mask &= track.get_track().get_type().get_paths();
-               if(!mask)
-                       return;
-
                GL::MatrixStack::Push push_mtx(renderer.matrix_stack());
                renderer.matrix_stack() *= track.Object3D::get_matrix();
                renderer.matrix_stack() *= GL::Matrix::translation(0, 0, z_offs);
 
                glColor4f(color.r, color.g, color.b, color.a);
-               for(unsigned i=0; mask; ++i, mask>>=1)
-                       if(mask&1)
-                               track.get_type().get_path_mesh(i).draw(renderer);
+               mesh->draw(renderer);
        }
 }
 
index 58dae2435d8fe4cb87036d2857035273e31bbf2a..ceeb178ce04c6b11fa67e63792ce4f054fb70ba3 100644 (file)
@@ -4,17 +4,20 @@
 #include <msp/gl/color.h>
 #include <msp/gl/mesh.h>
 #include <msp/gl/renderable.h>
+#include "utility.h"
 
 namespace R2C2 {
 
 class Track3D;
 
-class Path3D: public Msp::GL::Renderable
+class Path3D: public Utility3D, public Msp::GL::Renderable, public sigc::trackable
 {
 private:
        const Track3D &track;
-       unsigned paths;
+       int path;
+       int side;
        bool automatic;
+       const Msp::GL::Mesh *mesh;
        Msp::GL::Color color;
        float z_offs;
 
@@ -23,11 +26,15 @@ public:
        ~Path3D();
 
        void set_automatic();
-       void set_path(unsigned);
-       void set_mask(unsigned);
+       void set_path(int);
+       void set_side(int);
        void set_color(const Msp::GL::Color &);
        void set_layer(float);
+private:
+       void path_changed(unsigned);
+       void update_mesh();
 
+public:
        virtual long get_instance_key() const;
 
        virtual void render(Msp::GL::Renderer &, const Msp::GL::Tag &) const;
index 0fa6344ce7709b9faab370566d05cb0e119517d5..ee7671c8886ef337e6fee36ebe9d05d3d2b9b0e1 100644 (file)
@@ -17,8 +17,7 @@ Track3D::Track3D(Layout3D &l, Track &t):
        Object3D(l, t),
        GL::ObjectInstance(l.get_catalogue().get_track(t.get_type()).get_object()),
        track(t),
-       type(layout.get_catalogue().get_track(track.get_type())),
-       path(new Path3D(*this))
+       type(layout.get_catalogue().get_track(track.get_type()))
 {
        layout.get_scene().add(*this);
 
@@ -37,8 +36,6 @@ Track3D::Track3D(Layout3D &l, Track &t):
 
 Track3D::~Track3D()
 {
-       delete path;
-
        layout.get_scene().remove(*this);
 
        for(vector<Endpoint3D *>::iterator i=endpoints.begin(); i!=endpoints.end(); ++i)
index c66a65f969bae0b7dc08f23c4768401e17e502ea..9b70b630a5fd1f0a7e88bf418b21a66629901b1e 100644 (file)
@@ -21,7 +21,6 @@ private:
        Track &track;
        const TrackType3D &type;
        std::vector<Endpoint3D *> endpoints;
-       Path3D *path;
 
 public:
        Track3D(Layout3D &, Track &);
@@ -30,7 +29,6 @@ public:
        Layout3D &get_layout() const { return layout; }
        Track &get_track() const { return track; }
        const TrackType3D &get_type() const { return type; }
-       Path3D &get_path() { return *path; }
 
        virtual Vector get_node() const;
        virtual bool is_visible() const { return true; }
diff --git a/source/3d/trackcircuit.cpp b/source/3d/trackcircuit.cpp
new file mode 100644 (file)
index 0000000..d74ee20
--- /dev/null
@@ -0,0 +1,44 @@
+#include "libr2c2/blockiter.h"
+#include "libr2c2/trackiter.h"
+#include "layout.h"
+#include "path.h"
+#include "track.h"
+#include "trackcircuit.h"
+
+using namespace std;
+using namespace Msp;
+
+namespace R2C2 {
+
+TrackCircuit3D::TrackCircuit3D(Layout3D &l, TrackCircuit &tc):
+       Utility3D(l),
+       track_circuit(tc)
+{
+       Block *block = track_circuit.get_block();
+       TrackIter iter = BlockIter(block, 0).track_iter();
+       for(; (iter && &iter->get_block()==block); iter=iter.next())
+       {
+               Path3D *path = new Path3D(layout.get<Track3D>(*iter));
+               paths.push_back(path);
+               path->set_side(iter.entry()*2-1);
+       }
+
+       track_circuit.signal_state_changed.connect(sigc::mem_fun(this, &TrackCircuit3D::state_changed));
+       state_changed(track_circuit.get_state());
+}
+
+void TrackCircuit3D::state_changed(Sensor::State state)
+{
+       GL::Color color;
+       if(state>=Sensor::ACTIVE)
+               color = GL::Color(0.3f, 0.8f, 0.0f);
+       else if(state>Sensor::INACTIVE)
+               color = GL::Color(0.6f, 0.5f, 0.0f);
+       else
+               color = GL::Color(0.0f, 0.3f, 0.6f);
+
+       for(list<Path3D *>::const_iterator i=paths.begin(); i!=paths.end(); ++i)
+               (*i)->set_color(color);
+}
+
+} // namespace R2C2
diff --git a/source/3d/trackcircuit.h b/source/3d/trackcircuit.h
new file mode 100644 (file)
index 0000000..ae032b0
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef R2C2_TRACKCIRCUIT_H_
+#define R2C2_TRACKCIRCUIT_H_
+
+#include <libr2c2/trackcircuit.h>
+#include "utility.h"
+
+namespace R2C2 {
+
+class Layout3D;
+class Path3D;
+
+class TrackCircuit3D: public Utility3D, public sigc::trackable
+{
+private:
+       TrackCircuit &track_circuit;
+       std::list<Path3D *> paths;
+
+public:
+       TrackCircuit3D(Layout3D &, TrackCircuit &);
+
+private:
+       void state_changed(Sensor::State);
+};
+
+} // namespace R2C2
+
+#endif
index e402c89c5f597823e6daabde9943ef27b30d72bb..f6b3d5fb8b053635cbb1732c9885860f59cc61e6 100644 (file)
@@ -57,28 +57,45 @@ TrackType3D::TrackType3D(Catalogue3D &cat3d, const TrackType &tt):
 
                own_data = true;
        }
+
        unsigned paths = tt.get_paths();
-       for(unsigned i=0; paths; ++i, paths>>=1)
+       for(int i=-1; i<=1; ++i)
        {
-               GL::Mesh *m = 0;
-               if(paths&1)
+               // TODO Make profile width configurable
+               Profile profile;
+               if(i==0)
+               {
+                       float rail_w = (rail_max.x-rail_min.x)*2;
+                       profile.append_vertex(Vector(rail_w*-0.5, 0, 0), false);
+                       profile.append_vertex(Vector(rail_w*0.5, 0, 0), false);
+               }
+               else
                {
-                       m = new GL::Mesh(GL::VERTEX3);
+                       profile.append_vertex(Vector(i*(gauge*0.5+rail_min.x*2), 0, 0), false);
+                       profile.append_vertex(Vector(i*(gauge*0.5+rail_max.x*2), 0, 0), false);
+               }
+
+               // TODO Avoid generating redundant meshes for single-path tracks
+               for(int j=-1; j<=4; ++j)
+               {
+                       if(j>=0 && !((paths>>j)&1))
+                               continue;
+
+                       GL::Mesh *m = new GL::Mesh(GL::VERTEX3);
                        GL::MeshBuilder bld(*m);
                        unsigned index = 0;
-                       for(vector<TrackPart>::const_iterator j=parts.begin(); j!=parts.end(); ++j)
-                               if(j->get_path()==i)
-                                       build_part(*j, cat.get_path_profile(), Vector(0, 0, ballast_h+1.5*rail_h), false, bld, index);
+                       for(vector<TrackPart>::const_iterator k=parts.begin(); k!=parts.end(); ++k)
+                               if(j<0 || k->get_path()==static_cast<unsigned>(j))
+                                       build_part(*k, profile, Vector(0, 0, ballast_h+1.5*rail_h), false, bld, index);
+                       path_meshes[(j&0xFF)|((i&3)<<8)] = m;
                }
-               path_meshes.push_back(m);
        }
 }
 
 TrackType3D::~TrackType3D()
 {
-       for(vector<GL::Mesh *>::iterator i=path_meshes.begin(); i!=path_meshes.end(); ++i)
-               delete *i;
+       for(map<unsigned, GL::Mesh *>::iterator i=path_meshes.begin(); i!=path_meshes.end(); ++i)
+               delete i->second;
        if(own_data)
        {
                delete object;
@@ -86,13 +103,10 @@ TrackType3D::~TrackType3D()
        }
 }
 
-const GL::Mesh &TrackType3D::get_path_mesh(unsigned p) const
+const GL::Mesh &TrackType3D::get_path_mesh(int p, int s) const
 {
-       if(p>=path_meshes.size())
-               throw out_of_range("TrackType3D::get_path_mesh");
-       if(!path_meshes[p])
-               throw invalid_argument("TrackType3D::get_path_mesh");
-       return *path_meshes[p];
+       unsigned key = (p<0 ? 0xFF : p) | ((s&3)<<8);
+       return *get_item(path_meshes, key);
 }
 
 void TrackType3D::build_part(const TrackPart &part, const Profile &profile, const Vector &offset, bool mirror, GL::MeshBuilder &bld, unsigned &base_index)
index 952e8986b17365ee52112fd25a03b9b02e4f0c86..27bf7fe97723ec8e9e0c39d2f4b63ade8bcd0c89 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef R2C2_3D_TRACKTYPE_H_
 #define R2C2_3D_TRACKTYPE_H_
 
+#include <map>
 #include <msp/gl/mesh.h>
 #include <msp/gl/meshbuilder.h>
 #include <msp/gl/object.h>
@@ -18,14 +19,14 @@ private:
        Msp::GL::Mesh *mesh;
        Msp::GL::Object *object;
        bool own_data;
-       std::vector<Msp::GL::Mesh *> path_meshes;
+       std::map<unsigned, Msp::GL::Mesh *> path_meshes;
 
 public:
        TrackType3D(Catalogue3D &, const TrackType &);
        ~TrackType3D();
 
        const Msp::GL::Object &get_object() const { return *object; }
-       const Msp::GL::Mesh &get_path_mesh(unsigned) const;
+       const Msp::GL::Mesh &get_path_mesh(int, int) const;
 
 private:
        void build_part(const TrackPart &, const Profile &, const Vector &, bool, Msp::GL::MeshBuilder &, unsigned &);
diff --git a/source/3d/utility.cpp b/source/3d/utility.cpp
new file mode 100644 (file)
index 0000000..d7026f2
--- /dev/null
@@ -0,0 +1,17 @@
+#include "layout.h"
+#include "utility.h"
+
+namespace R2C2 {
+
+Utility3D::Utility3D(Layout3D &l):
+       layout(l)
+{
+       layout.add(*this);
+}
+
+Utility3D::~Utility3D()
+{
+       layout.remove(*this);
+}
+
+} // namespace R2C2
diff --git a/source/3d/utility.h b/source/3d/utility.h
new file mode 100644 (file)
index 0000000..f448164
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef R2C2_3D_UTILITY_H_
+#define R2C2_3D_UTILITY_H_
+
+namespace R2C2 {
+
+class Layout3D;
+
+class Utility3D
+{
+protected:
+       Layout3D &layout;
+
+       Utility3D(Layout3D &);
+public:
+       virtual ~Utility3D();
+};
+
+} // namespace R2C2
+
+#endif
index 930df589b7f7726d3b8f9a8af9aa223dbbaf4de4..3c3f83c903bb4592a712af1f039c957c63b91e8a 100644 (file)
@@ -68,9 +68,6 @@ Designer::Designer(int argc, char **argv):
        layout = new Layout(catalogue);
        layout_3d = new Layout3D(*layout);
 
-       layout->signal_object_added.connect(sigc::mem_fun(this, &Designer::object_added));
-       layout->signal_object_removed.connect(sigc::mem_fun(this, &Designer::object_removed));
-
        if(argc>1)
        {
                filename = argv[1];
@@ -361,10 +358,6 @@ void Designer::tick()
        root.tick();
        camera_ctl->tick(dt);
 
-       for(list<Track *>::iterator i=new_tracks.begin(); i!=new_tracks.end(); ++i)
-               layout_3d->get<Track3D>(**i).get_path().set_mask(0);
-       new_tracks.clear();
-
        render();
 
        window.swap_buffers();
@@ -525,22 +518,6 @@ void Designer::render()
        root.render();
 }
 
-void Designer::object_added(Object &obj)
-{
-       if(Track *trk = dynamic_cast<Track *>(&obj))
-               new_tracks.push_back(trk);
-}
-
-void Designer::object_removed(Object &obj)
-{
-       if(Track *trk = dynamic_cast<Track *>(&obj))
-       {
-               list<Track *>::iterator i = find(new_tracks.begin(), new_tracks.end(), trk);
-               if(i!=new_tracks.end())
-                       new_tracks.erase(i);
-       }
-}
-
 Object *Designer::pick_object(const Vector &pointer)
 {
        View3D &view = *(mode==CATALOGUE ? cat_view : main_view);
@@ -656,12 +633,9 @@ string Designer::tooltip(int x, int y)
 
 void Designer::clear_paths()
 {
-       const set<Track *> &ltracks = layout->get_all<Track>();
-       for(set<Track *>::iterator i=ltracks.begin(); i!=ltracks.end(); ++i)
-       {
-               Track3D &t3d = layout_3d->get<Track3D>(**i);
-               t3d.get_path().set_mask(0);
-       }
+       for(list<Path3D *>::iterator i=highlight_paths.begin(); i!=highlight_paths.end(); ++i)
+               delete *i;
+       highlight_paths.clear();
 }
 
 void Designer::show_route(const Route &route)
@@ -672,14 +646,10 @@ void Designer::show_route(const Route &route)
        for(set<Track *>::iterator i=rtracks.begin(); i!=rtracks.end(); ++i)
        {
                Track3D &t3d = layout_3d->get<Track3D>(**i);
-               t3d.get_path().set_color(GL::Color(0.5, 0.8, 1.0));
-               int path = -1;
+               Path3D *path = new Path3D(t3d);
+               path->set_color(GL::Color(0.5, 0.8, 1.0));
                if(unsigned tid = (*i)->get_turnout_id())
-                       path = route.get_turnout(tid);
-               if(path>=0)
-                       t3d.get_path().set_path(path);
-               else
-                       t3d.get_path().set_mask((*i)->get_type().get_paths());
+                       path->set_path(route.get_turnout(tid));
        }
 }
 
@@ -691,7 +661,7 @@ void Designer::show_zone(const Zone &zone)
        for(Zone::TrackSet::const_iterator i=ztracks.begin(); i!=ztracks.end(); ++i)
        {
                Track3D &t3d = layout_3d->get<Track3D>(**i);
-               t3d.get_path().set_color(GL::Color(0.8, 1.0, 0.5));
-               t3d.get_path().set_mask((*i)->get_type().get_paths());
+               Path3D *path = new Path3D(t3d);
+               path->set_color(GL::Color(0.8, 1.0, 0.5));
        }
 }
index b78ad81becf8db1650f4b9d8a691269148743c4d..02649cb24836b20ff6d3625bc48b3b3657123161 100644 (file)
@@ -63,7 +63,7 @@ private:
        Msp::GL::Object *base_object;
        R2C2::Route *cur_route;
        R2C2::Zone *cur_zone;
-       std::list<R2C2::Track *> new_tracks;
+       std::list<R2C2::Path3D *> highlight_paths;
 
        Mode mode;
        Selection selection;
@@ -113,8 +113,6 @@ private:
        void axis_motion(unsigned, float, float);
        void apply_camera();
        void render();
-       void object_added(R2C2::Object &);
-       void object_removed(R2C2::Object &);
        R2C2::Object *pick_object(const R2C2::Vector &);
        void update_track_icon(R2C2::Track3D &);
        void selection_changed();
index 8c1738eb0603d4e152a20afe7344d5f4e1ba814d..f0999d91cd9ffaddd1736f0c6fd6493e36077084 100644 (file)
 #include "libr2c2/driver.h"
 #include "libr2c2/trackcircuit.h"
 #include "libr2c2/tracktype.h"
+#include "3d/allocation.h"
 #include "3d/path.h"
 #include "3d/track.h"
+#include "3d/trackcircuit.h"
 #include "3d/vehicle.h"
 #include "engineer.h"
 #include "mainwindow.h"
@@ -70,12 +72,16 @@ Engineer::Engineer(int argc, char **argv):
        DataFile::load(layout, options.layout_fn);
 
        layout.signal_train_added.connect(sigc::mem_fun(this, &Engineer::train_added));
-       layout.signal_block_reserved.connect(sigc::hide<1>(sigc::mem_fun(this, &Engineer::reset_block_color)));
        layout.signal_emergency.connect(sigc::mem_fun(this, &Engineer::set_status));
        const set<Block *> &blocks = layout.get_all<Block>();
        for(set<Block *>::const_iterator i=blocks.begin(); i!=blocks.end(); ++i)
-               if(Sensor *sensor = (*i)->get_sensor())
-                       sensor->signal_state_changed.connect(sigc::hide(sigc::bind(sigc::mem_fun(this, &Engineer::reset_block_color), sigc::ref(**i))));
+               if(TrackCircuit *tc = (*i)->get_sensor())
+                       new TrackCircuit3D(layout_3d, *tc);
+
+       const set<Track *> &tracks = layout.get_all<Track>();
+       for(set<Track *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
+               if((*i)->get_type().is_turnout())
+                       new Path3D(layout_3d.get<Track3D>(**i));
 
        if(FS::exists(options.state_fn))
                DataFile::load(layout, options.state_fn);
@@ -208,12 +214,8 @@ void Engineer::tick()
 
                                delete picking_path;
                                picking_path = new Path3D(layout_3d.get<Track3D>(*track));
-                               if(picking_entry>=0)
-                                       picking_path->set_mask(picking_track->get_type().get_endpoint(picking_entry).paths);
-                               else
-                                       picking_path->set_mask(picking_track->get_type().get_paths());
                                picking_path->set_color(GL::Color(0));
-                               picking_path->set_layer(1);
+                               picking_path->set_layer(2);
                        }
                }
        }
@@ -250,7 +252,6 @@ void Engineer::button_press(unsigned btn)
                else if(btn==3 && picking_entry>=0)
                {
                        picking_entry = (picking_entry+1)%picking_track->get_type().get_endpoints().size();
-                       picking_path->set_mask(picking_track->get_type().get_endpoint(picking_entry).paths);
                }
        }
        else
@@ -350,37 +351,6 @@ void Engineer::view_all()
        camera.set_depth_clip(pos.z*0.5, pos.z*1.5);
 }
 
-void Engineer::set_block_color(const Block &block, const GL::Color &color)
-{
-       const set<Track *> &tracks = block.get_tracks();
-       for(set<Track *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
-               layout_3d.get<Track3D>(**i).get_path().set_color(color);
-}
-
-void Engineer::reset_block_color(const Block &block)
-{
-       bool active = false;
-       if(Sensor *sensor = block.get_sensor())
-               active = sensor->get_state()>Sensor::INACTIVE;
-
-       if(block.get_train())
-       {
-               GL::Color color;
-               map<Train *, GL::Color>::iterator i = train_colors.find(block.get_train());
-               if(i!=train_colors.end())
-                       color = i->second;
-
-               if(active)
-                       set_block_color(block, color*0.6);
-               else
-                       set_block_color(block, color*0.5+0.5);
-       }
-       else if(active)
-               set_block_color(block, GL::Color(0.6));
-       else
-               set_block_color(block, GL::Color(1));
-}
-
 Object *Engineer::pick_object(const Vector &p)
 {
        const GL::Vector3 &start = camera.get_position();
@@ -430,6 +400,9 @@ void Engineer::train_added(Train &train)
                }
        }
        train_colors[&train] = best_color;
+
+       Allocation3D *alloc = new Allocation3D(layout_3d, train);
+       alloc->set_color(best_color);
 }
 
 void Engineer::sighandler(int sig)
index 7997242e17cf0c82409e08d80b376d2e86c68566..d7fb2b859ed61408abb4bff097db1642ab096674 100644 (file)
@@ -80,8 +80,6 @@ private:
        void button_press(unsigned);
        void axis_motion(unsigned, float, float);
        void view_all();
-       void set_block_color(const R2C2::Block &, const Msp::GL::Color &);
-       void reset_block_color(const R2C2::Block &);
        void sensor_event(unsigned, bool);
        void block_reserved(const R2C2::Block &, const R2C2::Train *);
        R2C2::Object *pick_object(const R2C2::Vector &);
index ec3e95a7d00a2ed45c222a2932c9d5c66491d1ab..ab268cd84eeb2bc7a47a72d7665ee034c7537c8c 100644 (file)
@@ -88,9 +88,6 @@ void Catalogue::Loader::ballast_profile()
 void Catalogue::Loader::gauge(float g)
 {
        obj.gauge = g/1000;
-       obj.path_profile = Profile();
-       obj.path_profile.append_vertex(Vector(0.1*obj.gauge, 0, 0), false);
-       obj.path_profile.append_vertex(Vector(-0.1*obj.gauge, 0, 0), false);
 }
 
 void Catalogue::Loader::layout()
index 12ee006f45f34a1fcb5e7e399f39356e470c3236..d13c9821d67cad4c3cc09fcb4d42e57902cdb52a 100644 (file)
@@ -44,7 +44,6 @@ private:
        float gauge;
        Profile rail_profile;
        Profile ballast_profile;
-       Profile path_profile;
        std::string track_technique;
        TrackMap tracks;
        VehicleMap vehicles;
@@ -60,7 +59,6 @@ public:
        float get_rail_elevation() const;
        const Profile &get_rail_profile() const { return rail_profile; }
        const Profile &get_ballast_profile() const { return ballast_profile; }
-       const Profile &get_path_profile() const { return path_profile; }
        const std::string &get_track_technique() const { return track_technique; }
 
        void add_track(TrackType &);
index 3d9d66a915e78bc5ecf7b50da83ac7bf9a340922..bb4e77b6321a93998b3f1232f1f49ec00c2befde 100644 (file)
@@ -23,6 +23,7 @@ void TrackChain::add_track(Track &track)
        tracks.insert(&track);
        update_ends(track);
        on_track_added(track);
+       signal_track_added.emit(track);
 }
 
 void TrackChain::add_tracks(const TrackSet &trks)
@@ -38,10 +39,12 @@ void TrackChain::add_tracks(const TrackSet &trks)
                for(TrackSet::iterator i=pending.begin(); i!=pending.end(); ++i)
                        if((valid=check_validity(**i))==VALID)
                        {
-                               tracks.insert(*i);
-                               update_ends(**i);
-                               on_track_added(**i);
+                               Track *t = *i;
                                pending.erase(i);
+                               tracks.insert(t);
+                               update_ends(*t);
+                               on_track_added(*t);
+                               signal_track_added.emit(*t);
                                break;
                        }
 
@@ -127,9 +130,12 @@ bool TrackChain::has_track(Track &t) const
 void TrackChain::object_removed(Object &obj)
 {
        if(Track *track = dynamic_cast<Track *>(&obj))
+       {
                tracks.erase(track);
                /* TODO If the track was in the middle of the chain, keep only the
                longest fragment */
+               signal_track_removed.emit(*track);
+       }
 }
 
 } // namespace R2C2
index e73e23bd11309711b909a98803410c05d8bf399e..b4704f0bd9f145394035376b5abada7719b23789 100644 (file)
@@ -33,6 +33,10 @@ protected:
                INCOMPATIBLE
        };
 
+public:
+       sigc::signal<void, Track &> signal_track_added;
+       sigc::signal<void, Track &> signal_track_removed;
+
        Layout &layout;
        TrackSet tracks;
        TrackIter ends[2];