]> git.tdb.fi Git - r2c2.git/commitdiff
Reimplement path display
authorMikko Rasa <tdb@tdb.fi>
Sun, 14 Mar 2010 20:16:37 +0000 (20:16 +0000)
committerMikko Rasa <tdb@tdb.fi>
Sun, 14 Mar 2010 20:16:37 +0000 (20:16 +0000)
Make it possible to fill Profiles from code
Initialize Track::active_path to a valid value

16 files changed:
source/3d/layout.h
source/3d/path.cpp [new file with mode: 0644]
source/3d/path.h [new file with mode: 0644]
source/3d/track.cpp
source/3d/track.h
source/3d/tracktype.cpp
source/3d/tracktype.h
source/designer/designer.cpp
source/designer/designer.h
source/engineer/engineer.cpp
source/libmarklin/catalogue.cpp
source/libmarklin/catalogue.h
source/libmarklin/profile.cpp
source/libmarklin/profile.h
source/libmarklin/track.cpp
source/libmarklin/trackpart.cpp

index ba590dd37e2d8482d5180138f2ab6f663a7a6554..8fcd713a2c7be76c3b7a9ef247075f7d2f08feae 100644 (file)
@@ -26,6 +26,7 @@ private:
        std::list<Train3D *> trains;
        Msp::GL::Scene scene;
        Msp::GL::Scene ep_scene;
+       Msp::GL::Scene path_scene;
 
 public:
        Layout3D(Layout &);
@@ -45,6 +46,7 @@ public:
 
        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; }
 
 private:
        void track_added(Track &);
diff --git a/source/3d/path.cpp b/source/3d/path.cpp
new file mode 100644 (file)
index 0000000..1128b67
--- /dev/null
@@ -0,0 +1,77 @@
+/* $Id$
+
+This file is part of the MSP Märklin suite
+Copyright © 2010 Mikkosoft Productions, Mikko Rasa
+Distributed under the GPL
+*/
+
+#include <msp/gl/matrix.h>
+#include "libmarklin/tracktype.h"
+#include "layout.h"
+#include "path.h"
+#include "track.h"
+#include "tracktype.h"
+
+using namespace Msp;
+
+namespace Marklin {
+
+Path3D::Path3D(const Track3D &t):
+       track(t),
+       paths(0),
+       automatic(true)
+{
+       track.get_layout().get_path_scene().add(*this);
+}
+
+Path3D::~Path3D()
+{
+       track.get_layout().get_path_scene().remove(*this);
+}
+
+void Path3D::set_automatic()
+{
+       automatic = true;
+}
+
+void Path3D::set_path(unsigned p)
+{
+       if(!(track.get_track().get_type().get_paths()&(1<<p)))
+               throw InvalidParameterValue("Invalid path");
+       automatic = false;
+       paths = 1<<p;
+}
+
+void Path3D::set_mask(unsigned p)
+{
+       if(p&~track.get_track().get_type().get_paths())
+               throw InvalidParameterValue("Invalid path mask");
+       automatic = false;
+       paths = p;
+}
+
+void Path3D::set_color(const GL::Color &c)
+{
+       color = c;
+}
+
+void Path3D::render(const GL::Tag &tag) const
+{
+       if(tag==0)
+       {
+               unsigned mask = (automatic ? 1<<track.get_track().get_active_path() : paths);
+               mask &= track.get_track().get_type().get_paths();
+               if(!mask)
+                       return;
+
+               GL::PushMatrix push_mat;
+               track.apply_matrix();
+
+               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();
+       }
+}
+
+} // namespace Marklin
diff --git a/source/3d/path.h b/source/3d/path.h
new file mode 100644 (file)
index 0000000..56e7a2f
--- /dev/null
@@ -0,0 +1,41 @@
+/* $Id$
+
+This file is part of the MSP Märklin suite
+Copyright © 2010 Mikkosoft Productions, Mikko Rasa
+Distributed under the GPL
+*/
+
+#ifndef MARKLIN3D_PATH_H_
+#define MARKLIN3D_PATH_H_
+
+#include <msp/gl/color.h>
+#include <msp/gl/mesh.h>
+#include <msp/gl/renderable.h>
+
+namespace Marklin {
+
+class Track3D;
+
+class Path3D: public Msp::GL::Renderable
+{
+private:
+       const Track3D &track;
+       unsigned paths;
+       bool automatic;
+       Msp::GL::Color color;
+
+public:
+       Path3D(const Track3D &);
+       ~Path3D();
+
+       void set_automatic();
+       void set_path(unsigned);
+       void set_mask(unsigned);
+       void set_color(const Msp::GL::Color &);
+
+       virtual void render(const Msp::GL::Tag &) const;
+};
+
+} // namespace Marklin
+
+#endif
index a5c5dbf62a166904a5e3203d28b53af8a637284c..ade3d132bcef669759bff1c6796e14699a9ce177 100644 (file)
@@ -11,6 +11,7 @@ Distributed under the GPL
 #include "libmarklin/tracktype.h"
 #include "endpoint.h"
 #include "layout.h"
+#include "path.h"
 #include "track.h"
 #include "tracktype.h"
 
@@ -22,7 +23,8 @@ namespace Marklin {
 Track3D::Track3D(Layout3D &l, Track &t):
        layout(l),
        track(t),
-       type(layout.get_catalogue().get_track(track.get_type()))
+       type(layout.get_catalogue().get_track(track.get_type())),
+       path(new Path3D(*this))
 {
        layout.add_track(*this);
        layout.get_scene().add(*this);
@@ -77,16 +79,21 @@ Point Track3D::get_node() const
        return Point(pos.x+c*center.x-s*center.y, pos.y+s*center.x+c*center.y, pos.z+0.02);
 }
 
-void Track3D::render(const GL::Tag &tag) const
+void Track3D::apply_matrix() const
 {
-       GL::PushMatrix push_mat;
-
        const Point &pos = track.get_position();
        float rot = track.get_rotation();
 
        glTranslatef(pos.x, pos.y, pos.z);
        glRotatef(rot*180/M_PI, 0, 0, 1);
        glRotatef(track.get_slope()/track.get_type().get_total_length()*180/M_PI, 0, -1, 0);
+}
+
+void Track3D::render(const GL::Tag &tag) const
+{
+       GL::PushMatrix push_mat;
+
+       apply_matrix();
 
        glPushName(reinterpret_cast<unsigned>(this));
 
index 94865cfdf4afcf96837d84a552cebd2471cf26af..93e3a0d37ab440d514d93a990fb465ac153fcc40 100644 (file)
@@ -20,6 +20,7 @@ namespace Marklin {
 
 class Endpoint3D;
 class Layout3D;
+class Path3D;
 class TrackType3D;
 
 class Track3D: public Object3D, public Msp::GL::Renderable
@@ -29,6 +30,7 @@ private:
        Track &track;
        const TrackType3D &type;
        std::vector<Endpoint3D *> endpoints;
+       Path3D *path;
 
 public:
        Track3D(Layout3D &, Track &);
@@ -38,9 +40,11 @@ public:
        Track &get_track() const { return track; }
        const TrackType3D &get_type() const { return type; }
        void get_bounds(float, Point &, Point &) const;
+       Path3D &get_path() { return *path; }
 
        virtual Point get_node() const;
 
+       void apply_matrix() const;
        virtual void render(const Msp::GL::Tag &) const;
 };
 
index 1a898d4cd5383c21e0104fe8a5bfef7758c45188..12a1bb92a15df585e426e381cc30ab5331877b3f 100644 (file)
@@ -82,10 +82,12 @@ TrackType3D::TrackType3D(const Catalogue3D &cat3d, const TrackType &tt):
        const Profile &ballast_profile = cat.get_ballast_profile();
        const Point &ballast_min = ballast_profile.get_min_coords();
        const Point &ballast_max = ballast_profile.get_max_coords();
+       float ballast_h = ballast_max.y-ballast_min.y;
 
        const Profile &rail_profile = cat.get_rail_profile();
        const Point &rail_min = rail_profile.get_min_coords();
        const Point &rail_max = rail_profile.get_max_coords();
+       float rail_h = rail_max.y-rail_min.y;
 
        float gauge = cat.get_gauge();
 
@@ -101,12 +103,28 @@ TrackType3D::TrackType3D(const Catalogue3D &cat3d, const TrackType &tt):
                unsigned index = 0;
                GL::MeshBuilder bld(rail_mesh);
                bld.color(0.85f, 0.85f, 0.85f);
-               float y = ballast_max.y-ballast_min.y-rail_min.y;
+               float y = ballast_h-rail_min.y;
                for(vector<TrackPart>::const_iterator i=parts.begin(); i!=parts.end(); ++i)
                        build_part(*i, rail_profile, Point(-gauge/2-rail_max.x, y), bld, index);
                for(vector<TrackPart>::const_iterator i=parts.begin(); i!=parts.end(); ++i)
                        build_part(*i, rail_profile, Point(gauge/2-rail_min.x, y), bld, index);
        }
+       unsigned paths = tt.get_paths();
+       for(unsigned i=0; paths; ++i, paths>>=1)
+       {
+               GL::Mesh *mesh = 0;
+               if(paths&1)
+               {
+                       mesh = new GL::Mesh(GL::VERTEX3);
+                       GL::MeshBuilder bld(*mesh);
+                       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(), Point(0, ballast_h+1.5*rail_h), bld, index);
+               }
+               path_meshes.push_back(mesh);
+       }
 
        min_z = max_z = border.front().z;
        for(vector<Point>::iterator i=border.begin(); i!=border.end(); ++i)
@@ -138,6 +156,13 @@ void TrackType3D::get_bounds(float angle, Point &minp, Point &maxp) const
        }
 }
 
+const GL::Mesh &TrackType3D::get_path_mesh(unsigned p) const
+{
+       if(p>=path_meshes.size() || !path_meshes[p])
+               throw InvalidParameterValue("Invalid path");
+       return *path_meshes[p];
+}
+
 void TrackType3D::render(const GL::Tag &tag) const
 {
        if(tag==0)
index ab85d49ce88f1ba30bfe02d2975c917de65ad37d..980e7b82c843a483ffcf34083117119a0ab57f0b 100644 (file)
@@ -24,6 +24,7 @@ private:
        const Catalogue3D &catalogue;
        Msp::GL::Mesh ballast_mesh;
        Msp::GL::Mesh rail_mesh;
+       std::vector<Msp::GL::Mesh *> path_meshes;
        std::vector<Point> border;
        float min_z;
        float max_z;
@@ -32,12 +33,12 @@ public:
        TrackType3D(const Catalogue3D &, const TrackType &);
 
        void get_bounds(float, Point &, Point &) const;
+       const Msp::GL::Mesh &get_path_mesh(unsigned) const;
 
        virtual void render(const Msp::GL::Tag &) const;
 
 private:
        void build_part(const TrackPart &, const Profile &, const Point &, Msp::GL::MeshBuilder &, unsigned &);
-       //void optimize_border();
 };
 
 } // namespace Marklin
index b0971c25271be9d65390ff08ca5841614e7c84b6..c9c045af2e253d9091d89cefa964b17618b12a58 100644 (file)
@@ -27,6 +27,7 @@ Distributed under the GPL
 #include <msp/time/utils.h>
 #include "libmarklin/route.h"
 #include "libmarklin/tracktype.h"
+#include "3d/path.h"
 #include "designer.h"
 #include "input.h"
 #include "manipulator.h"
@@ -201,6 +202,7 @@ void Designer::set_sensor_id()
 void Designer::edit_route(Route &r)
 {
        cur_route = &r;
+       show_route(r);
 }
 
 void Designer::add_selection_to_route()
@@ -218,6 +220,8 @@ void Designer::add_selection_to_route()
        {
                IO::print("%s\n", e.what());
        }
+
+       show_route(*cur_route);
 }
 
 Point Designer::map_pointer_coords(int x, int y)
@@ -428,27 +432,12 @@ void Designer::render()
        {
                pipeline->render_all();
                layout_3d->get_endpoint_scene().render();
+               if(cur_route)
+                       layout_3d->get_path_scene().render();
                GL::enable(GL_CULL_FACE);
                GL::disable(GL::DEPTH_TEST);
                overlay->render(0);
                GL::enable(GL::DEPTH_TEST);
-               /*if(cur_route)
-               {
-                       glColor4f(0.5, 0.8, 1.0, 1.0);
-                       const set<const Track *> &rtracks = cur_route->get_tracks();
-                       const map<unsigned, int> &turnouts = cur_route->get_turnouts();
-                       for(set<const Track *>::const_iterator i=rtracks.begin(); i!=rtracks.end(); ++i)
-                       {
-                               unsigned path = 0;
-                               if(unsigned tid=(*i)->get_turnout_id())
-                               {
-                                       map<unsigned, int>::const_iterator j = turnouts.find(tid);
-                                       if(j!=turnouts.end())
-                                               path = j->second;
-                               }
-                               layout_3d->get_track(**i).render_path(path);
-                       }
-               }*/
 
                manipulator.render();
                if(mode==MEASURE)
@@ -592,3 +581,30 @@ string Designer::tooltip(int x, int y)
 
        return string();
 }
+
+void Designer::show_route(const Route &route)
+{
+       const set<Track *> &ltracks = layout->get_tracks();
+       const set<const Track *> &rtracks = route.get_tracks();
+       for(set<Track *>::iterator i=ltracks.begin(); i!=ltracks.end(); ++i)
+       {
+               Track3D &t3d = layout_3d->get_track(**i);
+               if(rtracks.count(*i))
+               {
+                       t3d.get_path().set_color(GL::Color(0.5, 0.8, 1.0));
+                       if((*i)->get_type().is_turnout())
+                       {
+                               unsigned tid = (*i)->get_turnout_id();
+                               int path = (tid ? route.get_turnout(tid) : -1);
+                               if(path>=0)
+                                       t3d.get_path().set_path(path);
+                               else
+                                       t3d.get_path().set_mask((*i)->get_type().get_paths());
+                       }
+                       else
+                               t3d.get_path().set_path(0);
+               }
+               else
+                       t3d.get_path().set_mask(0);
+       }
+}
index d2cc5d212def4b2c520969b0e32ae0d0aef4c8ed..5d22afb1c924c8b0a872d763820dc8567b8bff1f 100644 (file)
@@ -114,6 +114,7 @@ private:
        void sensor_id_accept(const std::string &);
        void view_all();
        std::string tooltip(int, int);
+       void show_route(const Marklin::Route &);
 };
 
 #endif
index 7966676769953b653848671df5957896609324f0..2e70fb4eddef55477f1ef1b8ad2b863391fc0584 100644 (file)
@@ -24,6 +24,7 @@ Distributed under the GPL
 #include <msp/time/units.h>
 #include "libmarklin/driver.h"
 #include "libmarklin/tracktype.h"
+#include "3d/path.h"
 #include "engineer.h"
 #include "mainpanel.h"
 #include "trainpanel.h"
@@ -147,6 +148,7 @@ void Engineer::tick()
        GL::clear(GL::COLOR_BUFFER_BIT|GL::DEPTH_BUFFER_BIT);
 
        pipeline.render_all();
+       layout_3d.get_path_scene().render();
        {
                GL::Bind blend(GL::Blend::alpha());
                overlay->render(0);
@@ -310,7 +312,9 @@ void Engineer::view_all()
 
 void Engineer::set_block_color(const Block &block, const GL::Color &color)
 {
-       (void)block; (void)color;
+       const set<Track *> &tracks = block.get_tracks();
+       for(set<Track *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
+               layout_3d.get_track(**i).get_path().set_color(color);
 }
 
 void Engineer::reset_block_color(const Block &block)
index bb724bc823868bc8beb12b8ec968258ae80ad324..bdd5369f9130d504d2a22182a6c1b920f111c892 100644 (file)
@@ -87,6 +87,9 @@ void Catalogue::Loader::ballast_profile()
 void Catalogue::Loader::gauge(float g)
 {
        obj.gauge = g/1000;
+       obj.path_profile = Profile();
+       obj.path_profile.append_point(Point(0.1*obj.gauge, 0));
+       obj.path_profile.append_point(Point(-0.1*obj.gauge, 0));
 }
 
 void Catalogue::Loader::layout()
index 641b6f8b13c3ea15275a987cdd76a8eff71035f5..f1654a19d62add8b8f5c31fdd95295acb837e10b 100644 (file)
@@ -43,6 +43,7 @@ private:
        float gauge;
        Profile rail_profile;
        Profile ballast_profile;
+       Profile path_profile;
        std::map<unsigned, TrackType *> tracks;
        std::map<unsigned, LocoType *> locos;
        Layout layout;
@@ -55,6 +56,7 @@ public:
        float get_gauge() const { return gauge; }
        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; }
 
        void add_track(TrackType &);
        const TrackType &get_track(unsigned) const;
index 256854b0fca9b4343c81f6f4be4cfe108eaef7f7..7b9dce52073075de8cb9473ae1fa3dda35ceedde 100644 (file)
@@ -13,6 +13,23 @@ using namespace Msp;
 
 namespace Marklin {
 
+void Profile::append_point(const Point &p)
+{
+       points.push_back(p);
+       if(points.size()==1)
+       {
+               min_coords = p;
+               max_coords = p;
+       }
+       else
+       {
+               min_coords.x = min(min_coords.x, p.x);
+               min_coords.y = min(min_coords.y, p.y);
+               max_coords.x = max(max_coords.x, p.x);
+               max_coords.y = max(max_coords.y, p.y);
+       }
+}
+
 const Point &Profile::get_point(unsigned i) const
 {
        if(i>=points.size())
@@ -37,22 +54,9 @@ Profile::Loader::Loader(Profile &p):
        add("point", &Loader::point);
 }
 
-void Profile::Loader::finish()
-{
-       obj.min_coords = obj.points[0];
-       obj.max_coords = obj.points[0];
-       for(unsigned i=1; i<obj.points.size(); ++i)
-       {
-               obj.min_coords.x = min(obj.min_coords.x, obj.points[i].x);
-               obj.min_coords.y = min(obj.min_coords.y, obj.points[i].y);
-               obj.max_coords.x = max(obj.max_coords.x, obj.points[i].x);
-               obj.max_coords.y = max(obj.max_coords.y, obj.points[i].y);
-       }
-}
-
 void Profile::Loader::point(float x, float y)
 {
-       obj.points.push_back(Point(x/1000, y/1000));
+       obj.append_point(Point(x/1000, y/1000));
 }
 
 } // namespace Marklin
index 3b194c8d39870650529d210b75ff05c31aa7c5b7..92b2dfc20918b6e2d8b24dd2c64f341225bb5136 100644 (file)
@@ -22,7 +22,6 @@ public:
        public:
                Loader(Profile &);
        private:
-               virtual void finish();
                void point(float, float);
        };
 
@@ -32,6 +31,7 @@ private:
        Point max_coords;
 
 public:
+       void append_point(const Point &);
        unsigned get_n_points() const { return points.size(); }
        const Point &get_point(unsigned) const;
        const Point &get_min_coords() const { return min_coords; }
index 250888dd6a8f5aa23f331a1bcf39830c789d3af7..7c08b6c46766c0d3e116c775d2f9f802e5c81653 100644 (file)
@@ -31,6 +31,8 @@ Track::Track(Layout &l, const TrackType &t):
 
        if(layout.has_driver())
                layout.get_driver().signal_turnout.connect(sigc::mem_fun(this, &Track::turnout_event));
+
+       for(unsigned paths = type.get_paths(); !(paths&1); ++active_path, paths>>=1) ;
 }
 
 Track::~Track()
index 938ae31ff6fdd63a2b3631bc4f0d2b654c0e0c9c..37c5f97a90b0fc81cae5eb150bb2cbd8a654e8d5 100644 (file)
@@ -11,8 +11,6 @@ Distributed under the GPL
 using namespace std;
 using namespace Msp;
 
-#include <msp/io/print.h>
-
 namespace Marklin {
 
 TrackPart::TrackPart():
@@ -79,7 +77,6 @@ void TrackPart::check_link(TrackPart &other)
 
                        if(dx*dx+dy*dy<1e-6 && da>=-0.01 && da<=0.01)
                        {
-                               IO::print("TrackParts linked!\n");
                                links[i] = &other;
                                other.links[j] = this;
                                return;