#include "vehicle.h"
#include "vehicletype.h"
+using namespace std;
using namespace Msp;
namespace Marklin {
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);
+ }
}
}
#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
#define LIBMARKLIN3D_VEHICLETYPE_H_
#include <msp/gl/mesh.h>
+#include <msp/gl/object.h>
#include "libmarklin/vehicletype.h"
namespace Marklin {
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
type(t),
next(0),
prev(0),
- direction(0)
+ direction(0),
+ bogie_dirs(type.get_bogies().size())
{
layout.add_vehicle(*this);
}
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;
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();
TrackPosition track_pos;
Point position;
float direction;
+ std::vector<float> bogie_dirs;
public:
Vehicle(Layout &, const VehicleType &);
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 &);
{ }
+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)
{
add("bogie", &Loader::bogie);
add("height", &Loader::height);
add("length", &Loader::length);
+ add("object", &VehicleType::object);
add("name", &VehicleType::name);
add("width", &Loader::width);
}
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)
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()
float position;
float wheel_dia;
bool powered;
+
+ Axle();
};
struct Bogie
float position;
std::vector<Axle> axles;
+ std::string object;
+ bool rotate_object;
+
+ Bogie();
};
private:
float height;
std::vector<Axle> axles;
std::vector<Bogie> bogies;
+ std::string object;
public:
VehicleType(unsigned);
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