From d405b9943c888e3945c7ea4e496f9d300b114fe0 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Fri, 22 Nov 2013 21:43:36 +0200 Subject: [PATCH] Move track appearance properties into a separate class MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This will eventually enable tracks with different appearance (such as Märklin C and K track) to coexist in the same catalogue. --- source/3d/catalogue.cpp | 27 +++++++++----- source/3d/catalogue.h | 6 ++-- source/3d/endpoint.cpp | 2 +- source/3d/tracktype.cpp | 7 ++-- source/designer/svgexporter.cpp | 6 ++-- source/libr2c2/catalogue.cpp | 26 ++++---------- source/libr2c2/catalogue.h | 13 ++----- source/libr2c2/trackappearance.cpp | 32 +++++++++++++++++ source/libr2c2/trackappearance.h | 37 ++++++++++++++++++++ source/libr2c2/tracktype.cpp | 3 +- source/libr2c2/tracktype.h | 6 +++- source/libr2c2/vehicle.cpp | 3 +- tracks.dat | 56 ++++++++++++++++-------------- 13 files changed, 147 insertions(+), 77 deletions(-) create mode 100644 source/libr2c2/trackappearance.cpp create mode 100644 source/libr2c2/trackappearance.h diff --git a/source/3d/catalogue.cpp b/source/3d/catalogue.cpp index 9daa7c8..e28237f 100644 --- a/source/3d/catalogue.cpp +++ b/source/3d/catalogue.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -14,8 +15,7 @@ using namespace Msp; namespace R2C2 { Catalogue3D::Catalogue3D(Catalogue &c): - catalogue(c), - endpoint_mesh((GL::NORMAL3, GL::VERTEX3)) + catalogue(c) { add_type().creator(&Catalogue3D::create); add_type().creator(&Catalogue3D::create); @@ -28,8 +28,6 @@ Catalogue3D::Catalogue3D(Catalogue &c): const Catalogue::ObjectMap &objs = catalogue.get_all(); for(Catalogue::ObjectMap::const_iterator i=objs.begin(); i!=objs.end(); ++i) object_added(*i->second); - - build_endpoint_mesh(); } Catalogue3D::~Catalogue3D() @@ -41,7 +39,12 @@ Catalogue3D::~Catalogue3D() void Catalogue3D::object_added(const ObjectType &ot) { if(const TrackType *tt = dynamic_cast(&ot)) + { objects[&ot] = new TrackType3D(*this, *tt); + const TrackAppearance &appearance = tt->get_appearance(); + if(!endpoint_meshes.count(&appearance)) + build_endpoint_mesh(appearance); + } else if(const SignalType *st = dynamic_cast(&ot)) objects[&ot] = new SignalType3D(*this, *st); else if(const VehicleType *vt = dynamic_cast(&ot)) @@ -53,13 +56,13 @@ const ObjectType3D &Catalogue3D::get_3d(const ObjectType &ot) const return *get_item(objects, &ot); } -void Catalogue3D::build_endpoint_mesh() +void Catalogue3D::build_endpoint_mesh(const TrackAppearance &appearance) { - const Profile &ballast_profile = catalogue.get_ballast_profile(); + const Profile &ballast_profile = appearance.get_ballast_profile(); const Vector &ballast_min = ballast_profile.get_min_coords(); const Vector &ballast_max = ballast_profile.get_max_coords(); - const Profile &rail_profile = catalogue.get_rail_profile(); + const Profile &rail_profile = appearance.get_rail_profile(); const Vector &rail_min = rail_profile.get_min_coords(); const Vector &rail_max = rail_profile.get_max_coords(); @@ -68,7 +71,8 @@ void Catalogue3D::build_endpoint_mesh() float width = max(max(-ballast_min.x, ballast_max.x)*2, gauge+(rail_max.x-rail_min.x)*2)+0.004; float height = ballast_max.y-ballast_min.y+rail_max.y-rail_min.y+0.01; - GL::MeshBuilder bld(endpoint_mesh); + GL::Mesh *mesh = new GL::Mesh((GL::NORMAL3, GL::VERTEX3)); + GL::MeshBuilder bld(*mesh); bld.normal(1, 0, 0); bld.begin(GL::QUADS); bld.vertex(0, width/2, 0); @@ -76,6 +80,13 @@ void Catalogue3D::build_endpoint_mesh() bld.vertex(0, -width/2, height); bld.vertex(0, -width/2, 0); bld.end(); + + endpoint_meshes[&appearance] = mesh; +} + +const GL::Mesh &Catalogue3D::get_endpoint_mesh(const TrackAppearance &appearance) const +{ + return *get_item(endpoint_meshes, &appearance); } FS::Path Catalogue3D::locate_file(const string &name) diff --git a/source/3d/catalogue.h b/source/3d/catalogue.h index 1cc096a..ea41828 100644 --- a/source/3d/catalogue.h +++ b/source/3d/catalogue.h @@ -17,7 +17,7 @@ class Catalogue3D: public Msp::DataFile::Collection private: Catalogue &catalogue; std::map objects; - Msp::GL::Mesh endpoint_mesh; + std::map endpoint_meshes; public: Catalogue3D(Catalogue &); @@ -34,9 +34,9 @@ public: { return dynamic_cast::Type3D &>(get_3d(static_cast(ot))); } private: - void build_endpoint_mesh(); + void build_endpoint_mesh(const TrackAppearance &); public: - const Msp::GL::Mesh &get_endpoint_mesh() const { return endpoint_mesh; } + const Msp::GL::Mesh &get_endpoint_mesh(const TrackAppearance &) const; private: Msp::FS::Path locate_file(const std::string &); diff --git a/source/3d/endpoint.cpp b/source/3d/endpoint.cpp index 97e05a4..aedd689 100644 --- a/source/3d/endpoint.cpp +++ b/source/3d/endpoint.cpp @@ -13,7 +13,7 @@ namespace R2C2 { Endpoint3D::Endpoint3D(const Track3D &t, unsigned i): track(t), index(i), - mesh(track.get_layout().get_catalogue().get_endpoint_mesh()) + mesh(track.get_layout().get_catalogue().get_endpoint_mesh(track.get_track().get_type().get_appearance())) { track.get_layout().get_endpoint_scene().add(*this); } diff --git a/source/3d/tracktype.cpp b/source/3d/tracktype.cpp index d73387c..d664c39 100644 --- a/source/3d/tracktype.cpp +++ b/source/3d/tracktype.cpp @@ -15,15 +15,16 @@ TrackType3D::TrackType3D(Catalogue3D &c, const TrackType &tt): object(0), own_data(false) { + const TrackAppearance &appearance = tt.get_appearance(); const Catalogue &cat = catalogue.get_catalogue(); const vector &parts = tt.get_parts(); - const Profile &ballast_profile = cat.get_ballast_profile(); + const Profile &ballast_profile = appearance.get_ballast_profile(); const Vector &ballast_min = ballast_profile.get_min_coords(); const Vector &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 Profile &rail_profile = appearance.get_rail_profile(); const Vector &rail_min = rail_profile.get_min_coords(); const Vector &rail_max = rail_profile.get_max_coords(); float rail_h = rail_max.y-rail_min.y; @@ -53,7 +54,7 @@ TrackType3D::TrackType3D(Catalogue3D &c, const TrackType &tt): object = new GL::Object; object->set_mesh(mesh); - object->set_technique(&catalogue.get(cat.get_track_technique())); + object->set_technique(&catalogue.get(appearance.get_technique())); own_data = true; } diff --git a/source/designer/svgexporter.cpp b/source/designer/svgexporter.cpp index bb8cf4e..890112f 100644 --- a/source/designer/svgexporter.cpp +++ b/source/designer/svgexporter.cpp @@ -19,10 +19,8 @@ void SvgExporter::save(const string &fn) { gauge = layout.get_catalogue().get_gauge()*1000; - const Profile &rail_profile = layout.get_catalogue().get_rail_profile(); - const Vector &rail_min = rail_profile.get_min_coords(); - const Vector &rail_max = rail_profile.get_max_coords(); - rail_width = (rail_max.x-rail_min.x)*1000; + // XXX This should be retrieved from track appearance + rail_width = 2; xmlpp::Document *doc = new xmlpp::Document; xmlpp::Element *root = doc->create_root_node("svg", "http://www.w3.org/2000/svg"); diff --git a/source/libr2c2/catalogue.cpp b/source/libr2c2/catalogue.cpp index 779e210..2fdc21c 100644 --- a/source/libr2c2/catalogue.cpp +++ b/source/libr2c2/catalogue.cpp @@ -24,11 +24,6 @@ Catalogue::~Catalogue() delete i->second; } -float Catalogue::get_rail_elevation() const -{ - return ballast_profile.get_height()+rail_profile.get_height(); -} - void Catalogue::add(ObjectType &object) { insert_unique(objects, object.get_article_number(), &object); @@ -44,23 +39,16 @@ const ObjectType &Catalogue::get(const ArticleNumber &art_nr) const Catalogue::Loader::Loader(Catalogue &c): DataFile::ObjectLoader(c) { - add("ballast_profile", &Loader::ballast_profile); add("gauge", &Loader::gauge); add("layout", &Loader::layout); - add("rail_profile", &Loader::rail_profile); add("scale", &Loader::scale); add("signal", &Loader::signal); add("terrain", &Loader::terrain); add("track", &Loader::track); - add("track_technique", &Catalogue::track_technique); + add("track_appearance", &Loader::track_appearance); add("vehicle", &Loader::vehicle); } -void Catalogue::Loader::ballast_profile() -{ - load_sub(obj.ballast_profile); -} - void Catalogue::Loader::gauge(float g) { obj.gauge = g/1000; @@ -71,11 +59,6 @@ void Catalogue::Loader::layout() load_sub(obj.layout); } -void Catalogue::Loader::rail_profile() -{ - load_sub(obj.rail_profile); -} - void Catalogue::Loader::scale(float n, float d) { obj.scale = n/d; @@ -106,11 +89,16 @@ void Catalogue::Loader::track(ArticleNumber art_nr) if(obj.objects.count(art_nr)) throw key_error(art_nr); - RefPtr trk = new TrackType(art_nr); + RefPtr trk = new TrackType(art_nr, obj.appearance); load_sub(*trk); obj.add(*trk.release()); } +void Catalogue::Loader::track_appearance() +{ + load_sub(obj.appearance); +} + void Catalogue::Loader::vehicle(ArticleNumber art_nr) { if(obj.objects.count(art_nr)) diff --git a/source/libr2c2/catalogue.h b/source/libr2c2/catalogue.h index 5a91560..21ebd38 100644 --- a/source/libr2c2/catalogue.h +++ b/source/libr2c2/catalogue.h @@ -5,7 +5,7 @@ #include #include "articlenumber.h" #include "layout.h" -#include "profile.h" +#include "trackappearance.h" namespace R2C2 { @@ -19,14 +19,13 @@ public: public: Loader(Catalogue &); private: - void ballast_profile(); void gauge(float); void layout(); - void rail_profile(); void scale(float, float); void signal(ArticleNumber); void terrain(ArticleNumber); void track(ArticleNumber); + void track_appearance(); void vehicle(ArticleNumber); }; @@ -37,9 +36,7 @@ public: private: float scale; float gauge; - Profile rail_profile; - Profile ballast_profile; - std::string track_technique; + TrackAppearance appearance; ObjectMap objects; Layout layout; @@ -49,10 +46,6 @@ public: float get_scale() const { return scale; } float get_gauge() const { return gauge; } - float get_rail_elevation() const; - const Profile &get_rail_profile() const { return rail_profile; } - const Profile &get_ballast_profile() const { return ballast_profile; } - const std::string &get_track_technique() const { return track_technique; } void add(ObjectType &); const ObjectType &get(const ArticleNumber &) const; diff --git a/source/libr2c2/trackappearance.cpp b/source/libr2c2/trackappearance.cpp new file mode 100644 index 0000000..b97d696 --- /dev/null +++ b/source/libr2c2/trackappearance.cpp @@ -0,0 +1,32 @@ +#include "trackappearance.h" + +using namespace std; +using namespace Msp; + +namespace R2C2 { + +float TrackAppearance::get_rail_elevation() const +{ + return ballast_profile.get_height()+rail_profile.get_height(); +} + + +TrackAppearance::Loader::Loader(TrackAppearance &a): + ObjectLoader(a) +{ + add("ballast_profile", &Loader::ballast_profile); + add("rail_profile", &Loader::rail_profile); + add("technique", &TrackAppearance::technique); +} + +void TrackAppearance::Loader::ballast_profile() +{ + load_sub(obj.ballast_profile); +} + +void TrackAppearance::Loader::rail_profile() +{ + load_sub(obj.rail_profile); +} + +} // namespace R2C2 diff --git a/source/libr2c2/trackappearance.h b/source/libr2c2/trackappearance.h new file mode 100644 index 0000000..8a18cd4 --- /dev/null +++ b/source/libr2c2/trackappearance.h @@ -0,0 +1,37 @@ +#ifndef LIBR2C2_TRACKAPPEARANCE_H_ +#define LIBR2C2_TRACKAPPEARANCE_H_ + +#include +#include +#include "profile.h" + +namespace R2C2 { + +class TrackAppearance +{ +public: + class Loader: public Msp::DataFile::ObjectLoader + { + public: + Loader(TrackAppearance &); + + private: + void ballast_profile(); + void rail_profile(); + }; + +private: + Profile rail_profile; + Profile ballast_profile; + std::string technique; + +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 std::string &get_technique() const { return technique; } +}; + +} // namespace R2C2 + +#endif diff --git a/source/libr2c2/tracktype.cpp b/source/libr2c2/tracktype.cpp index e9136ac..7a1f27a 100644 --- a/source/libr2c2/tracktype.cpp +++ b/source/libr2c2/tracktype.cpp @@ -7,8 +7,9 @@ using namespace Msp; namespace R2C2 { -TrackType::TrackType(const ArticleNumber &an): +TrackType::TrackType(const ArticleNumber &an, const TrackAppearance &ta): ObjectType(an), + appearance(ta), state_bits(0), autofit_preference(1) { } diff --git a/source/libr2c2/tracktype.h b/source/libr2c2/tracktype.h index 181cb21..64efe8c 100644 --- a/source/libr2c2/tracktype.h +++ b/source/libr2c2/tracktype.h @@ -9,6 +9,8 @@ namespace R2C2 { +class TrackAppearance; + class TrackType: public ObjectType { public: @@ -39,6 +41,7 @@ public: }; private: + const TrackAppearance &appearance; std::vector parts; std::vector endpoints; unsigned state_bits; @@ -46,8 +49,9 @@ private: std::string object; public: - TrackType(const ArticleNumber &); + TrackType(const ArticleNumber &, const TrackAppearance &); + const TrackAppearance &get_appearance() const { return appearance; } float get_total_length() const; float get_path_length(int) const; unsigned get_paths() const; diff --git a/source/libr2c2/vehicle.cpp b/source/libr2c2/vehicle.cpp index 099644a..dee1e76 100644 --- a/source/libr2c2/vehicle.cpp +++ b/source/libr2c2/vehicle.cpp @@ -175,7 +175,8 @@ void Vehicle::update_position(int sign) { OrientedPoint p = placement.get_point(); position = p.position; - position.z += layout.get_catalogue().get_rail_elevation(); + // TODO Move the z adjustment to VehiclePlacement + position.z += placement.get_position(VehiclePlacement::FRONT_AXLE)->get_type().get_appearance().get_rail_elevation(); rotation = p.rotation; tilt = p.tilt; diff --git a/tracks.dat b/tracks.dat index 9c6bda8..40cf1ca 100644 --- a/tracks.dat +++ b/tracks.dat @@ -1,31 +1,35 @@ scale 1 87; gauge 16.5; -rail_profile -{ - point 1.5 0.0; - smooth_point 1.5 0.3; - smooth_point 0.8 0.4; - smooth_point 0.8 1.4; - smooth_point 1.0 1.6; - smooth_point 1.0 2.1; - smooth_point 0.8 2.3; - smooth_point 0.2 2.3; - smooth_point 0.0 2.1; - smooth_point 0.0 1.6; - smooth_point 0.2 1.4; - smooth_point 0.2 0.4; - smooth_point -0.5 0.3; - point -0.5 0.0; -}; -ballast_profile -{ - point 20.0 0.0; - point 14.0 8.0; - point -14.0 8.0; - point -20.0 0.0; -}; - -track_technique "track.technique"; + +track_appearance +{ + rail_profile + { + point 1.5 0.0; + smooth_point 1.5 0.3; + smooth_point 0.8 0.4; + smooth_point 0.8 1.4; + smooth_point 1.0 1.6; + smooth_point 1.0 2.1; + smooth_point 0.8 2.3; + smooth_point 0.2 2.3; + smooth_point 0.0 2.1; + smooth_point 0.0 1.6; + smooth_point 0.2 1.4; + smooth_point 0.2 0.4; + smooth_point -0.5 0.3; + point -0.5 0.0; + }; + ballast_profile + { + point 20.0 0.0; + point 14.0 8.0; + point -14.0 8.0; + point -20.0 0.0; + }; + + technique "track.technique"; +}; // Straight -- 2.45.2