]> git.tdb.fi Git - r2c2.git/commitdiff
Add vehicles
authorMikko Rasa <tdb@tdb.fi>
Tue, 6 Apr 2010 08:08:54 +0000 (08:08 +0000)
committerMikko Rasa <tdb@tdb.fi>
Tue, 6 Apr 2010 08:08:54 +0000 (08:08 +0000)
Fix direction in Track::get_point
Add overload of Track::get_point that uses the current path

26 files changed:
locos.dat
source/3d/catalogue.cpp
source/3d/catalogue.h
source/3d/layout.cpp
source/3d/layout.h
source/3d/train.cpp [deleted file]
source/3d/train.h [deleted file]
source/3d/vehicle.cpp [new file with mode: 0644]
source/3d/vehicle.h [new file with mode: 0644]
source/3d/vehicletype.cpp [new file with mode: 0644]
source/3d/vehicletype.h [new file with mode: 0644]
source/engineer/engineer.cpp
source/engineer/engineer.h
source/libmarklin/catalogue.h
source/libmarklin/layout.cpp
source/libmarklin/layout.h
source/libmarklin/locotype.cpp
source/libmarklin/locotype.h
source/libmarklin/track.cpp
source/libmarklin/track.h
source/libmarklin/train.cpp
source/libmarklin/train.h
source/libmarklin/vehicle.cpp [new file with mode: 0644]
source/libmarklin/vehicle.h [new file with mode: 0644]
source/libmarklin/vehicletype.cpp [new file with mode: 0644]
source/libmarklin/vehicletype.h [new file with mode: 0644]

index f44c9beb5635c664550cfc19ace054930fe46d50..e2f57565e7218bf0de6b411928a769d201603eea 100644 (file)
--- 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; };
+       };
 };
index 54341c10c0432e7344d30d35cda86cf3724b2596..1068feafdfa87a1933c538e06d5921049107a9b5 100644 (file)
@@ -6,8 +6,10 @@ Distributed under the GPL
 */
 
 #include <msp/gl/meshbuilder.h>
+#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<unsigned, TrackType *> &trks = catalogue.get_tracks();
        for(map<unsigned, TrackType *>::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 VehicleType *, VehicleType3D *>::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();
index 6cc5bede4fcdc27f2faa845c1e96d723888f9eb0..d826a780381990b6a471c0e47f7b56053e062d71 100644 (file)
@@ -15,12 +15,14 @@ Distributed under the GPL
 namespace Marklin {
 
 class TrackType3D;
+class VehicleType3D;
 
 class Catalogue3D
 {
 private:
        Catalogue &catalogue;
        std::map<const TrackType *, TrackType3D *> tracks;
+       std::map<const VehicleType *, VehicleType3D *> 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();
 };
 
index 1a557153fda308ce56a18066e281ca2e3e1b8830..70c55096cfa91eed259b6be9ebd99ef701dfd88c 100644 (file)
@@ -14,6 +14,8 @@ Distributed under the GPL
 #include <msp/gl/texture.h>
 #include <msp/datafile/parser.h>
 #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<Track *> &ltracks = layout.get_tracks();
        for(set<Track *>::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<unsigned>::max();
        for(vector<GL::SelectRecord>::iterator i=select_buf.begin(); i!=select_buf.end(); ++i)
-               if(i->min_depth<track_depth)
+               if(i->min_depth<track_depth && !i->names.empty())
                {
                        track = reinterpret_cast<Track3D *>(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<Train3D *>::iterator i = find(trains.begin(), trains.end(), &t);
-       if(i!=trains.end())
-               trains.erase(i);
+       list<Vehicle3D *>::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<Train3D *>::const_iterator i=trains.begin(); i!=trains.end(); ++i)
-               if(&(*i)->get_train()==&t)
+       for(list<Vehicle3D *>::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
index 8fcd713a2c7be76c3b7a9ef247075f7d2f08feae..a0c77868ae58bc68a3c804843622996d119d2263 100644 (file)
@@ -12,18 +12,19 @@ Distributed under the GPL
 #include <msp/gl/scene.h>
 #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<Track3D *> tracks;
-       std::list<Train3D *> trains;
+       std::list<Vehicle3D *> 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 (file)
index d14225e..0000000
+++ /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 (file)
index 098d344..0000000
+++ /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 (file)
index 0000000..4fbac68
--- /dev/null
@@ -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 <cmath>
+#include <msp/gl/matrix.h>
+#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 (file)
index 0000000..feab8a1
--- /dev/null
@@ -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 <msp/gl/renderable.h>
+#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 (file)
index 0000000..a808185
--- /dev/null
@@ -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 <msp/gl/meshbuilder.h>
+#include <msp/gl/vector.h>
+#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 (file)
index 0000000..f734e50
--- /dev/null
@@ -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 <msp/gl/mesh.h>
+#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
index 4a35c8e0cd381bc6307f24e828c8352d68152239..d1a123bb7b5e44282e7045da291309a67a8dc91c 100644 (file)
@@ -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;
index 30a3825893827539c8328487e91b76e15c8037eb..8ce848e8779f971f408c077729b032e1f298d6ef 100644 (file)
@@ -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"
 
index f1654a19d62add8b8f5c31fdd95295acb837e10b..61a336f5f6c2e7441f6cb05cd38aa934b54e8734 100644 (file)
@@ -17,6 +17,7 @@ namespace Marklin {
 
 class LocoType;
 class TrackType;
+class VehicleType;
 
 class Catalogue
 {
index c0930352fb7d2b171f7279a55c0dd1fddffc454b..7855dca7d7115333dc1b060ff4f3d57b68950bbd 100644 (file)
@@ -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)
index 608ddece1eed1c2398fc36b101d2b0d6fb0c5063..385a3cfab760e17d7beab074501e6d4cd3bf30ce 100644 (file)
@@ -21,6 +21,7 @@ class Driver;
 class Route;
 class Track;
 class Train;
+class Vehicle;
 
 class Layout
 {
@@ -46,6 +47,8 @@ public:
        sigc::signal<void, Route &> signal_route_removed;
        sigc::signal<void, Train &> signal_train_added;
        sigc::signal<void, Train &> signal_train_removed;
+       sigc::signal<void, Vehicle &> signal_vehicle_added;
+       sigc::signal<void, Vehicle &> signal_vehicle_removed;
        sigc::signal<void, Block &, Train *> signal_block_reserved;
 
 private:
@@ -56,6 +59,7 @@ private:
        std::map<std::string, Route *> routes;
        std::set<Block *> blocks;
        std::map<unsigned, Train *> trains;
+       std::set<Vehicle *> vehicles;
        Msp::Time::TimeStamp last_tick;
 
 public:
@@ -89,6 +93,9 @@ public:
        const std::map<unsigned, Train *> &get_trains() const { return trains; }
        void remove_train(Train &);
 
+       void add_vehicle(Vehicle &);
+       void remove_vehicle(Vehicle &);
+
        void tick();
 
        void save(const std::string &);
index 7a1becf35ac5152db6d926a1c73673ed271ea895..c00f7d3a94deda2c2586d4f66b080c1a71367ca0 100644 (file)
@@ -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 &lt):
-       Msp::DataFile::BasicLoader<LocoType>(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<LocoType &>(obj).funcs[i] = f;
 }
 
 } // namespace Marklin
index 5fd34d8c32f20d56d043075e7fa5dfd9d72ed985..8234c4f45d1e85a661462c9bf46b9319a9d01d21 100644 (file)
@@ -8,14 +8,14 @@ Distributed under the GPL
 #ifndef LIBMARKLIN_LOCOTYPE_H_
 #define LIBMARKLIN_LOCOTYPE_H_
 
-#include <msp/datafile/loader.h>
+#include "vehicletype.h"
 
 namespace Marklin {
 
-class LocoType
+class LocoType: public VehicleType
 {
 public:
-       class Loader: public Msp::DataFile::BasicLoader<LocoType>
+       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<unsigned, std::string> &get_functions() const { return funcs; }
 };
index fc365862301c9acfa0734ccd3b510b7a5c6cbe77..030af70bc85fd1d2e667b4e47a24830a7ac915ea 100644 (file)
@@ -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<DataFile::Statement> &st) const
 {
        st.push_back((DataFile::Statement("position"), pos.x, pos.y, pos.z));
index 7a36a2d6f8bdd15faa90d8958029f782869178a8..008b81dd4a169c46429e17f4f972f7cb14322eac 100644 (file)
@@ -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<Msp::DataFile::Statement> &) const;
 private:
index f745313233d57ce7e2b513ee2628c815c69dade2..a87717480bf7806d77b0e014bb2baf2b54e94d0b 100644 (file)
@@ -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<Vehicle *>::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<BlockRef>::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<BlockRef>::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<BlockRef> &blocks)
index b579d7f37deba40ba47d607baabf0e42817e7de7..f9dba5dfbabb68339fd71ddc3fd4a0fd353ff816 100644 (file)
@@ -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<Vehicle *> vehicles;
        std::list<BlockRef> cur_blocks;
        std::list<BlockRef> rsv_blocks;
        Block *pending_block;
@@ -86,11 +88,6 @@ private:
        bool pure_speed;
        std::vector<RealSpeed> 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 (file)
index 0000000..7c299c7
--- /dev/null
@@ -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 <cmath>
+#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<VehicleType::Axle> &axles = type.get_axles();
+       if(axles.size()>=2)
+               tp = get_position(axles.front().position, axles.back().position, track_pos);
+       else
+       {
+               const vector<VehicleType::Bogie> &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(dist<target_dist)
+               {
+                       float adjust = target_dist-dist+0.01*layout.get_catalogue().get_scale();
+                       front_pos.advance(adjust/2);
+                       back_pos.advance(-adjust/2);
+               }
+               else
+               {
+                       float f = -back/target_dist;
+                       TrackPoint pt;
+                       pt.pos = Point(back_point.x+dx*f, back_point.y+dy*f, back_point.z+dz*f);
+                       pt.dir = atan2(dy, dx);
+                       return pt;
+               }
+       }
+}
+
+
+Vehicle::TrackPosition::TrackPosition():
+       track(0),
+       ep(0),
+       offs(0)
+{ }
+
+Vehicle::TrackPosition::TrackPosition(Track *t, unsigned e, float o):
+       track(t),
+       ep(e),
+       offs(o)
+{ }
+
+void Vehicle::TrackPosition::advance(float d)
+{
+       if(!track)
+               return;
+
+       unsigned path = track->get_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 (file)
index 0000000..dcf7737
--- /dev/null
@@ -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 (file)
index 0000000..0913401
--- /dev/null
@@ -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<VehicleType>(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<Axle>(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<Bogie>(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 (file)
index 0000000..6c33890
--- /dev/null
@@ -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 <msp/datafile/objectloader.h>
+
+namespace Marklin {
+
+class VehicleType
+{
+public:
+       class Loader: public Msp::DataFile::ObjectLoader<VehicleType>
+       {
+       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<Axle>
+               {
+               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<Bogie>
+               {
+               public:
+                       Loader(Bogie &);
+               private:
+                       void axle();
+                       void position(float);
+               };
+
+               float position;
+               std::vector<Axle> axles;
+       };
+
+private:
+       unsigned art_nr;
+       std::string name;
+       float length;
+       float width;
+       float height;
+       std::vector<Axle> axles;
+       std::vector<Bogie> 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<Axle> &get_axles() const { return axles; }
+       const std::vector<Bogie> &get_bogies() const { return bogies; }
+};
+
+} // namespace Marklin
+
+#endif