]> git.tdb.fi Git - r2c2.git/commitdiff
Render vehicles with real 3D models
authorMikko Rasa <tdb@tdb.fi>
Sun, 18 Apr 2010 11:16:37 +0000 (11:16 +0000)
committerMikko Rasa <tdb@tdb.fi>
Sun, 18 Apr 2010 11:16:37 +0000 (11:16 +0000)
source/3d/vehicle.cpp
source/3d/vehicletype.cpp
source/3d/vehicletype.h
source/libmarklin/vehicle.cpp
source/libmarklin/vehicle.h
source/libmarklin/vehicletype.cpp
source/libmarklin/vehicletype.h

index 4fbac68c0ea36c952bbe537022315d7db383d923..41bb26259da3b2a769c7a93e427acfb76ab1fe0b 100644 (file)
@@ -11,6 +11,7 @@ Distributed under the GPL
 #include "vehicle.h"
 #include "vehicletype.h"
 
+using namespace std;
 using namespace Msp;
 
 namespace Marklin {
@@ -46,7 +47,21 @@ void Vehicle3D::render(const GL::Tag &tag) const
                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();
+               if(type.get_body_object())
+                       type.get_body_object()->render(tag);
+
+               const vector<VehicleType::Bogie> &bogies = vehicle.get_type().get_bogies();
+               for(unsigned i=0; i<bogies.size(); ++i)
+               {
+                       GL::PushMatrix push_mat2;
+                       GL::translate(bogies[i].position, 0, 0);
+                       float angle = vehicle.get_bogie_direction(i)*180/M_PI;
+                       if(bogies[i].rotate_object)
+                               angle += 180;
+                       GL::rotate(angle, 0, 0, 1);
+                       if(type.get_bogie_object(i))
+                               type.get_bogie_object(i)->render(tag);
+               }
        }
 }
 
index a808185afd942776868de45f14d9646c5e9d545d..91c123866de22888bd67e8ed725bc92e6b080741 100644 (file)
@@ -7,45 +7,59 @@ Distributed under the GPL
 
 #include <msp/gl/meshbuilder.h>
 #include <msp/gl/vector.h>
+#include "catalogue.h"
 #include "vehicletype.h"
 
+using namespace std;
 using namespace Msp;
 
 namespace Marklin {
 
 VehicleType3D::VehicleType3D(Catalogue3D &, const VehicleType &vt):
-       body_mesh((GL::NORMAL3, GL::VERTEX3))
+       body_object(0),
+       bogie_objects(vt.get_bogies().size())
 {
-       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();
+       body_object = get_object(vt.get_object());
+
+       for(unsigned i=0; i<bogie_objects.size(); ++i)
+               bogie_objects[i] = get_object(vt.get_bogies()[i].object);
+}
+
+VehicleType3D::~VehicleType3D()
+{
+       for(map<string, GL::Object *>::iterator i=objects.begin(); i!=objects.end(); ++i)
+               delete i->second;
+}
+
+const GL::Object *VehicleType3D::get_axle_object(unsigned) const
+{
+       return 0;
+}
+
+const GL::Object *VehicleType3D::get_bogie_object(unsigned i) const
+{
+       if(i>=bogie_objects.size())
+               throw InvalidParameterValue("Bogie index out of range");
+       return bogie_objects[i];
+}
+
+const GL::Object *VehicleType3D::get_bogie_axle_object(unsigned, unsigned) const
+{
+       return 0;
+}
+
+GL::Object *VehicleType3D::get_object(const string &name)
+{
+       if(name.empty())
+               return 0;
+
+       GL::Object *&ptr = objects[name];
+       if(!ptr)
+       {
+               ptr = new GL::Object;
+               DataFile::load(*ptr, name);
+       }
+       return ptr;
 }
 
 } // namespace Marklin
index f734e50d9468d49de118b7505ba404028a63f679..c5c491a7fe63c9973024b2aba908fd7c1670a306 100644 (file)
@@ -9,6 +9,7 @@ Distributed under the GPL
 #define LIBMARKLIN3D_VEHICLETYPE_H_
 
 #include <msp/gl/mesh.h>
+#include <msp/gl/object.h>
 #include "libmarklin/vehicletype.h"
 
 namespace Marklin {
@@ -18,12 +19,20 @@ class Catalogue3D;
 class VehicleType3D
 {
 private:
-       Msp::GL::Mesh body_mesh;
+       std::map<std::string, Msp::GL::Object *> objects;
+       Msp::GL::Object *body_object;
+       std::vector<Msp::GL::Object *> bogie_objects;
 
 public:
        VehicleType3D(Catalogue3D &, const VehicleType &);
+       ~VehicleType3D();
 
-       const Msp::GL::Mesh &get_body_mesh() const { return body_mesh; }
+       const Msp::GL::Object *get_body_object() const { return body_object; }
+       const Msp::GL::Object *get_axle_object(unsigned) const;
+       const Msp::GL::Object *get_bogie_object(unsigned) const;
+       const Msp::GL::Object *get_bogie_axle_object(unsigned, unsigned) const;
+private:
+       Msp::GL::Object *get_object(const std::string &);
 };
 
 } // namespace Marklin
index 8d52a7f07816121d071b5d1e6aaf4adc42f23dcd..1f3d3ec178e56a771987264a495b5c20982d80b9 100644 (file)
@@ -23,7 +23,8 @@ Vehicle::Vehicle(Layout &l, const VehicleType &t):
        type(t),
        next(0),
        prev(0),
-       direction(0)
+       direction(0),
+       bogie_dirs(type.get_bogies().size())
 {
        layout.add_vehicle(*this);
 }
@@ -113,6 +114,13 @@ void Vehicle::advance(float d)
        propagate_position();
 }
 
+float Vehicle::get_bogie_direction(unsigned i) const
+{
+       if(i>=bogie_dirs.size())
+               throw InvalidParameterValue("Bogie index out of range");
+       return bogie_dirs[i];
+}
+
 void Vehicle::update_position()
 {
        TrackPoint tp;
@@ -137,13 +145,16 @@ void Vehicle::update_position()
 
                        const vector<VehicleType::Axle> &front_axles = bogies.front().axles;
                        float wheelbase = front_axles.front().position-front_axles.back().position;
-                       Point front_point = get_point(front, wheelbase, -front_axles.back().position/wheelbase).pos;
+                       TrackPoint front_point = get_point(front, wheelbase, -front_axles.back().position/wheelbase);
 
                        const vector<VehicleType::Axle> &back_axles = bogies.back().axles;
                        wheelbase = back_axles.front().position-back_axles.back().position;
-                       Point back_point = get_point(back, wheelbase, -back_axles.back().position/wheelbase).pos;
+                       TrackPoint back_point = get_point(back, wheelbase, -back_axles.back().position/wheelbase);
+
+                       tp = get_point(front_point.pos, back_point.pos, -bogies.back().position/bogie_spacing);
 
-                       tp = get_point(front_point, back_point, -bogies.back().position/bogie_spacing);
+                       bogie_dirs.front() = front_point.dir-tp.dir;
+                       bogie_dirs.back() = back_point.dir-tp.dir;
                }
                else
                        tp = track_pos.get_point();
index c58df764917c0ea6c4cefb20006f756d3a2f19db..303c6686a339d6fc938823f6e80ac2d0426b373b 100644 (file)
@@ -48,6 +48,7 @@ private:
        TrackPosition track_pos;
        Point position;
        float direction;
+       std::vector<float> bogie_dirs;
 
 public:
        Vehicle(Layout &, const VehicleType &);
@@ -69,6 +70,7 @@ public:
        float get_offset() const { return track_pos.offs; }
        const Point &get_position() const { return position; }
        float get_direction() const { return direction; }
+       float get_bogie_direction(unsigned) const;
 private:
        void update_position();
        void update_position_from(const Vehicle &);
index 0913401e45b89b12c301361b6bc56655cf7444c5..0c057e26203b79075eb1207f2c4b6c4b7bbda2f3 100644 (file)
@@ -19,6 +19,19 @@ VehicleType::VehicleType(unsigned n):
 { }
 
 
+VehicleType::Axle::Axle():
+       position(0),
+       wheel_dia(0),
+       powered(false)
+{ }
+
+
+VehicleType::Bogie::Bogie():
+       position(0),
+       rotate_object(false)
+{ }
+
+
 VehicleType::Loader::Loader(VehicleType &vt):
        DataFile::ObjectLoader<VehicleType>(vt)
 {
@@ -26,6 +39,7 @@ VehicleType::Loader::Loader(VehicleType &vt):
        add("bogie",  &Loader::bogie);
        add("height", &Loader::height);
        add("length", &Loader::length);
+       add("object", &VehicleType::object);
        add("name",   &VehicleType::name);
        add("width",  &Loader::width);
 }
@@ -64,8 +78,8 @@ VehicleType::Axle::Loader::Loader(Axle &a):
        DataFile::ObjectLoader<Axle>(a)
 {
        add("position",       &Loader::position);
-       add("wheel_diameter", &Loader::wheel_diameter);
        add("powered",        &Axle::powered);
+       add("wheel_diameter", &Loader::wheel_diameter);
 }
 
 void VehicleType::Axle::Loader::position(float p)
@@ -82,8 +96,10 @@ void VehicleType::Axle::Loader::wheel_diameter(float d)
 VehicleType::Bogie::Loader::Loader(Bogie &b):
        DataFile::ObjectLoader<Bogie>(b)
 {
-       add("position", &Loader::position);
-       add("axle",     &Loader::axle);
+       add("axle",          &Loader::axle);
+       add("object",        &Bogie::object);
+       add("position",      &Loader::position);
+       add("rotate_object", &Bogie::rotate_object);
 }
 
 void VehicleType::Bogie::Loader::axle()
index 01e678b05ee17c077dabb0895a6f3bd03bbf13aa..65f69e766d54ca66d48d3bb9000a6f68ab2bad22 100644 (file)
@@ -41,6 +41,8 @@ public:
                float position;
                float wheel_dia;
                bool powered;
+
+               Axle();
        };
 
        struct Bogie
@@ -56,6 +58,10 @@ public:
 
                float position;
                std::vector<Axle> axles;
+               std::string object;
+               bool rotate_object;
+
+               Bogie();
        };
 
 private:
@@ -66,6 +72,7 @@ private:
        float height;
        std::vector<Axle> axles;
        std::vector<Bogie> bogies;
+       std::string object;
 
 public:
        VehicleType(unsigned);
@@ -78,6 +85,7 @@ public:
        float get_height() const { return height; }
        const std::vector<Axle> &get_axles() const { return axles; }
        const std::vector<Bogie> &get_bogies() const { return bogies; }
+       const std::string &get_object() const { return object; }
 };
 
 } // namespace Marklin