From e5cd9e4fbc577036a0385c985b6b65df8218d0a2 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Tue, 6 Apr 2010 08:08:54 +0000 Subject: [PATCH] Add vehicles Fix direction in Track::get_point Add overload of Track::get_point that uses the current path --- locos.dat | 71 +++++++++++ source/3d/catalogue.cpp | 17 +++ source/3d/catalogue.h | 4 + source/3d/layout.cpp | 34 +++--- source/3d/layout.h | 15 +-- source/3d/train.cpp | 31 ----- source/3d/train.h | 35 ------ source/3d/vehicle.cpp | 53 +++++++++ source/3d/vehicle.h | 40 +++++++ source/3d/vehicletype.cpp | 51 ++++++++ source/3d/vehicletype.h | 31 +++++ source/engineer/engineer.cpp | 8 +- source/engineer/engineer.h | 1 + source/libmarklin/catalogue.h | 1 + source/libmarklin/layout.cpp | 12 ++ source/libmarklin/layout.h | 7 ++ source/libmarklin/locotype.cpp | 7 +- source/libmarklin/locotype.h | 8 +- source/libmarklin/track.cpp | 6 + source/libmarklin/track.h | 1 + source/libmarklin/train.cpp | 66 +++++------ source/libmarklin/train.h | 11 +- source/libmarklin/vehicle.cpp | 189 ++++++++++++++++++++++++++++++ source/libmarklin/vehicle.h | 67 +++++++++++ source/libmarklin/vehicletype.cpp | 101 ++++++++++++++++ source/libmarklin/vehicletype.h | 84 +++++++++++++ 26 files changed, 807 insertions(+), 144 deletions(-) delete mode 100644 source/3d/train.cpp delete mode 100644 source/3d/train.h create mode 100644 source/3d/vehicle.cpp create mode 100644 source/3d/vehicle.h create mode 100644 source/3d/vehicletype.cpp create mode 100644 source/3d/vehicletype.h create mode 100644 source/libmarklin/vehicle.cpp create mode 100644 source/libmarklin/vehicle.h create mode 100644 source/libmarklin/vehicletype.cpp create mode 100644 source/libmarklin/vehicletype.h diff --git a/locos.dat b/locos.dat index f44c9be..e2f5756 100644 --- a/locos.dat +++ b/locos.dat @@ -8,6 +8,21 @@ locomotive 37844 function 2 "telex"; function 3 "sfx"; function 5 "whst"; + + length 150; + width 33; + height 33; + + bogie + { + position 39; + axle { position 23; wheel_diameter 9; }; + }; + axle { position 31; wheel_diameter 16; powered true; }; + axle { position 11; wheel_diameter 16; powered true; }; + axle { position -9; wheel_diameter 16; powered true; }; + axle { position -29; wheel_diameter 16; powered true; }; + axle { position -49; wheel_diameter 16; powered true; }; }; locomotive 33961 @@ -15,16 +30,72 @@ locomotive 33961 name "BR 86"; function 0 "light"; function 2 "telex"; + + length 144; + width 33; + height 33; + + bogie + { + position 36; + axle { position 23; wheel_diameter 9; }; + }; + axle { position 29; wheel_diameter 16; powered true; }; + axle { position 9.67; wheel_diameter 16; powered true; }; + axle { position -9.67; wheel_diameter 16; powered true; }; + axle { position -29; wheel_diameter 16; powered true; }; + bogie + { + position -36; + axle { position -23; wheel_diameter 9; }; + }; }; locomotive 36850 { name "BR 185"; function 0 "light"; + + length 205; + width 33; + height 33; + + bogie + { + position 60; + axle { position 15; wheel_diameter 14; powered true; }; + axle { position -15; wheel_diameter 14; powered true; }; + }; + bogie + { + position -60; + axle { position 15; wheel_diameter 14; powered true; }; + axle { position -15; wheel_diameter 14; powered true; }; + }; }; locomotive 37225 { name "BR 194"; function 0 "light"; + + length 200; + width 33; + height 33; + + bogie + { + position 45; + // Note: front bogie not powered in model + axle { position 34; wheel_diameter 14; powered true; }; + axle { position 6; wheel_diameter 14; powered true; }; + axle { position -19; wheel_diameter 14; powered true; }; + }; + bogie + { + position -45; + axle { position 19; wheel_diameter 14; powered true; }; + axle { position -6; wheel_diameter 14; powered true; }; + axle { position -34; wheel_diameter 14; powered true; }; + }; }; diff --git a/source/3d/catalogue.cpp b/source/3d/catalogue.cpp index 54341c1..1068fea 100644 --- a/source/3d/catalogue.cpp +++ b/source/3d/catalogue.cpp @@ -6,8 +6,10 @@ Distributed under the GPL */ #include +#include "libmarklin/locotype.h" #include "catalogue.h" #include "tracktype.h" +#include "vehicletype.h" using namespace std; using namespace Msp; @@ -19,6 +21,7 @@ Catalogue3D::Catalogue3D(Catalogue &c): endpoint_mesh((GL::NORMAL3, GL::VERTEX3)) { catalogue.signal_track_added.connect(sigc::mem_fun(this, &Catalogue3D::track_added)); + catalogue.signal_loco_added.connect(sigc::mem_fun(this, &Catalogue3D::loco_added)); const map &trks = catalogue.get_tracks(); for(map::const_iterator i=trks.begin(); i!=trks.end(); ++i) @@ -45,11 +48,25 @@ const TrackType3D &Catalogue3D::get_track(const TrackType &tt) const return *i->second; } +const VehicleType3D &Catalogue3D::get_vehicle(const VehicleType &vt) const +{ + map::const_iterator i = vehicles.find(&vt); + if(i==vehicles.end()) + throw KeyError("Unknown vehicle type"); + + return *i->second; +} + void Catalogue3D::track_added(const TrackType &track) { tracks[&track] = new TrackType3D(*this, track); } +void Catalogue3D::loco_added(const LocoType &loco) +{ + vehicles[&loco] = new VehicleType3D(*this, loco); +} + void Catalogue3D::build_endpoint_mesh() { const Profile &ballast_profile = catalogue.get_ballast_profile(); diff --git a/source/3d/catalogue.h b/source/3d/catalogue.h index 6cc5bed..d826a78 100644 --- a/source/3d/catalogue.h +++ b/source/3d/catalogue.h @@ -15,12 +15,14 @@ Distributed under the GPL namespace Marklin { class TrackType3D; +class VehicleType3D; class Catalogue3D { private: Catalogue &catalogue; std::map tracks; + std::map vehicles; Msp::GL::Material ballast_material; Msp::GL::Material rail_material; Msp::GL::Mesh endpoint_mesh; @@ -31,11 +33,13 @@ public: const Catalogue &get_catalogue() const { return catalogue; } const TrackType3D &get_track(const TrackType &) const; + const VehicleType3D &get_vehicle(const VehicleType &) const; const Msp::GL::Material &get_ballast_material() const { return ballast_material; } const Msp::GL::Material &get_rail_material() const { return rail_material; } const Msp::GL::Mesh &get_endpoint_mesh() const { return endpoint_mesh; } private: void track_added(const TrackType &); + void loco_added(const LocoType &); void build_endpoint_mesh(); }; diff --git a/source/3d/layout.cpp b/source/3d/layout.cpp index 1a55715..70c5509 100644 --- a/source/3d/layout.cpp +++ b/source/3d/layout.cpp @@ -14,6 +14,8 @@ Distributed under the GPL #include #include #include "layout.h" +#include "track.h" +#include "vehicle.h" using namespace std; using namespace Msp; @@ -26,7 +28,7 @@ Layout3D::Layout3D(Layout &l): { layout.signal_track_added.connect(sigc::mem_fun(this, &Layout3D::track_added)); layout.signal_track_removed.connect(sigc::mem_fun(this, &Layout3D::track_removed)); - layout.signal_train_added.connect(sigc::mem_fun(this, &Layout3D::train_added)); + layout.signal_vehicle_added.connect(sigc::mem_fun(this, &Layout3D::vehicle_added)); const set <racks = layout.get_tracks(); for(set::iterator i=ltracks.begin(); i!=ltracks.end(); ++i) @@ -37,8 +39,8 @@ Layout3D::~Layout3D() { while(!tracks.empty()) delete tracks.front(); - while(!trains.empty()) - delete trains.front(); + while(!vehicles.empty()) + delete vehicles.front(); } void Layout3D::add_track(Track3D &t) @@ -89,7 +91,7 @@ Track3D *Layout3D::pick_track(float x, float y, float size) const Track3D *track = 0; unsigned track_depth = numeric_limits::max(); for(vector::iterator i=select_buf.begin(); i!=select_buf.end(); ++i) - if(i->min_depthmin_depthnames.empty()) { track = reinterpret_cast(i->names.back()); track_depth = i->min_depth; @@ -98,25 +100,25 @@ Track3D *Layout3D::pick_track(float x, float y, float size) const return track; } -void Layout3D::add_train(Train3D &t) +void Layout3D::add_vehicle(Vehicle3D &v) { - trains.push_back(&t); + vehicles.push_back(&v); } -void Layout3D::remove_train(Train3D &t) +void Layout3D::remove_vehicle(Vehicle3D &v) { - list::iterator i = find(trains.begin(), trains.end(), &t); - if(i!=trains.end()) - trains.erase(i); + list::iterator i = find(vehicles.begin(), vehicles.end(), &v); + if(i!=vehicles.end()) + vehicles.erase(i); } -Train3D &Layout3D::get_train(const Train &t) const +Vehicle3D &Layout3D::get_vehicle(const Vehicle &v) const { - for(list::const_iterator i=trains.begin(); i!=trains.end(); ++i) - if(&(*i)->get_train()==&t) + for(list::const_iterator i=vehicles.begin(); i!=vehicles.end(); ++i) + if(&(*i)->get_vehicle()==&v) return **i; - throw KeyError("Unknown train"); + throw KeyError("Unknown vehicle"); } void Layout3D::track_added(Track &t) @@ -134,9 +136,9 @@ void Layout3D::track_removed(Track &t) } } -void Layout3D::train_added(Train &t) +void Layout3D::vehicle_added(Vehicle &v) { - new Train3D(*this, t); + new Vehicle3D(*this, v); } } // namespace Marklin diff --git a/source/3d/layout.h b/source/3d/layout.h index 8fcd713..a0c7786 100644 --- a/source/3d/layout.h +++ b/source/3d/layout.h @@ -12,18 +12,19 @@ Distributed under the GPL #include #include "libmarklin/layout.h" #include "catalogue.h" -#include "track.h" -#include "train.h" namespace Marklin { +class Track3D; +class Vehicle3D; + class Layout3D: public sigc::trackable { private: Layout &layout; Catalogue3D catalogue; std::list tracks; - std::list trains; + std::list vehicles; Msp::GL::Scene scene; Msp::GL::Scene ep_scene; Msp::GL::Scene path_scene; @@ -40,9 +41,9 @@ public: Track3D &get_track(const Track &) const; Track3D *pick_track(float, float, float) const; - void add_train(Train3D &); - void remove_train(Train3D &); - Train3D &get_train(const Train &) const; + void add_vehicle(Vehicle3D &); + void remove_vehicle(Vehicle3D &); + Vehicle3D &get_vehicle(const Vehicle &) const; Msp::GL::Scene &get_scene() { return scene; } Msp::GL::Scene &get_endpoint_scene() { return ep_scene; } @@ -51,7 +52,7 @@ public: private: void track_added(Track &); void track_removed(Track &); - void train_added(Train &); + void vehicle_added(Vehicle &); }; } // namespace Marklin diff --git a/source/3d/train.cpp b/source/3d/train.cpp deleted file mode 100644 index d14225e..0000000 --- a/source/3d/train.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* $Id$ - -This file is part of the MSP Märklin suite -Copyright © 2010 Mikkosoft Productions, Mikko Rasa -Distributed under the GPL -*/ - -#include "layout.h" -#include "train.h" - -namespace Marklin { - -Train3D::Train3D(Layout3D &l, const Train &t): - layout(l), - train(t) -{ - layout.add_train(*this); -} - -Train3D::~Train3D() -{ - layout.remove_train(*this); -} - -Point Train3D::get_node() const -{ - const Point &pos = train.get_position(); - return Point(pos.x, pos.y, pos.z+0.02); -} - -} // namespace Marklin diff --git a/source/3d/train.h b/source/3d/train.h deleted file mode 100644 index 098d344..0000000 --- a/source/3d/train.h +++ /dev/null @@ -1,35 +0,0 @@ -/* $Id$ - -This file is part of the MSP Märklin suite -Copyright © 2010 Mikkosoft Productions, Mikko Rasa -Distributed under the GPL -*/ - -#ifndef MARKLIN3D_TRAIN_H_ -#define MARKLIN3D_TRAIN_H_ - -#include "libmarklin/train.h" -#include "object.h" - -namespace Marklin { - -class Layout3D; - -class Train3D: public Object3D -{ -private: - Layout3D &layout; - const Train &train; - -public: - Train3D(Layout3D &, const Train &); - ~Train3D(); - - const Train &get_train() const { return train; } - - virtual Point get_node() const; -}; - -} // namespace Marklin - -#endif diff --git a/source/3d/vehicle.cpp b/source/3d/vehicle.cpp new file mode 100644 index 0000000..4fbac68 --- /dev/null +++ b/source/3d/vehicle.cpp @@ -0,0 +1,53 @@ +/* $Id$ + +This file is part of the MSP Märklin suite +Copyright © 2010 Mikkosoft Productions, Mikko Rasa +Distributed under the GPL +*/ + +#include +#include +#include "layout.h" +#include "vehicle.h" +#include "vehicletype.h" + +using namespace Msp; + +namespace Marklin { + +Vehicle3D::Vehicle3D(Layout3D &l, Vehicle &v): + layout(l), + vehicle(v), + type(layout.get_catalogue().get_vehicle(vehicle.get_type())) +{ + layout.add_vehicle(*this); + layout.get_scene().add(*this); +} + +Vehicle3D::~Vehicle3D() +{ + layout.remove_vehicle(*this); + layout.get_scene().remove(*this); +} + +Point Vehicle3D::get_node() const +{ + Point p = vehicle.get_position(); + return Point(p.x, p.y, p.z+0.01+vehicle.get_type().get_height()); +} + +void Vehicle3D::render(const GL::Tag &tag) const +{ + if(tag==0) + { + GL::PushMatrix push_mat; + + const Point &pos = vehicle.get_position(); + GL::translate(pos.x, pos.y, pos.z+0.01); + GL::rotate(vehicle.get_direction()*180/M_PI, 0, 0, 1); + + type.get_body_mesh().draw(); + } +} + +} // namespace Marklin diff --git a/source/3d/vehicle.h b/source/3d/vehicle.h new file mode 100644 index 0000000..feab8a1 --- /dev/null +++ b/source/3d/vehicle.h @@ -0,0 +1,40 @@ +/* $Id$ + +This file is part of the MSP Märklin suite +Copyright © 2010 Mikkosoft Productions, Mikko Rasa +Distributed under the GPL +*/ + +#ifndef LIBMARKLIN3D_VEHICLE_H_ +#define LIBMARKLIN3D_VEHICLE_H_ + +#include +#include "libmarklin/vehicle.h" +#include "object.h" + +namespace Marklin { + +class Layout3D; +class VehicleType3D; + +class Vehicle3D: public Object3D, public Msp::GL::Renderable +{ +private: + Layout3D &layout; + Vehicle &vehicle; + const VehicleType3D &type; + +public: + Vehicle3D(Layout3D &, Vehicle &); + ~Vehicle3D(); + + Vehicle &get_vehicle() const { return vehicle; } + + virtual Point get_node() const; + + virtual void render(const Msp::GL::Tag &) const; +}; + +} // namespace Marklin + +#endif diff --git a/source/3d/vehicletype.cpp b/source/3d/vehicletype.cpp new file mode 100644 index 0000000..a808185 --- /dev/null +++ b/source/3d/vehicletype.cpp @@ -0,0 +1,51 @@ +/* $Id$ + +This file is part of the MSP Märklin suite +Copyright © 2010 Mikkosoft Productions, Mikko Rasa +Distributed under the GPL +*/ + +#include +#include +#include "vehicletype.h" + +using namespace Msp; + +namespace Marklin { + +VehicleType3D::VehicleType3D(Catalogue3D &, const VehicleType &vt): + body_mesh((GL::NORMAL3, GL::VERTEX3)) +{ + GL::Vector3 corner(vt.get_length()/2, vt.get_width()/2, vt.get_height()); + + GL::MeshBuilder bld(body_mesh); + bld.begin(GL::QUADS); + bld.normal(1, 0, 0); + bld.vertex(corner.x, -corner.y, 0); + bld.vertex(corner.x, corner.y, 0); + bld.vertex(corner.x, corner.y, corner.z); + bld.vertex(corner.x, -corner.y, corner.z); + bld.normal(-1, 0, 0); + bld.vertex(-corner.x, corner.y, 0); + bld.vertex(-corner.x, -corner.y, 0); + bld.vertex(-corner.x, -corner.y, corner.z); + bld.vertex(-corner.x, corner.y, corner.z); + bld.normal(0, 1, 0); + bld.vertex(corner.x, corner.y, 0); + bld.vertex(-corner.x, corner.y, 0); + bld.vertex(-corner.x, corner.y, corner.z); + bld.vertex(corner.x, corner.y, corner.z); + bld.normal(0, -1, 0); + bld.vertex(-corner.x, -corner.y, 0); + bld.vertex(corner.x, -corner.y, 0); + bld.vertex(corner.x, -corner.y, corner.z); + bld.vertex(-corner.x, -corner.y, corner.z); + bld.normal(0, 0, 1); + bld.vertex(-corner.x, -corner.y, corner.z); + bld.vertex(corner.x, -corner.y, corner.z); + bld.vertex(corner.x, corner.y, corner.z); + bld.vertex(-corner.x, corner.y, corner.z); + bld.end(); +} + +} // namespace Marklin diff --git a/source/3d/vehicletype.h b/source/3d/vehicletype.h new file mode 100644 index 0000000..f734e50 --- /dev/null +++ b/source/3d/vehicletype.h @@ -0,0 +1,31 @@ +/* $Id$ + +This file is part of the MSP Märklin suite +Copyright © 2010 Mikkosoft Productions, Mikko Rasa +Distributed under the GPL +*/ + +#ifndef LIBMARKLIN3D_VEHICLETYPE_H_ +#define LIBMARKLIN3D_VEHICLETYPE_H_ + +#include +#include "libmarklin/vehicletype.h" + +namespace Marklin { + +class Catalogue3D; + +class VehicleType3D +{ +private: + Msp::GL::Mesh body_mesh; + +public: + VehicleType3D(Catalogue3D &, const VehicleType &); + + const Msp::GL::Mesh &get_body_mesh() const { return body_mesh; } +}; + +} // namespace Marklin + +#endif diff --git a/source/engineer/engineer.cpp b/source/engineer/engineer.cpp index 4a35c8e..d1a123b 100644 --- a/source/engineer/engineer.cpp +++ b/source/engineer/engineer.cpp @@ -27,6 +27,8 @@ Distributed under the GPL #include "libmarklin/driver.h" #include "libmarklin/tracktype.h" #include "3d/path.h" +#include "3d/track.h" +#include "3d/vehicle.h" #include "engineer.h" #include "mainpanel.h" #include "trainpanel.h" @@ -391,9 +393,9 @@ void Engineer::train_added(Train &train) train_panels.push_back(tpanel); tpanel->set_visible(true); - Train3D &t3d = layout_3d.get_train(train); - overlay->set_label(t3d, train.get_name()); - train.signal_name_changed.connect(sigc::bind<0>(sigc::mem_fun(overlay, &Overlay3D::set_label), sigc::ref(t3d))); + Vehicle3D &loco3d = layout_3d.get_vehicle(train.get_vehicle(0)); + overlay->set_label(loco3d, train.get_name()); + train.signal_name_changed.connect(sigc::bind<0>(sigc::mem_fun(overlay, &Overlay3D::set_label), sigc::ref(loco3d))); GL::Color best_color; float best_d_sq = 0; diff --git a/source/engineer/engineer.h b/source/engineer/engineer.h index 30a3825..8ce848e 100644 --- a/source/engineer/engineer.h +++ b/source/engineer/engineer.h @@ -20,6 +20,7 @@ Distributed under the GPL #include "libmarklin/train.h" #include "3d/layout.h" #include "3d/overlay.h" +#include "3d/path.h" #include "network/server.h" #include "options.h" diff --git a/source/libmarklin/catalogue.h b/source/libmarklin/catalogue.h index f1654a1..61a336f 100644 --- a/source/libmarklin/catalogue.h +++ b/source/libmarklin/catalogue.h @@ -17,6 +17,7 @@ namespace Marklin { class LocoType; class TrackType; +class VehicleType; class Catalogue { diff --git a/source/libmarklin/layout.cpp b/source/libmarklin/layout.cpp index c093035..7855dca 100644 --- a/source/libmarklin/layout.cpp +++ b/source/libmarklin/layout.cpp @@ -182,6 +182,18 @@ void Layout::remove_train(Train &t) signal_train_removed.emit(t); } +void Layout::add_vehicle(Vehicle &v) +{ + if(vehicles.insert(&v).second) + signal_vehicle_added.emit(v); +} + +void Layout::remove_vehicle(Vehicle &v) +{ + if(vehicles.erase(&v)) + signal_vehicle_removed.emit(v); +} + void Layout::tick() { if(driver) diff --git a/source/libmarklin/layout.h b/source/libmarklin/layout.h index 608ddec..385a3cf 100644 --- a/source/libmarklin/layout.h +++ b/source/libmarklin/layout.h @@ -21,6 +21,7 @@ class Driver; class Route; class Track; class Train; +class Vehicle; class Layout { @@ -46,6 +47,8 @@ public: sigc::signal signal_route_removed; sigc::signal signal_train_added; sigc::signal signal_train_removed; + sigc::signal signal_vehicle_added; + sigc::signal signal_vehicle_removed; sigc::signal signal_block_reserved; private: @@ -56,6 +59,7 @@ private: std::map routes; std::set blocks; std::map trains; + std::set vehicles; Msp::Time::TimeStamp last_tick; public: @@ -89,6 +93,9 @@ public: const std::map &get_trains() const { return trains; } void remove_train(Train &); + void add_vehicle(Vehicle &); + void remove_vehicle(Vehicle &); + void tick(); void save(const std::string &); diff --git a/source/libmarklin/locotype.cpp b/source/libmarklin/locotype.cpp index 7a1becf..c00f7d3 100644 --- a/source/libmarklin/locotype.cpp +++ b/source/libmarklin/locotype.cpp @@ -12,7 +12,7 @@ using namespace std; namespace Marklin { LocoType::LocoType(unsigned an): - art_nr(an) + VehicleType(an) { } unsigned LocoType::get_max_function() const @@ -24,15 +24,14 @@ unsigned LocoType::get_max_function() const LocoType::Loader::Loader(LocoType <): - Msp::DataFile::BasicLoader(lt) + VehicleType::Loader(lt) { add("function", &Loader::function); - add("name", &LocoType::name); } void LocoType::Loader::function(unsigned i, const string &f) { - obj.funcs[i] = f; + static_cast(obj).funcs[i] = f; } } // namespace Marklin diff --git a/source/libmarklin/locotype.h b/source/libmarklin/locotype.h index 5fd34d8..8234c4f 100644 --- a/source/libmarklin/locotype.h +++ b/source/libmarklin/locotype.h @@ -8,14 +8,14 @@ Distributed under the GPL #ifndef LIBMARKLIN_LOCOTYPE_H_ #define LIBMARKLIN_LOCOTYPE_H_ -#include +#include "vehicletype.h" namespace Marklin { -class LocoType +class LocoType: public VehicleType { public: - class Loader: public Msp::DataFile::BasicLoader + class Loader: public VehicleType::Loader { public: Loader(LocoType &); @@ -30,8 +30,6 @@ private: public: LocoType(unsigned); - unsigned get_article_number() const { return art_nr; } - const std::string &get_name() const { return name; } unsigned get_max_function() const; const std::map &get_functions() const { return funcs; } }; diff --git a/source/libmarklin/track.cpp b/source/libmarklin/track.cpp index fc36586..030af70 100644 --- a/source/libmarklin/track.cpp +++ b/source/libmarklin/track.cpp @@ -300,6 +300,7 @@ TrackPoint Track::get_point(unsigned epi, unsigned path, float d) const float s = sin(rot); p.pos = Point(pos.x+c*p.pos.x-s*p.pos.y, pos.y+s*p.pos.x+c*p.pos.y, 0); + p.dir += rot; if(type.get_endpoints().size()==2) { float len = type.get_path_length(path); @@ -319,6 +320,11 @@ TrackPoint Track::get_point(unsigned epi, unsigned path, float d) const return p; } +TrackPoint Track::get_point(unsigned epi, float d) const +{ + return get_point(epi, active_path, d); +} + void Track::save(list &st) const { st.push_back((DataFile::Statement("position"), pos.x, pos.y, pos.z)); diff --git a/source/libmarklin/track.h b/source/libmarklin/track.h index 7a36a2d..008b81d 100644 --- a/source/libmarklin/track.h +++ b/source/libmarklin/track.h @@ -81,6 +81,7 @@ public: Track *get_link(unsigned) const; unsigned traverse(unsigned, unsigned) const; TrackPoint get_point(unsigned, unsigned, float) const; + TrackPoint get_point(unsigned, float) const; void save(std::list &) const; private: diff --git a/source/libmarklin/train.cpp b/source/libmarklin/train.cpp index f745313..a877174 100644 --- a/source/libmarklin/train.cpp +++ b/source/libmarklin/train.cpp @@ -15,6 +15,7 @@ Distributed under the GPL #include "route.h" #include "tracktype.h" #include "train.h" +#include "vehicle.h" using namespace std; using namespace Msp; @@ -37,9 +38,10 @@ Train::Train(Layout &l, const LocoType &t, unsigned a): travel_dist(0), travel_speed(0), pure_speed(false), - real_speed(15), - cur_track(0) + real_speed(15) { + vehicles.push_back(new Vehicle(layout, loco_type)); + layout.add_train(*this); layout.get_driver().add_loco(address); @@ -53,6 +55,8 @@ Train::Train(Layout &l, const LocoType &t, unsigned a): Train::~Train() { + for(vector::iterator i=vehicles.begin(); i!=vehicles.end(); ++i) + delete *i; layout.remove_train(*this); } @@ -63,6 +67,20 @@ void Train::set_name(const string &n) signal_name_changed.emit(name); } +Vehicle &Train::get_vehicle(unsigned i) +{ + if(i>=vehicles.size()) + throw InvalidParameterValue("Vehicle index out of range"); + return *vehicles[i]; +} + +const Vehicle &Train::get_vehicle(unsigned i) const +{ + if(i>=vehicles.size()) + throw InvalidParameterValue("Vehicle index out of range"); + return *vehicles[i]; +} + void Train::set_speed(unsigned speed) { if(speed==target_speed) @@ -102,12 +120,7 @@ void Train::set_reverse(bool rev) release_blocks(rsv_blocks); reverse_blocks(cur_blocks); - if(cur_track) - { - unsigned path = cur_track->get_active_path(); - cur_track_ep = cur_track->traverse(cur_track_ep, path); - offset = cur_track->get_type().get_path_length(path)-offset; - } + // XXX Do something about the vehicles } void Train::set_function(unsigned func, bool state) @@ -245,34 +258,16 @@ void Train::tick(const Time::TimeStamp &t, const Time::TimeDelta &dt) stop_timeout = Time::TimeStamp(); } - if(cur_track) + if(current_speed) { - unsigned path = cur_track->get_active_path(); - - offset += get_real_speed(current_speed)*(dt/Time::sec); - float path_len = cur_track->get_type().get_path_length(path); - if(offset>path_len) - { - unsigned out = cur_track->traverse(cur_track_ep, path); - Track *next = cur_track->get_link(out); - - bool ok = false; - for(list::const_iterator i=cur_blocks.begin(); (!ok && i!=cur_blocks.end()); ++i) - ok = i->block->get_tracks().count(next); + Track *track = vehicles[0]->get_track(); - if(ok) - { - if(next) - cur_track_ep = next->get_endpoint_by_link(*cur_track); - cur_track = next; - offset = 0; - } - else - offset = path_len-0.001; - } + bool ok = false; + for(list::const_iterator i=cur_blocks.begin(); (!ok && i!=cur_blocks.end()); ++i) + ok = i->block->get_tracks().count(track); - if(cur_track) - pos = cur_track->get_point(cur_track_ep, path, offset).pos; + if(ok) + vehicles[0]->advance(get_real_speed(current_speed)*(dt/Time::sec)); } } @@ -669,10 +664,7 @@ void Train::set_status(const string &s) void Train::set_position(const Block::Endpoint &bep) { - cur_track = bep.track; - cur_track_ep = bep.track_ep; - offset = 0; - pos = cur_track->get_endpoint_position(cur_track_ep); + vehicles[0]->place(bep.track, bep.track_ep, 0, Vehicle::FRONT_AXLE); } void Train::release_blocks(list &blocks) diff --git a/source/libmarklin/train.h b/source/libmarklin/train.h index b579d7f..f9dba5d 100644 --- a/source/libmarklin/train.h +++ b/source/libmarklin/train.h @@ -17,6 +17,7 @@ namespace Marklin { class LocoType; class Route; +class Vehicle; class Train: public sigc::trackable { @@ -67,6 +68,7 @@ private: const LocoType &loco_type; unsigned address; std::string name; + std::vector vehicles; std::list cur_blocks; std::list rsv_blocks; Block *pending_block; @@ -86,11 +88,6 @@ private: bool pure_speed; std::vector real_speed; - Track *cur_track; - unsigned cur_track_ep; - float offset; - Point pos; - public: Train(Layout &, const LocoType &, unsigned); ~Train(); @@ -100,6 +97,9 @@ public: void set_name(const std::string &); const std::string &get_name() const { return name; } + Vehicle &get_vehicle(unsigned); + const Vehicle &get_vehicle(unsigned) const; + void set_speed(unsigned); void set_reverse(bool); void set_function(unsigned, bool); @@ -118,7 +118,6 @@ public: int get_entry_to_block(Block &) const; const std::string &get_status() const { return status; } - const Point &get_position() const { return pos; } void tick(const Msp::Time::TimeStamp &, const Msp::Time::TimeDelta &); diff --git a/source/libmarklin/vehicle.cpp b/source/libmarklin/vehicle.cpp new file mode 100644 index 0000000..7c299c7 --- /dev/null +++ b/source/libmarklin/vehicle.cpp @@ -0,0 +1,189 @@ +/* $Id$ + +This file is part of the MSP Märklin suite +Copyright © 2010 Mikkosoft Productions, Mikko Rasa +Distributed under the GPL +*/ + +#include +#include "catalogue.h" +#include "layout.h" +#include "track.h" +#include "tracktype.h" +#include "vehicle.h" +#include "vehicletype.h" + +using namespace std; + +namespace Marklin { + +Vehicle::Vehicle(Layout &l, const VehicleType &t): + layout(l), + type(t), + next(0), + prev(0), + direction(0) +{ + layout.add_vehicle(*this); +} + +Vehicle::~Vehicle() +{ + layout.remove_vehicle(*this); +} + +void Vehicle::place(Track *t, unsigned e, float o, PlaceMode m) +{ + track_pos = TrackPosition(t, e, o); + if(m==FRONT_AXLE) + { + float front = type.get_length()/2; + if(!type.get_axles().empty()) + front = type.get_axles().front().position; + if(!type.get_bogies().empty()) + { + const VehicleType::Bogie &bogie = type.get_bogies().front(); + front = max(front, bogie.position+bogie.axles.front().position); + } + track_pos.advance(-front); + } + update_position(); +} + +void Vehicle::advance(float d) +{ + track_pos.advance(d); + update_position(); +} + +void Vehicle::update_position() +{ + TrackPoint tp; + + const vector &axles = type.get_axles(); + if(axles.size()>=2) + tp = get_position(axles.front().position, axles.back().position, track_pos); + else + { + const vector &bogies = type.get_bogies(); + if(bogies.size()>=2) + // XXX Calculate bogie positions correctly + tp = get_position(bogies.front().position, bogies.back().position, track_pos); + else + tp = track_pos.get_point(); + } + position = tp.pos; + direction = tp.dir; +} + +TrackPoint Vehicle::get_position(float front, float back, const TrackPosition &tpos) +{ + TrackPosition front_pos = tpos; + front_pos.advance(front); + + TrackPosition back_pos = tpos; + back_pos.advance(back); + + float target_dist = front-back; + + while(1) + { + Point front_point = front_pos.get_point().pos; + Point back_point = back_pos.get_point().pos; + + float dx = front_point.x-back_point.x; + float dy = front_point.y-back_point.y; + float dz = front_point.z-back_point.z; + float dist = sqrt(dx*dx+dy*dy+dz*dz); + + if(distget_active_path(); + + offs += d; + float path_len = track->get_type().get_path_length(path); + while(track && offs>=path_len) + { + unsigned out = track->traverse(ep, path); + Track *next = track->get_link(out); + + if(next) + { + ep = next->get_endpoint_by_link(*track); + track = next; + + offs -= path_len; + path = track->get_active_path(); + path_len = track->get_type().get_path_length(path); + } + else + track = 0; + } + + while(track && offs<0) + { + Track *prev = track->get_link(ep); + if(prev) + { + unsigned in = prev->get_endpoint_by_link(*track); + track = prev; + + path = track->get_active_path(); + ep = track->traverse(in, path); + + path_len = track->get_type().get_path_length(path); + offs += path_len; + } + else + track = 0; + } + + if(!track) + { + ep = 0; + offs = 0; + } +} + +TrackPoint Vehicle::TrackPosition::get_point() const +{ + if(track) + return track->get_point(ep, offs); + else + return TrackPoint(); +} + +} // namespace Marklin diff --git a/source/libmarklin/vehicle.h b/source/libmarklin/vehicle.h new file mode 100644 index 0000000..dcf7737 --- /dev/null +++ b/source/libmarklin/vehicle.h @@ -0,0 +1,67 @@ +/* $Id$ + +This file is part of the MSP Märklin suite +Copyright © 2010 Mikkosoft Productions, Mikko Rasa +Distributed under the GPL +*/ + +#ifndef LIBMARKLIN_VEHICLE_H_ +#define LIBMARKLIN_VEHICLE_H_ + +#include "geometry.h" + +namespace Marklin { + +class Layout; +class Track; +class VehicleType; + +class Vehicle +{ +public: + enum PlaceMode + { + CENTER, + FRONT_AXLE + }; + +private: + struct TrackPosition + { + Track *track; + unsigned ep; + float offs; + + TrackPosition(); + TrackPosition(Track *, unsigned, float); + void advance(float); + TrackPoint get_point() const; + }; + + Layout &layout; + const VehicleType &type; + Vehicle *next; + Vehicle *prev; + TrackPosition track_pos; + Point position; + float direction; + +public: + Vehicle(Layout &, const VehicleType &); + ~Vehicle(); + + const VehicleType &get_type() const { return type; } + + void place(Track *, unsigned, float, PlaceMode = CENTER); + void advance(float); + Track *get_track() const { return track_pos.track; } + const Point &get_position() const { return position; } + float get_direction() const { return direction; } +private: + void update_position(); + TrackPoint get_position(float, float, const TrackPosition &); +}; + +} // namespace Marklin + +#endif diff --git a/source/libmarklin/vehicletype.cpp b/source/libmarklin/vehicletype.cpp new file mode 100644 index 0000000..0913401 --- /dev/null +++ b/source/libmarklin/vehicletype.cpp @@ -0,0 +1,101 @@ +/* $Id$ + +This file is part of the MSP Märklin suite +Copyright © 2010 Mikkosoft Productions, Mikko Rasa +Distributed under the GPL +*/ + +#include "vehicletype.h" + +using namespace Msp; + +namespace Marklin { + +VehicleType::VehicleType(unsigned n): + art_nr(n), + length(0), + width(0), + height(0) +{ } + + +VehicleType::Loader::Loader(VehicleType &vt): + DataFile::ObjectLoader(vt) +{ + add("axle", &Loader::axle); + add("bogie", &Loader::bogie); + add("height", &Loader::height); + add("length", &Loader::length); + add("name", &VehicleType::name); + add("width", &Loader::width); +} + +void VehicleType::Loader::axle() +{ + Axle axl; + load_sub(axl); + obj.axles.push_back(axl); +} + +void VehicleType::Loader::bogie() +{ + Bogie bog; + load_sub(bog); + obj.bogies.push_back(bog); +} + +void VehicleType::Loader::height(float h) +{ + obj.height = h/1000; +} + +void VehicleType::Loader::length(float l) +{ + obj.length = l/1000; +} + +void VehicleType::Loader::width(float w) +{ + obj.width = w/1000; +} + + +VehicleType::Axle::Loader::Loader(Axle &a): + DataFile::ObjectLoader(a) +{ + add("position", &Loader::position); + add("wheel_diameter", &Loader::wheel_diameter); + add("powered", &Axle::powered); +} + +void VehicleType::Axle::Loader::position(float p) +{ + obj.position = p/1000; +} + +void VehicleType::Axle::Loader::wheel_diameter(float d) +{ + obj.wheel_dia = d/1000; +} + + +VehicleType::Bogie::Loader::Loader(Bogie &b): + DataFile::ObjectLoader(b) +{ + add("position", &Loader::position); + add("axle", &Loader::axle); +} + +void VehicleType::Bogie::Loader::axle() +{ + Axle axl; + load_sub(axl); + obj.axles.push_back(axl); +} + +void VehicleType::Bogie::Loader::position(float p) +{ + obj.position = p/1000; +} + +} // namespace Marklin diff --git a/source/libmarklin/vehicletype.h b/source/libmarklin/vehicletype.h new file mode 100644 index 0000000..6c33890 --- /dev/null +++ b/source/libmarklin/vehicletype.h @@ -0,0 +1,84 @@ +/* $Id$ + +This file is part of the MSP Märklin suite +Copyright © 2010 Mikkosoft Productions, Mikko Rasa +Distributed under the GPL +*/ + +#ifndef LIBMARKLIN_VEHICLETYPE_H_ +#define LIBMARKLIN_VEHICLETYPE_H_ + +#include + +namespace Marklin { + +class VehicleType +{ +public: + class Loader: public Msp::DataFile::ObjectLoader + { + public: + Loader(VehicleType &); + private: + void axle(); + void bogie(); + void height(float); + void length(float); + void width(float); + }; + + struct Axle + { + class Loader: public Msp::DataFile::ObjectLoader + { + public: + Loader(Axle &); + private: + void position(float); + void wheel_diameter(float); + }; + + float position; + float wheel_dia; + bool powered; + }; + + struct Bogie + { + class Loader: public Msp::DataFile::ObjectLoader + { + public: + Loader(Bogie &); + private: + void axle(); + void position(float); + }; + + float position; + std::vector axles; + }; + +private: + unsigned art_nr; + std::string name; + float length; + float width; + float height; + std::vector axles; + std::vector bogies; + +public: + VehicleType(unsigned); + + unsigned get_article_number() const { return art_nr; } + const std::string &get_name() const { return name; } + float get_length() const { return length; } + float get_width() const { return width; } + float get_height() const { return height; } + const std::vector &get_axles() const { return axles; } + const std::vector &get_bogies() const { return bogies; } +}; + +} // namespace Marklin + +#endif -- 2.43.0