--- /dev/null
+#include "object.h"
+
+using namespace Msp;
+
+namespace R2C2 {
+
+Object3D::Object3D(Object &o):
+ object(o)
+{
+ object.signal_moved.connect(sigc::mem_fun(this, &Object3D::moved));
+}
+
+void Object3D::moved()
+{
+ matrix = GL::Matrix::translation(object.get_position());
+ matrix.rotate(object.get_rotation(), 0, 0, 1);
+ matrix.rotate(object.get_tilt(), 0, -1, 0);
+}
+
+} // namespace R2C2
#ifndef R2C2_3D_OBJECT_H_
#define R2C2_3D_OBJECT_H_
+#include <sigc++/trackable.h>
+#include <msp/gl/matrix.h>
#include "libr2c2/geometry.h"
+#include "libr2c2/object.h"
namespace R2C2 {
-class Object3D
+class Object3D: public sigc::trackable
{
protected:
- Object3D() { }
+ Object &object;
+ Msp::GL::Matrix matrix;
+
+ Object3D(Object &);
public:
virtual ~Object3D() { }
+ const Msp::GL::Matrix &get_matrix() const { return matrix; }
virtual Vector get_node() const = 0;
virtual bool is_visible() const = 0;
+protected:
+ virtual void moved();
};
} // namespace R2C2
return;
GL::MatrixStack::Push push_mtx(renderer.matrix_stack());
- GL::Matrix matrix = track.create_matrix();
- matrix.translate(0, 0, z_offs);
- renderer.matrix_stack() *= matrix;
+ renderer.matrix_stack() *= track.Object3D::get_matrix();
+ renderer.matrix_stack() *= GL::Matrix::translation(0, 0, z_offs);
glColor4f(color.r, color.g, color.b, color.a);
for(unsigned i=0; mask; ++i, mask>>=1)
namespace R2C2 {
Signal3D::Signal3D(Layout3D &l, Signal &s):
+ Object3D(s),
GL::ObjectInstance(l.get_catalogue().get_signal(s.get_type()).get_object()),
layout(l),
signal(s)
layout.get_scene().remove(*this);
}
+Vector Signal3D::get_node() const
+{
+ return matrix*Vector(0, -0.035, 0.13);
+}
+
void Signal3D::setup_render(GL::Renderer &renderer, const GL::Tag &) const
{
- renderer.matrix_stack() *= GL::Matrix::translation(signal.get_position());
- renderer.matrix_stack() *= GL::Matrix::rotation(signal.get_rotation(), 0, 0, 1);
+ renderer.matrix_stack() *= matrix;
// XXX Use track gauge, configure signal side
renderer.matrix_stack() *= GL::Matrix::translation(0, -0.035, 0);
}
#include <msp/gl/objectinstance.h>
#include "libr2c2/signal.h"
+#include "object.h"
namespace R2C2 {
class Layout3D;
-class Signal3D: public Msp::GL::ObjectInstance
+class Signal3D: public Object3D, public Msp::GL::ObjectInstance
{
private:
Layout3D &layout;
Signal3D(Layout3D &, Signal &);
~Signal3D();
+ virtual Vector get_node() const;
+ virtual bool is_visible() const { return true; }
+
Signal &get_signal() const { return signal; }
virtual void setup_render(Msp::GL::Renderer &, const Msp::GL::Tag &) const;
};
namespace R2C2 {
Track3D::Track3D(Layout3D &l, Track &t):
+ Object3D(t),
GL::ObjectInstance(l.get_catalogue().get_track(t.get_type()).get_object()),
layout(l),
track(t),
const Vector &minp = bbox.get_minimum_point();
const Vector &maxp = bbox.get_maximum_point();
- return track.get_position()+rotated_vector((minp+maxp)/2.0f, track.get_rotation())+Vector(0, 0, 0.02);
-}
-
-GL::Matrix Track3D::create_matrix() const
-{
- GL::Matrix matrix;
- matrix.translate(track.get_position());
- matrix.rotate(track.get_rotation(), 0, 0, 1);
- matrix.rotate(track.get_tilt(), 0, -1, 0);
-
- return matrix;
+ return matrix*((minp+maxp)/2.0f+Vector(0, 0, 0.02));
}
void Track3D::setup_render(Msp::GL::Renderer &renderer, const GL::Tag &) const
{
- renderer.matrix_stack() *= create_matrix();
+ renderer.matrix_stack() *= matrix;
}
void Track3D::link_changed(unsigned i, Track *trk)
class Path3D;
class TrackType3D;
-class Track3D: public Object3D, public Msp::GL::ObjectInstance, public sigc::trackable
+class Track3D: public Object3D, public Msp::GL::ObjectInstance
{
private:
Layout3D &layout;
virtual Vector get_node() const;
virtual bool is_visible() const { return true; }
- Msp::GL::Matrix create_matrix() const;
virtual void setup_render(Msp::GL::Renderer &, const Msp::GL::Tag &) const;
private:
void link_changed(unsigned, Track *);
namespace R2C2 {
Vehicle3D::Vehicle3D(Layout3D &l, Vehicle &v):
+ Object3D(v),
GL::ObjectInstance(*l.get_catalogue().get_vehicle(v.get_type()).get_body_object()),
layout(l),
vehicle(v),
void Vehicle3D::setup_render(GL::Renderer &renderer, const GL::Tag &) const
{
- GL::Matrix matrix;
- matrix.translate(vehicle.get_position());
- Angle rot = vehicle.get_rotation();
- if(vehicle.get_type().get_rotate_object())
- rot += Angle::half_turn();
- matrix.rotate(rot, 0, 0, 1);
renderer.matrix_stack() *= matrix;
+ if(vehicle.get_type().get_rotate_object())
+ renderer.matrix_stack() *= GL::Matrix::rotation(Angle::half_turn(), 0, 0, 1);
}
} // namespace R2C2
class Object
{
+public:
+ sigc::signal<void> signal_moved;
+
protected:
Layout &layout;
Vector position;
position = p;
update_location();
+ signal_moved.emit();
}
void Signal::update_location()
rotation = r;
update_location();
+ signal_moved.emit();
}
unsigned Signal::get_n_snap_nodes() const
void Track::set_position(const Vector &p)
{
position = p;
+ signal_moved.emit();
propagate_slope();
}
void Track::set_rotation(const Angle &r)
{
rotation = wrap_positive(r);
+ signal_moved.emit();
}
void Track::set_tilt(const Angle &t)
tilt = t;
slope = tan(tilt)*type.get_path_length(0);
+ signal_moved.emit();
propagate_slope();
}
position.z = epp.z-slope;
}
}
+
+ signal_moved.emit();
}
void Track::set_turnout_id(unsigned i)
void Track::Loader::position(float x, float y, float z)
{
- obj.position = Vector(x, y, z);
+ obj.set_position(Vector(x, y, z));
}
void Track::Loader::rotation(float r)
{
- obj.rotation = Angle::from_radians(r);
+ obj.set_rotation(Angle::from_radians(r));
}
void Track::Loader::sensor_id(unsigned id)
void Track::Loader::slope(float s)
{
- tilt(atan(s/obj.type.get_path_length(0)));
+ obj.set_tilt(Geometry::atan(s/obj.type.get_path_length(0)));
}
void Track::Loader::tilt(float t)
{
- if(obj.links.size()!=2)
- return;
-
- obj.tilt = Angle::from_radians(t);
- obj.slope = tan(t)*obj.type.get_path_length(0);
+ obj.set_tilt(Angle::from_radians(t));
}
void Track::Loader::turnout_id(unsigned id)
position = tp.pos;
position.z += layout.get_catalogue().get_rail_elevation();
rotation = tp.dir;
+ signal_moved.emit();
}
void Vehicle::update_position_from(const Vehicle &veh)