]> git.tdb.fi Git - r2c2.git/blobdiff - source/libr2c2/vehicletype.cpp
Reserve enough blocks for the entire train when placing
[r2c2.git] / source / libr2c2 / vehicletype.cpp
index 2da44cc992f340f7c73e7f44e104fc4285327078..9d929b328cbf6359d880715721cce898f16b0180 100644 (file)
@@ -1,4 +1,6 @@
 #include <msp/core/maputils.h>
+#include <msp/geometry/box.h>
+#include <msp/geometry/transformedshape.h>
 #include <msp/strings/format.h>
 #include "vehicletype.h"
 
@@ -8,7 +10,7 @@ using namespace Msp;
 namespace R2C2 {
 
 VehicleType::VehicleType(const ArticleNumber &an):
-       art_nr(an),
+       ObjectType(an),
        locomotive(false),
        swap_direction(false),
        length(0),
@@ -24,13 +26,20 @@ unsigned VehicleType::get_max_function() const
        return (--functions.end())->first;
 }
 
-const VehicleType::Axle &VehicleType::get_fixed_axle(unsigned i) const
+const VehicleType::Axle &VehicleType::get_axle(unsigned i) const
 {
        if(i>=axles.size())
-               throw out_of_range("VehicleType::get_fixed_axle");
+               throw out_of_range("VehicleType::get_axle");
        return axles[i];
 }
 
+const VehicleType::Axle &VehicleType::get_fixed_axle(unsigned i) const
+{
+       if(i>=fixed_axles.size())
+               throw out_of_range("VehicleType::get_fixed_axle");
+       return *fixed_axles[i];
+}
+
 const VehicleType::Bogie &VehicleType::get_bogie(unsigned i) const
 {
        if(i>=bogies.size())
@@ -44,7 +53,7 @@ const VehicleType::Axle &VehicleType::get_bogie_axle(unsigned i, unsigned j) con
                throw out_of_range("VehicleType::get_bogie_axle");
        if(j>=bogies[i].axles.size())
                throw out_of_range("VehicleType::get_bogie_axle");
-       return bogies[i].axles[j];
+       return *bogies[i].axles[j];
 }
 
 const VehicleType::Rod &VehicleType::get_rod(unsigned i) const
@@ -56,32 +65,23 @@ const VehicleType::Rod &VehicleType::get_rod(unsigned i) const
 
 float VehicleType::get_front_axle_offset() const
 {
-       float front = length/2;
        if(!axles.empty())
-               front = axles.front().position;
-       if(!bogies.empty())
-       {
-               const Bogie &bogie = bogies.front();
-               front = max(front, bogie.position+bogie.axles.front().position);
-       }
-       return front;
+               return axles.front().position;
+       return length/2;
 }
 
 float VehicleType::get_back_axle_offset() const
 {
-       float back = -length/2;
        if(!axles.empty())
-               back = axles.back().position;
-       if(!bogies.empty())
-       {
-               const Bogie &bogie = bogies.back();
-               back = min(back, bogie.position+bogie.axles.back().position);
-       }
-       return back;
+               return axles.back().position;
+       return -length/2;
 }
 
 
 VehicleType::Axle::Axle():
+       index(0),
+       bogie(0),
+       local_position(0),
        position(0),
        wheel_dia(0),
        powered(false)
@@ -105,7 +105,7 @@ VehicleType::Rod::Rod():
 
 
 VehicleType::Loader::Loader(VehicleType &vt):
-       DataFile::ObjectLoader<VehicleType>(vt)
+       DataFile::DerivedObjectLoader<VehicleType, ObjectType::Loader>(vt)
 {
        add("axle",       &Loader::axle);
        add("bogie",      &Loader::bogie);
@@ -113,7 +113,6 @@ VehicleType::Loader::Loader(VehicleType &vt):
        add("height",     &Loader::height);
        add("length",     &Loader::length);
        add("locomotive", &VehicleType::locomotive);
-       add("name",       &VehicleType::name);
        add("object",     &VehicleType::object);
        add("rod",        &Loader::rod);
        add("rotate_object", &VehicleType::rotate_object);
@@ -121,6 +120,31 @@ VehicleType::Loader::Loader(VehicleType &vt):
        add("width",      &Loader::width);
 }
 
+void VehicleType::Loader::finish()
+{
+       for(unsigned i=0; i<obj.bogies.size(); ++i)
+       {
+               obj.bogies[i].index = i;
+               for(unsigned j=0; j<obj.bogies[i].axles.size(); ++j)
+               {
+                       obj.bogies[i].axles[j] = &obj.axles[obj.bogies[i].first_axle+j];
+                       obj.bogies[i].axles[j]->bogie = &obj.bogies[i];
+                       obj.bogies[i].axles[j]->position += obj.bogies[i].position;
+               }
+       }
+
+       for(unsigned i=0; i<obj.axles.size(); ++i)
+       {
+               obj.axles[i].index = i;
+               if(!obj.axles[i].bogie)
+                       obj.fixed_axles.push_back(&obj.axles[i]);
+       }
+
+       obj.shape = new Geometry::TransformedShape<float, 3>(
+               Geometry::Box<float>(obj.length, obj.width, obj.height),
+               Transform::translation(Vector(0, 0, obj.height/2)));
+}
+
 void VehicleType::Loader::axle()
 {
        Axle axl;
@@ -131,7 +155,8 @@ void VehicleType::Loader::axle()
 void VehicleType::Loader::bogie()
 {
        Bogie bog;
-       load_sub(bog);
+       Bogie::Loader ldr(obj, bog);
+       load_sub_with(ldr);
        obj.bogies.push_back(bog);
 }
 
@@ -178,7 +203,8 @@ VehicleType::Axle::Loader::Loader(Axle &a):
 
 void VehicleType::Axle::Loader::position(float p)
 {
-       obj.position = p/1000;
+       obj.local_position = p/1000;
+       obj.position = obj.local_position;
 }
 
 void VehicleType::Axle::Loader::wheel_diameter(float d)
@@ -187,8 +213,9 @@ void VehicleType::Axle::Loader::wheel_diameter(float d)
 }
 
 
-VehicleType::Bogie::Loader::Loader(Bogie &b):
-       DataFile::ObjectLoader<Bogie>(b)
+VehicleType::Bogie::Loader::Loader(VehicleType &t, Bogie &b):
+       DataFile::ObjectLoader<Bogie>(b),
+       parent(t)
 {
        add("axle",          &Loader::axle);
        add("object",        &Bogie::object);
@@ -200,7 +227,11 @@ void VehicleType::Bogie::Loader::axle()
 {
        Axle axl;
        load_sub(axl);
-       obj.axles.push_back(axl);
+       if(obj.axles.empty())
+               obj.first_axle = parent.axles.size();
+       parent.axles.push_back(axl);
+       // Actual pointers will be filled after everything is loaded
+       obj.axles.push_back(0);
 }
 
 void VehicleType::Bogie::Loader::position(float p)