namespace R2C2 {
Axle3D::Axle3D(const Vehicle3D &v, unsigned a):
- VehiclePart3D(v, *v.get_type().get_fixed_axle_object(a)),
+ VehiclePart3D(v, *v.get_type().get_axle_object(a)),
bogie(0),
- axle(vehicle.get_vehicle().get_fixed_axle(a))
-{ }
-
-Axle3D::Axle3D(const Vehicle3D &v, unsigned b, unsigned a):
- VehiclePart3D(v, *v.get_type().get_bogie_axle_object(b, a)),
- bogie(&vehicle.get_vehicle().get_bogie(b)),
- axle(bogie->axles[a])
-{ }
+ axle(vehicle.get_vehicle().get_axle(a))
+{
+ if(axle.type->bogie)
+ bogie = &vehicle.get_vehicle().get_bogie(axle.type->bogie->index);
+}
void Axle3D::update_matrix()
{
matrix.rotate(bogie->direction, 0, 0, 1);
}
- matrix.translate(axle.type->position, 0, axle.type->wheel_dia/2);
+ matrix.translate(axle.type->local_position, 0, axle.type->wheel_dia/2);
matrix.rotate(axle.angle, 0, 1, 0);
}
public:
Axle3D(const Vehicle3D &, unsigned);
- Axle3D(const Vehicle3D &, unsigned, unsigned);
virtual void update_matrix();
};
vehicle(v),
type(layout.get_catalogue().get_vehicle(vehicle.get_type()))
{
- unsigned n_axles = vehicle.get_type().get_fixed_axles().size();
+ unsigned n_axles = vehicle.get_type().get_axles().size();
for(unsigned i=0; i<n_axles; ++i)
- if(type.get_fixed_axle_object(i))
+ if(type.get_axle_object(i))
children.push_back(new Axle3D(*this, i));
unsigned n_bogies = vehicle.get_type().get_bogies().size();
for(unsigned i=0; i<n_bogies; ++i)
if(type.get_bogie_object(i))
- {
children.push_back(new Bogie3D(*this, i));
- n_axles = vehicle.get_type().get_bogie(i).axles.size();
- for(unsigned j=0; j<n_axles; ++j)
- if(type.get_bogie_axle_object(i, j))
- children.push_back(new Axle3D(*this, i, j));
- }
-
unsigned n_rods = vehicle.get_type().get_rods().size();
for(unsigned i=0; i<n_rods; ++i)
if(type.get_rod_object(i))
VehicleType3D::VehicleType3D(Catalogue3D &c, const VehicleType &t):
catalogue(c),
type(t),
- body_object(0),
- axle_objects(1)
+ body_object(0)
{
body_object = get_object(type.get_object());
- const vector<VehicleType::Axle> &axles = type.get_fixed_axles();
+ const vector<VehicleType::Axle> &axles = type.get_axles();
for(vector<VehicleType::Axle>::const_iterator i=axles.begin(); i!=axles.end(); ++i)
- axle_objects[0].push_back(get_object(i->object));
+ axle_objects.push_back(get_object(i->object));
const vector<VehicleType::Bogie> &bogies = type.get_bogies();
for(vector<VehicleType::Bogie>::const_iterator i=bogies.begin(); i!=bogies.end(); ++i)
- {
bogie_objects.push_back(get_object(i->object));
- axle_objects.push_back(vector<GL::Object *>());
- for(vector<VehicleType::Axle>::const_iterator j=i->axles.begin(); j!=i->axles.end(); ++j)
- axle_objects.back().push_back(get_object(j->object));
- }
const vector<VehicleType::Rod> &rods = type.get_rods();
for(vector<VehicleType::Rod>::const_iterator i=rods.begin(); i!=rods.end(); ++i)
delete i->second;
}
-const GL::Object *VehicleType3D::get_fixed_axle_object(unsigned i) const
+const GL::Object *VehicleType3D::get_axle_object(unsigned i) const
{
- if(i>=axle_objects[0].size())
+ if(i>=axle_objects.size())
throw out_of_range("VehicleType3D::get_fixed_axle_object");
- return axle_objects[0][i];
+ return axle_objects[i];
}
const GL::Object *VehicleType3D::get_bogie_object(unsigned i) const
return bogie_objects[i];
}
-const GL::Object *VehicleType3D::get_bogie_axle_object(unsigned i, unsigned j) const
-{
- if(i>=bogie_objects.size())
- throw out_of_range("VehicleType3D::get_bogie_axle_object");
- if(j>=axle_objects[i+1].size())
- throw out_of_range("VehicleType3D::get_bogie_axle_object");
- return axle_objects[i+1][j];
-}
-
const GL::Object *VehicleType3D::get_rod_object(unsigned i) const
{
if(i>=rod_objects.size())
std::map<std::string, Msp::GL::Object *> objects;
Msp::GL::Object *body_object;
std::vector<Msp::GL::Object *> bogie_objects;
- std::vector<std::vector<Msp::GL::Object *> > axle_objects;
+ std::vector<Msp::GL::Object *> axle_objects;
std::vector<Msp::GL::Object *> rod_objects;
public:
~VehicleType3D();
const Msp::GL::Object *get_body_object() const { return body_object; }
- const Msp::GL::Object *get_fixed_axle_object(unsigned) const;
+ 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;
const Msp::GL::Object *get_rod_object(unsigned) const;
private:
Msp::GL::Object *get_object(const std::string &);
front_sensor(0),
back_sensor(0)
{
- axles.assign(type.get_fixed_axles().begin(), type.get_fixed_axles().end());
+ axles.assign(type.get_axles().begin(), type.get_axles().end());
+ for(vector<Axle>::iterator i=axles.begin(); i!=axles.end(); ++i)
+ if(!i->type->bogie)
+ fixed_axles.push_back(&*i);
bogies.assign(type.get_bogies().begin(), type.get_bogies().end());
rods.assign(type.get_rods().begin(), type.get_rods().end());
+ for(vector<Bogie>::iterator i=bogies.begin(); i!=bogies.end(); ++i)
+ for(unsigned j=0; j<i->axles.size(); ++j)
+ i->axles[j] = &axles[i->type->first_axle+j];
layout.add(*this);
}
propagate_position();
}
-const Vehicle::Axle &Vehicle::get_fixed_axle(unsigned i) const
+const Vehicle::Axle &Vehicle::get_axle(unsigned i) const
{
if(i>=axles.size())
- throw out_of_range("Vehicle::get_fixed_axle");
+ throw out_of_range("Vehicle::get_axle");
return axles[i];
}
+const Vehicle::Axle &Vehicle::get_fixed_axle(unsigned i) const
+{
+ if(i>=fixed_axles.size())
+ throw out_of_range("Vehicle::get_fixed_axle");
+ return *fixed_axles[i];
+}
+
const Vehicle::Bogie &Vehicle::get_bogie(unsigned i) const
{
if(i>=bogies.size())
throw out_of_range("Vehicle::get_bogie_axle");
if(j>=bogies[i].axles.size())
throw out_of_range("Vehicle::get_bogie_axle");
- return bogies[i].axles[j];
+ return *bogies[i].axles[j];
}
const Vehicle::Rod &Vehicle::get_rod(unsigned i) const
{
OrientedPoint p;
- if(axles.size()>=2)
+ if(fixed_axles.size()>=2)
{
- float wheelbase = axles.front().type->position-axles.back().type->position;
- p = get_point(track, wheelbase, -axles.back().type->position/wheelbase);
+ float wheelbase = fixed_axles.front()->type->position-fixed_axles.back()->type->position;
+ p = get_point(track, wheelbase, -fixed_axles.back()->type->position/wheelbase);
}
else if(bogies.size()>=2)
{
float bogie_spacing = bogies.front().type->position-bogies.back().type->position;
adjust_for_distance(front, back, bogie_spacing);
- const vector<Axle> &front_axles = bogies.front().axles;
- float wheelbase = front_axles.front().type->position-front_axles.back().type->position;
- OrientedPoint front_point = get_point(front, wheelbase, -front_axles.back().type->position/wheelbase);
+ const vector<Axle *> &front_axles = bogies.front().axles;
+ float wheelbase = front_axles.front()->type->position-front_axles.back()->type->position;
+ OrientedPoint front_point = get_point(front, wheelbase, -front_axles.back()->type->position/wheelbase);
- const vector<Axle> &back_axles = bogies.back().axles;
- wheelbase = back_axles.front().type->position-back_axles.back().type->position;
- OrientedPoint back_point = get_point(back, wheelbase, -back_axles.back().type->position/wheelbase);
+ const vector<Axle *> &back_axles = bogies.back().axles;
+ wheelbase = back_axles.front()->type->position-back_axles.back()->type->position;
+ OrientedPoint back_point = get_point(back, wheelbase, -back_axles.back()->type->position/wheelbase);
p = get_point(front_point.position, back_point.position, -bogies.back().type->position/bogie_spacing);
{
for(vector<Axle>::iterator i=axles.begin(); i!=axles.end(); ++i)
i->angle += Angle::from_radians(d*2/i->type->wheel_dia);
- for(vector<Bogie>::iterator i=bogies.begin(); i!=bogies.end(); ++i)
- for(vector<Axle>::iterator j=i->axles.begin(); j!=i->axles.end(); ++j)
- j->angle += Angle::from_radians(d*2/j->type->wheel_dia);
update_rods();
}
Vehicle::Bogie::Bogie(const VehicleType::Bogie &t):
- type(&t)
-{
- for(VehicleType::AxleArray::const_iterator i=type->axles.begin(); i!=type->axles.end(); ++i)
- axles.push_back(*i);
-}
+ type(&t),
+ axles(t.axles.size())
+{ }
Vehicle::Rod::Rod(const VehicleType::Rod &t):
{
const VehicleType::Bogie *type;
Angle direction;
- std::vector<Axle> axles;
+ std::vector<Axle *> axles;
Bogie(const VehicleType::Bogie &);
};
Vehicle *prev;
TrackOffsetIter track;
std::vector<Axle> axles;
+ std::vector<Axle *> fixed_axles;
std::vector<Bogie> bogies;
std::vector<Rod> rods;
unsigned front_sensor;
Track *get_track() const { return track.track(); }
unsigned get_entry() const { return track.entry(); }
float get_offset() const { return track.offset(); }
+ const Axle &get_axle(unsigned) const;
const Axle &get_fixed_axle(unsigned) const;
const Bogie &get_bogie(unsigned) const;
const Axle &get_bogie_axle(unsigned, unsigned) 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())
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
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)
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::bogie()
{
Bogie bog;
- load_sub(bog);
+ Bogie::Loader ldr(obj, bog);
+ load_sub_with(ldr);
obj.bogies.push_back(bog);
}
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)
}
-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);
{
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)
void width(float);
};
+ struct Bogie;
+
struct Axle
{
class Loader: public Msp::DataFile::ObjectLoader<Axle>
void wheel_diameter(float);
};
+ unsigned index;
+ Bogie *bogie;
+ float local_position;
float position;
float wheel_dia;
bool powered;
Axle();
};
- typedef std::vector<Axle> AxleArray;
-
struct Bogie
{
class Loader: public Msp::DataFile::ObjectLoader<Bogie>
{
+ private:
+ VehicleType &parent;
+
public:
- Loader(Bogie &);
+ Loader(VehicleType &, Bogie &);
private:
void axle();
void position(float);
};
+ unsigned index;
float position;
- AxleArray axles;
+ unsigned first_axle;
+ std::vector<Axle *> axles;
std::string object;
bool rotate_object;
Bogie();
};
- typedef std::vector<Bogie> BogieArray;
-
struct Rod
{
enum Anchor
Rod();
};
+ typedef std::vector<Axle> AxleArray;
+ typedef std::vector<Bogie> BogieArray;
typedef std::vector<Rod> RodArray;
-
typedef std::map<unsigned, std::string> FunctionMap;
private:
float width;
float height;
AxleArray axles;
+ std::vector<Axle *> fixed_axles;
BogieArray bogies;
RodArray rods;
std::string object;
float get_length() const { return length; }
float get_width() const { return width; }
float get_height() const { return height; }
- const AxleArray &get_fixed_axles() const { return axles; }
+ const AxleArray &get_axles() const { return axles; }
+ const Axle &get_axle(unsigned) const;
const Axle &get_fixed_axle(unsigned) const;
const BogieArray &get_bogies() const { return bogies; }
const Bogie &get_bogie(unsigned) const;