From 90790c9a28793d31b9ea38eea2f55652a0e9297b Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sun, 14 Mar 2010 20:16:37 +0000 Subject: [PATCH] Reimplement path display Make it possible to fill Profiles from code Initialize Track::active_path to a valid value --- source/3d/layout.h | 2 + source/3d/path.cpp | 77 +++++++++++++++++++++++++++++++++ source/3d/path.h | 41 ++++++++++++++++++ source/3d/track.cpp | 15 +++++-- source/3d/track.h | 4 ++ source/3d/tracktype.cpp | 27 +++++++++++- source/3d/tracktype.h | 3 +- source/designer/designer.cpp | 50 +++++++++++++-------- source/designer/designer.h | 1 + source/engineer/engineer.cpp | 6 ++- source/libmarklin/catalogue.cpp | 3 ++ source/libmarklin/catalogue.h | 2 + source/libmarklin/profile.cpp | 32 ++++++++------ source/libmarklin/profile.h | 2 +- source/libmarklin/track.cpp | 2 + source/libmarklin/trackpart.cpp | 3 -- 16 files changed, 228 insertions(+), 42 deletions(-) create mode 100644 source/3d/path.cpp create mode 100644 source/3d/path.h diff --git a/source/3d/layout.h b/source/3d/layout.h index ba590dd..8fcd713 100644 --- a/source/3d/layout.h +++ b/source/3d/layout.h @@ -26,6 +26,7 @@ private: std::list 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 index 0000000..1128b67 --- /dev/null +++ b/source/3d/path.cpp @@ -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 +#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<>=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 index 0000000..56e7a2f --- /dev/null +++ b/source/3d/path.h @@ -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 +#include +#include + +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 diff --git a/source/3d/track.cpp b/source/3d/track.cpp index a5c5dbf..ade3d13 100644 --- a/source/3d/track.cpp +++ b/source/3d/track.cpp @@ -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(this)); diff --git a/source/3d/track.h b/source/3d/track.h index 94865cf..93e3a0d 100644 --- a/source/3d/track.h +++ b/source/3d/track.h @@ -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 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; }; diff --git a/source/3d/tracktype.cpp b/source/3d/tracktype.cpp index 1a898d4..12a1bb9 100644 --- a/source/3d/tracktype.cpp +++ b/source/3d/tracktype.cpp @@ -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::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::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::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::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) diff --git a/source/3d/tracktype.h b/source/3d/tracktype.h index ab85d49..980e7b8 100644 --- a/source/3d/tracktype.h +++ b/source/3d/tracktype.h @@ -24,6 +24,7 @@ private: const Catalogue3D &catalogue; Msp::GL::Mesh ballast_mesh; Msp::GL::Mesh rail_mesh; + std::vector path_meshes; std::vector 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 diff --git a/source/designer/designer.cpp b/source/designer/designer.cpp index b0971c2..c9c045a 100644 --- a/source/designer/designer.cpp +++ b/source/designer/designer.cpp @@ -27,6 +27,7 @@ Distributed under the GPL #include #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 &rtracks = cur_route->get_tracks(); - const map &turnouts = cur_route->get_turnouts(); - for(set::const_iterator i=rtracks.begin(); i!=rtracks.end(); ++i) - { - unsigned path = 0; - if(unsigned tid=(*i)->get_turnout_id()) - { - map::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 <racks = layout->get_tracks(); + const set &rtracks = route.get_tracks(); + for(set::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); + } +} diff --git a/source/designer/designer.h b/source/designer/designer.h index d2cc5d2..5d22afb 100644 --- a/source/designer/designer.h +++ b/source/designer/designer.h @@ -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 diff --git a/source/engineer/engineer.cpp b/source/engineer/engineer.cpp index 7966676..2e70fb4 100644 --- a/source/engineer/engineer.cpp +++ b/source/engineer/engineer.cpp @@ -24,6 +24,7 @@ Distributed under the GPL #include #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 &tracks = block.get_tracks(); + for(set::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) diff --git a/source/libmarklin/catalogue.cpp b/source/libmarklin/catalogue.cpp index bb724bc..bdd5369 100644 --- a/source/libmarklin/catalogue.cpp +++ b/source/libmarklin/catalogue.cpp @@ -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() diff --git a/source/libmarklin/catalogue.h b/source/libmarklin/catalogue.h index 641b6f8..f1654a1 100644 --- a/source/libmarklin/catalogue.h +++ b/source/libmarklin/catalogue.h @@ -43,6 +43,7 @@ private: float gauge; Profile rail_profile; Profile ballast_profile; + Profile path_profile; std::map tracks; std::map 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; diff --git a/source/libmarklin/profile.cpp b/source/libmarklin/profile.cpp index 256854b..7b9dce5 100644 --- a/source/libmarklin/profile.cpp +++ b/source/libmarklin/profile.cpp @@ -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>=1) ; } Track::~Track() diff --git a/source/libmarklin/trackpart.cpp b/source/libmarklin/trackpart.cpp index 938ae31..37c5f97 100644 --- a/source/libmarklin/trackpart.cpp +++ b/source/libmarklin/trackpart.cpp @@ -11,8 +11,6 @@ Distributed under the GPL using namespace std; using namespace Msp; -#include - 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; -- 2.45.2