From 2910db1364914c0ab98a0f80250cc39137821577 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Mon, 6 May 2013 20:23:15 +0300 Subject: [PATCH] Add a common base class for tangible objects --- source/3d/axle.cpp | 2 +- source/3d/bogie.cpp | 2 +- source/3d/rod.cpp | 2 +- source/3d/signal.cpp | 2 +- source/3d/vehicle.cpp | 6 +-- source/engineer/trainview.cpp | 2 +- source/libr2c2/layout.cpp | 30 ++++++++++-- source/libr2c2/layout.h | 8 ++++ source/libr2c2/object.h | 35 ++++++++++++++ source/libr2c2/objecttype.cpp | 14 ++++++ source/libr2c2/objecttype.h | 35 ++++++++++++++ source/libr2c2/signal.cpp | 54 ++++++++++++++------- source/libr2c2/signal.h | 24 +++++----- source/libr2c2/signaltype.cpp | 6 +-- source/libr2c2/signaltype.h | 9 ++-- source/libr2c2/track.cpp | 86 +++++++++++++++++++--------------- source/libr2c2/track.h | 21 ++++----- source/libr2c2/tracktype.cpp | 5 +- source/libr2c2/tracktype.h | 9 ++-- source/libr2c2/vehicle.cpp | 13 +++-- source/libr2c2/vehicle.h | 17 ++++--- source/libr2c2/vehicletype.cpp | 5 +- source/libr2c2/vehicletype.h | 10 ++-- 23 files changed, 269 insertions(+), 128 deletions(-) create mode 100644 source/libr2c2/object.h create mode 100644 source/libr2c2/objecttype.cpp create mode 100644 source/libr2c2/objecttype.h diff --git a/source/3d/axle.cpp b/source/3d/axle.cpp index 6b0e1f5..c9f7a70 100644 --- a/source/3d/axle.cpp +++ b/source/3d/axle.cpp @@ -36,7 +36,7 @@ void Axle3D::setup_render(GL::Renderer &renderer, const GL::Tag &) const const Vector &pos = vehicle.get_position(); matrix.translate(pos.x, pos.y, pos.z); - matrix.rotate(vehicle.get_direction(), 0, 0, 1); + matrix.rotate(vehicle.get_rotation(), 0, 0, 1); if(bogie) { diff --git a/source/3d/bogie.cpp b/source/3d/bogie.cpp index a36fc9b..8e99ceb 100644 --- a/source/3d/bogie.cpp +++ b/source/3d/bogie.cpp @@ -28,7 +28,7 @@ void Bogie3D::setup_render(Msp::GL::Renderer &renderer, const GL::Tag &) const const Vector &pos = vehicle.get_position(); matrix.translate(pos.x, pos.y, pos.z); - matrix.rotate(vehicle.get_direction(), 0, 0, 1); + matrix.rotate(vehicle.get_rotation(), 0, 0, 1); matrix.translate(bogie.type->position, 0, 0); float dir = bogie.direction; diff --git a/source/3d/rod.cpp b/source/3d/rod.cpp index c59dd83..10b5f46 100644 --- a/source/3d/rod.cpp +++ b/source/3d/rod.cpp @@ -27,7 +27,7 @@ void Rod3D::setup_render(GL::Renderer &renderer, const GL::Tag &) const GL::Matrix matrix; const Vector &pos = vehicle.get_position(); matrix.translate(pos.x, pos.y, pos.z); - matrix.rotate(vehicle.get_direction(), 0, 0, 1); + matrix.rotate(vehicle.get_rotation(), 0, 0, 1); matrix.translate(rod.position.x, rod.position.y, rod.position.z); if(rod.type->mirror_object) diff --git a/source/3d/signal.cpp b/source/3d/signal.cpp index 8601bcc..0942bce 100644 --- a/source/3d/signal.cpp +++ b/source/3d/signal.cpp @@ -27,7 +27,7 @@ void Signal3D::setup_render(GL::Renderer &renderer, const GL::Tag &) const { const Vector &pos = signal.get_position(); renderer.matrix_stack() *= GL::Matrix::translation(pos.x, pos.y, pos.z); - renderer.matrix_stack() *= GL::Matrix::rotation(signal.get_direction(), 0, 0, 1); + renderer.matrix_stack() *= GL::Matrix::rotation(signal.get_rotation(), 0, 0, 1); // XXX Use track gauge, configure signal side renderer.matrix_stack() *= GL::Matrix::translation(0, -0.035, 0); } diff --git a/source/3d/vehicle.cpp b/source/3d/vehicle.cpp index 0bd57e9..d1e5657 100644 --- a/source/3d/vehicle.cpp +++ b/source/3d/vehicle.cpp @@ -95,10 +95,10 @@ void Vehicle3D::setup_render(GL::Renderer &renderer, const GL::Tag &) const GL::Matrix matrix; const Vector &pos = vehicle.get_position(); matrix.translate(pos.x, pos.y, pos.z); - float dir = vehicle.get_direction(); + float rot = vehicle.get_rotation(); if(vehicle.get_type().get_rotate_object()) - dir += M_PI; - matrix.rotate(dir, 0, 0, 1); + rot += M_PI; + matrix.rotate(rot, 0, 0, 1); renderer.matrix_stack() *= matrix; } diff --git a/source/engineer/trainview.cpp b/source/engineer/trainview.cpp index 1ab236f..79f9c94 100644 --- a/source/engineer/trainview.cpp +++ b/source/engineer/trainview.cpp @@ -86,7 +86,7 @@ void TrainView::prepare() { const Vehicle &veh = train.get_vehicle(0); const Vector &pos = veh.get_position(); - float angle = veh.get_direction(); + float angle = veh.get_rotation(); if(!forward) angle += M_PI; float c = cos(angle); diff --git a/source/libr2c2/layout.cpp b/source/libr2c2/layout.cpp index a4c7309..4679fd9 100644 --- a/source/libr2c2/layout.cpp +++ b/source/libr2c2/layout.cpp @@ -74,11 +74,7 @@ void Layout::add_track(Track &t) Track *Layout::pick_track(const Vector &start, const Vector &ray) { - for(set::iterator i=tracks.begin(); i!=tracks.end(); ++i) - if((*i)->collide_ray(start, ray)) - return *i; - - return 0; + return pick(tracks, start, ray); } void Layout::remove_track(Track &t) @@ -111,12 +107,36 @@ void Layout::add_signal(Signal &s) signal_signal_added.emit(s); } +Signal *Layout::pick_signal(const Vector &start, const Vector &ray) +{ + return pick(signals, start, ray); +} + void Layout::remove_signal(Signal &s) { if(signals.erase(&s)) signal_signal_removed.emit(s); } +Object *Layout::pick_object(const Vector &start, const Vector &ray) +{ + if(Object *obj = pick_track(start, ray)) + return obj; + else if((obj = pick_signal(start, ray))) + return obj; + return 0; +} + +template +T *Layout::pick(const set &objs, const Vector &start, const Vector &ray) +{ + for(typename set::const_iterator i=objs.begin(); i!=objs.end(); ++i) + if((*i)->collide_ray(start, ray)) + return *i; + + return 0; +} + void Layout::add_block(Block &b) { blocks.insert(&b); diff --git a/source/libr2c2/layout.h b/source/libr2c2/layout.h index 73c74b8..c327955 100644 --- a/source/libr2c2/layout.h +++ b/source/libr2c2/layout.h @@ -93,8 +93,16 @@ public: void add_signal(Signal &); const std::set &get_signals() const { return signals; } + Signal *pick_signal(const Vector &, const Vector &); void remove_signal(Signal &); + Object *pick_object(const Vector &, const Vector &); + +private: + template + static T *pick(const std::set &, const Vector &, const Vector &); + +public: void add_block(Block &); Block &get_block(unsigned) const; const std::set &get_blocks() const { return blocks; } diff --git a/source/libr2c2/object.h b/source/libr2c2/object.h new file mode 100644 index 0000000..206ec33 --- /dev/null +++ b/source/libr2c2/object.h @@ -0,0 +1,35 @@ +#ifndef LIBR2C2_OBJECT_H_ +#define LIBR2C2_OBJECT_H_ + +#include "geometry.h" +#include "objecttype.h" + +namespace R2C2 { + +class Layout; + +class Object +{ +protected: + Layout &layout; + Vector position; + float rotation; + + Object(Layout &l): layout(l) { } +public: + virtual ~Object() { } + + virtual Object *clone(Layout * = 0) const = 0; + virtual const ObjectType &get_type() const = 0; + Layout &get_layout() const { return layout; } + virtual void set_position(const Vector &) = 0; + virtual void set_rotation(float) = 0; + const Vector &get_position() const { return position; } + float get_rotation() const { return rotation; } + virtual Object *get_parent() const { return 0; } + virtual bool collide_ray(const Vector &, const Vector &) const = 0; +}; + +} // namespace R2C2 + +#endif diff --git a/source/libr2c2/objecttype.cpp b/source/libr2c2/objecttype.cpp new file mode 100644 index 0000000..10d9c88 --- /dev/null +++ b/source/libr2c2/objecttype.cpp @@ -0,0 +1,14 @@ +#include "objecttype.h" + +using namespace Msp; + +namespace R2C2 { + +ObjectType::Loader::Loader(ObjectType &ot): + DataFile::ObjectLoader(ot) +{ + add("description", &ObjectType::description); + add("name", &ObjectType::name); +} + +} // namespace R2C2 diff --git a/source/libr2c2/objecttype.h b/source/libr2c2/objecttype.h new file mode 100644 index 0000000..0cca264 --- /dev/null +++ b/source/libr2c2/objecttype.h @@ -0,0 +1,35 @@ +#ifndef LIBR2C2_OBJECTTYPE_H_ +#define LIBR2C2_OBJECTTYPE_H_ + +#include +#include +#include "articlenumber.h" + +namespace R2C2 { + +class ObjectType +{ +public: + class Loader: public Msp::DataFile::ObjectLoader + { + public: + Loader(ObjectType &); + }; + +protected: + ArticleNumber art_nr; + std::string name; + std::string description; + + ObjectType(const ArticleNumber &a): art_nr(a) { } +public: + virtual ~ObjectType() { } + + const ArticleNumber &get_article_number() const { return art_nr; } + const std::string &get_name() const { return name; } + const std::string &get_description() const { return description; } +}; + +} // namespace R2C2 + +#endif diff --git a/source/libr2c2/signal.cpp b/source/libr2c2/signal.cpp index a8b0be0..72cf235 100644 --- a/source/libr2c2/signal.cpp +++ b/source/libr2c2/signal.cpp @@ -13,7 +13,7 @@ using namespace Msp; namespace R2C2 { Signal::Signal(Layout &l, const SignalType &t): - layout(l), + Object(l), type(t), address(0), track(0), @@ -33,6 +33,14 @@ Signal::~Signal() layout.remove_signal(*this); } +Signal *Signal::clone(Layout *to_layout) const +{ + Signal *sig = new Signal((to_layout ? *to_layout : layout), type); + sig->set_position(position); + sig->set_rotation(rotation); + return sig; +} + void Signal::set_address(unsigned a) { address = a; @@ -53,7 +61,7 @@ void Signal::set_position(const Vector &p) if(dget_type().get_endpoints().size(); for(unsigned j=0; jget_endpoint_direction(j)-direction; + float a = track->get_endpoint_direction(j)-rotation; while(a<-M_PI/2) a += M_PI*2; while(a>M_PI*3/2) @@ -82,23 +90,37 @@ void Signal::normalize_location() } } -void Signal::set_direction(float d) +void Signal::set_rotation(float r) { - float a = direction-d; + float a = rotation-r; while(a>M_PI*3/2) a -= M_PI*2; while(a<-M_PI/2) a += M_PI*2; if(a>=M_PI/2) { - direction += M_PI; - if(direction>M_PI*2) - direction -= M_PI*2; + rotation += M_PI; + if(rotation>M_PI*2) + rotation -= M_PI*2; } normalize_location(); } +bool Signal::collide_ray(const Vector &start, const Vector &ray) const +{ + // XXX Totally hardcoded stuff, should be replaced with a geometry system + Vector center = position; + center.x += sin(rotation)*0.035; + center.y -= cos(rotation)*0.035; + Vector d(center.x-start.x, center.y-start.y); + float x = (d.x*ray.x+d.y*ray.y)/(ray.x*ray.x+ray.y*ray.y); + Vector nearest(start.x+ray.x*x-center.x, start.y+ray.y*x-center.y, start.z+ray.z*x-center.z); + if(nearest.z<0|| nearest.z>0.12) + return false; + return nearest.x*nearest.x+nearest.y*nearest.y<0.0001; +} + void Signal::tick(const Time::TimeDelta &) { if(check_allocated_blocks) @@ -176,7 +198,7 @@ void Signal::reset() void Signal::save(list &st) const { st.push_back((DataFile::Statement("position"), position.x, position.y, position.z)); - st.push_back((DataFile::Statement("direction"), direction)); + st.push_back((DataFile::Statement("rotation"), rotation)); if(address) st.push_back((DataFile::Statement("address"), address)); } @@ -185,9 +207,9 @@ void Signal::save(list &st) const Signal::Loader::Loader(Signal &s): DataFile::ObjectLoader(s) { - add("address", &Loader::address); - add("direction", &Loader::direction); - add("position", &Loader::position); + add("address", &Loader::address); + add("position", &Loader::position); + add("rotation", &Loader::rotation); } void Signal::Loader::address(unsigned a) @@ -195,14 +217,14 @@ void Signal::Loader::address(unsigned a) obj.set_address(a); } -void Signal::Loader::direction(float d) +void Signal::Loader::position(float x, float y, float z) { - obj.set_direction(d); + obj.set_position(Vector(x, y, z)); } -void Signal::Loader::position(float x, float y, float z) +void Signal::Loader::rotation(float d) { - obj.set_position(Vector(x, y, z)); + obj.set_rotation(d); } } // namespace R2C2 diff --git a/source/libr2c2/signal.h b/source/libr2c2/signal.h index dcaa17a..92e1977 100644 --- a/source/libr2c2/signal.h +++ b/source/libr2c2/signal.h @@ -4,16 +4,17 @@ #include #include #include "geometry.h" +#include "object.h" +#include "signaltype.h" +#include "track.h" namespace R2C2 { class Block; class Layout; -class SignalType; -class Track; class Train; -class Signal +class Signal: public Object { public: class Loader: public Msp::DataFile::ObjectLoader @@ -23,16 +24,13 @@ public: private: void address(unsigned); - void direction(float); void position(float, float, float); + void rotation(float); }; private: - Layout &layout; const SignalType &type; unsigned address; - Vector position; - float direction; Track *track; Block *block; unsigned entry; @@ -45,16 +43,18 @@ public: Signal(Layout &, const SignalType &); ~Signal(); - const SignalType &get_type() const { return type; } + virtual Signal *clone(Layout * = 0) const; + virtual const SignalType &get_type() const { return type; } void set_address(unsigned); - void set_position(const Vector &); - void set_direction(float); + virtual void set_position(const Vector &); + virtual void set_rotation(float); private: void normalize_location(); public: - const Vector &get_position() const { return position; } - float get_direction() const { return direction; } + virtual Track *get_parent() const { return track; } + + virtual bool collide_ray(const Vector &, const Vector &) const; void tick(const Msp::Time::TimeDelta &); diff --git a/source/libr2c2/signaltype.cpp b/source/libr2c2/signaltype.cpp index 9fb25e9..d3f48d9 100644 --- a/source/libr2c2/signaltype.cpp +++ b/source/libr2c2/signaltype.cpp @@ -1,19 +1,19 @@ #include "signaltype.h" using namespace std; +using namespace Msp; namespace R2C2 { SignalType::SignalType(const ArticleNumber &an): - art_nr(an) + ObjectType(an) { } SignalType::Loader::Loader(SignalType &st): - ObjectLoader(st) + DataFile::DerivedObjectLoader(st) { - add("description", &SignalType::description); add("indication", &Loader::indication); add("object", &SignalType::object); } diff --git a/source/libr2c2/signaltype.h b/source/libr2c2/signaltype.h index 4499d7e..97de833 100644 --- a/source/libr2c2/signaltype.h +++ b/source/libr2c2/signaltype.h @@ -2,11 +2,11 @@ #define LIBR2C2_SIGNALTYPE_H_ #include -#include "articlenumber.h" +#include "objecttype.h" namespace R2C2 { -class SignalType +class SignalType: public ObjectType { public: struct Indication @@ -22,7 +22,7 @@ public: unsigned free_blocks; }; - class Loader: public Msp::DataFile::ObjectLoader + class Loader: public Msp::DataFile::DerivedObjectLoader { public: Loader(SignalType &); @@ -33,15 +33,12 @@ public: typedef std::list IndicationList; private: - ArticleNumber art_nr; - std::string description; IndicationList indications; std::string object; public: SignalType(const ArticleNumber &); - const ArticleNumber &get_article_number() const { return art_nr; } const IndicationList &get_indications() const { return indications; } const std::string &get_object() const { return object; } }; diff --git a/source/libr2c2/track.cpp b/source/libr2c2/track.cpp index d4e9d12..b679af7 100644 --- a/source/libr2c2/track.cpp +++ b/source/libr2c2/track.cpp @@ -12,10 +12,9 @@ using namespace Msp; namespace R2C2 { Track::Track(Layout &l, const TrackType &t): - layout(l), + Object(l), type(t), block(0), - rot(0), slope(0), flex(false), turnout_id(0), @@ -41,6 +40,14 @@ Track::~Track() layout.remove_track(*this); } +Track *Track::clone(Layout *to_layout) const +{ + Track *track = new Track((to_layout ? *to_layout : layout), type); + track->set_position(position); + track->set_rotation(rotation); + return track; +} + void Track::set_block(Block *b) { if(b && !b->has_track(*this)) @@ -61,16 +68,16 @@ Block &Track::get_block() const void Track::set_position(const Vector &p) { - pos = p; + position = p; } void Track::set_rotation(float r) { - rot = r; - while(rot<0) - rot += M_PI*2; - while(rot>M_PI*2) - rot -= M_PI*2; + rotation = r; + while(rotation<0) + rotation += M_PI*2; + while(rotation>M_PI*2) + rotation -= M_PI*2; } void Track::set_slope(float s) @@ -95,8 +102,8 @@ void Track::check_slope() { Vector epp0 = links[0]->get_endpoint_position(links[0]->get_endpoint_by_link(*this)); Vector epp1 = links[1]->get_endpoint_position(links[1]->get_endpoint_by_link(*this)); - pos.z = epp0.z; - slope = epp1.z-pos.z; + position.z = epp0.z; + slope = epp1.z-position.z; } else { @@ -104,12 +111,12 @@ void Track::check_slope() if(links[0]) { Vector epp = links[0]->get_endpoint_position(links[0]->get_endpoint_by_link(*this)); - pos.z = epp.z; + position.z = epp.z; } else if(links[1]) { Vector epp = links[1]->get_endpoint_position(links[1]->get_endpoint_by_link(*this)); - pos.z = epp.z; + position.z = epp.z; } } } @@ -165,10 +172,10 @@ Vector Track::get_endpoint_position(unsigned epi) const const TrackType::Endpoint &ep = eps[epi]; - float c = cos(rot); - float s = sin(rot); + float c = cos(rotation); + float s = sin(rotation); - Vector p(pos.x+c*ep.pos.x-s*ep.pos.y, pos.y+s*ep.pos.x+c*ep.pos.y, pos.z); + Vector p(position.x+c*ep.pos.x-s*ep.pos.y, position.y+s*ep.pos.x+c*ep.pos.y, position.z); if(eps.size()==2 && epi==1) p.z += slope; return p; @@ -182,7 +189,7 @@ float Track::get_endpoint_direction(unsigned epi) const const TrackType::Endpoint &ep = eps[epi]; - return rot+ep.dir; + return rotation+ep.dir; } bool Track::snap_to(Track &other, bool link, float limit) @@ -215,9 +222,9 @@ bool Track::snap_to(Track &other, bool link, float limit) { if(!link || (!flex && !other.get_flex())) { - set_rotation(other.rot+other_eps[j].dir-eps[i].dir+M_PI); - Vector p(epp2.x-(eps[i].pos.x*cos(rot)-eps[i].pos.y*sin(rot)), - epp2.y-(eps[i].pos.y*cos(rot)+eps[i].pos.x*sin(rot)), + set_rotation(other.rotation+other_eps[j].dir-eps[i].dir+M_PI); + Vector p(epp2.x-(eps[i].pos.x*cos(rotation)-eps[i].pos.y*sin(rotation)), + epp2.y-(eps[i].pos.y*cos(rotation)+eps[i].pos.x*sin(rotation)), epp2.z); if(eps.size()==2 && i==1) p.z -= slope; @@ -256,7 +263,7 @@ bool Track::snap(Vector &pt, float &d) const if(dx*dx+dy*dy<1e-4) { pt = epp; - d = rot+eps[i].dir; + d = rotation+eps[i].dir; return true; } } @@ -299,11 +306,11 @@ Track *Track::get_link(unsigned i) const TrackPoint Track::get_point(unsigned epi, unsigned path, float d) const { TrackPoint p = type.get_point(epi, path, d); - float c = cos(rot); - float s = sin(rot); + float c = cos(rotation); + float s = sin(rotation); - p.pos = Vector(pos.x+c*p.pos.x-s*p.pos.y, pos.y+s*p.pos.x+c*p.pos.y, pos.z); - p.dir += rot; + p.pos = Vector(position.x+c*p.pos.x-s*p.pos.y, position.y+s*p.pos.x+c*p.pos.y, position.z); + p.dir += rotation; if(type.get_endpoints().size()==2) { float len = type.get_path_length(path); @@ -330,22 +337,22 @@ TrackPoint Track::get_point(unsigned epi, float d) const TrackPoint Track::get_nearest_point(const Vector &p) const { - Vector local(p.x-pos.x, p.y-pos.y, p.z-pos.z); - float c = cos(rot); - float s = sin(rot); + Vector local(p.x-position.x, p.y-position.y, p.z-position.z); + float c = cos(rotation); + float s = sin(rotation); local = Vector(c*local.x+s*local.y, c*local.y-s*local.x, local.z); TrackPoint tp = type.get_nearest_point(local); - tp.pos = Vector(pos.x+tp.pos.x*c-tp.pos.y*s, pos.y+tp.pos.y*c+tp.pos.x*s, pos.z+tp.pos.z); - tp.dir += rot; + tp.pos = Vector(position.x+tp.pos.x*c-tp.pos.y*s, position.y+tp.pos.y*c+tp.pos.x*s, position.z+tp.pos.z); + tp.dir += rotation; return tp; } -bool Track::collide_ray(const Vector &start, const Vector &ray) +bool Track::collide_ray(const Vector &start, const Vector &ray) const { - Vector local_start(start.x-pos.x, start.y-pos.y, start.z-pos.z); - float c = cos(rot); - float s = sin(rot); + Vector local_start(start.x-position.x, start.y-position.y, start.z-position.z); + float c = cos(rotation); + float s = sin(rotation); local_start = Vector(c*local_start.x+s*local_start.y, c*local_start.y-s*local_start.x, local_start.z); Vector local_ray(c*ray.x+s*ray.y, c*ray.y-s*ray.x, ray.z); @@ -356,8 +363,8 @@ bool Track::collide_ray(const Vector &start, const Vector &ray) void Track::save(list &st) const { - st.push_back((DataFile::Statement("position"), pos.x, pos.y, pos.z)); - st.push_back((DataFile::Statement("rotation"), rot)); + st.push_back((DataFile::Statement("position"), position.x, position.y, position.z)); + st.push_back((DataFile::Statement("rotation"), rotation)); st.push_back((DataFile::Statement("slope"), slope)); if(turnout_id) st.push_back((DataFile::Statement("turnout_id"), turnout_id)); @@ -385,7 +392,7 @@ Track::Loader::Loader(Track &t): DataFile::ObjectLoader(t) { add("position", &Loader::position); - add("rotation", &Track::rot); + add("rotation", &Loader::rotation); add("slope", &Track::slope); add("turnout_id", &Loader::turnout_id); add("sensor_id", &Loader::sensor_id); @@ -394,7 +401,12 @@ Track::Loader::Loader(Track &t): void Track::Loader::position(float x, float y, float z) { - obj.pos = Vector(x, y, z); + obj.position = Vector(x, y, z); +} + +void Track::Loader::rotation(float r) +{ + obj.rotation = r; } void Track::Loader::sensor_id(unsigned id) diff --git a/source/libr2c2/track.h b/source/libr2c2/track.h index 4dbfa2d..883fb5e 100644 --- a/source/libr2c2/track.h +++ b/source/libr2c2/track.h @@ -6,14 +6,15 @@ #include #include #include "geometry.h" +#include "object.h" +#include "tracktype.h" namespace R2C2 { class Block; class Layout; -class TrackType; -class Track: public sigc::trackable +class Track: public Object, public sigc::trackable { public: class Loader: public Msp::DataFile::ObjectLoader @@ -22,6 +23,7 @@ public: Loader(Track &); private: void position(float, float, float); + void rotation(float); void sensor_id(unsigned); void turnout_id(unsigned); }; @@ -30,11 +32,8 @@ public: sigc::signal signal_path_changed; private: - Layout &layout; const TrackType &type; Block *block; - Vector pos; - float rot; float slope; bool flex; unsigned turnout_id; @@ -49,17 +48,15 @@ public: Track(Layout &, const TrackType &); ~Track(); - Layout &get_layout() const { return layout; } - const TrackType &get_type() const { return type; } + virtual Track *clone(Layout * = 0) const; + virtual const TrackType &get_type() const { return type; } void set_block(Block *); Block &get_block() const; - void set_position(const Vector &); - void set_rotation(float); + virtual void set_position(const Vector &); + virtual void set_rotation(float); void set_slope(float); void set_flex(bool); - const Vector &get_position() const { return pos; } - float get_rotation() const { return rot; } float get_slope() const { return slope; } bool get_flex() const { return flex; } void check_slope(); @@ -85,7 +82,7 @@ public: TrackPoint get_point(unsigned, float) const; TrackPoint get_nearest_point(const Vector &) const; - bool collide_ray(const Vector &, const Vector &); + virtual bool collide_ray(const Vector &, const Vector &) const; void save(std::list &) const; private: diff --git a/source/libr2c2/tracktype.cpp b/source/libr2c2/tracktype.cpp index bf038c5..3be1ecb 100644 --- a/source/libr2c2/tracktype.cpp +++ b/source/libr2c2/tracktype.cpp @@ -7,7 +7,7 @@ using namespace Msp; namespace R2C2 { TrackType::TrackType(const ArticleNumber &an): - art_nr(an), + ObjectType(an), state_bits(0), autofit_preference(1) { } @@ -192,11 +192,10 @@ TrackType::Endpoint::Endpoint(float x, float y, float d, unsigned p): TrackType::Loader::Loader(TrackType &t): - Msp::DataFile::ObjectLoader(t), + DataFile::DerivedObjectLoader(t), state_bits_set(false) { add("autofit_preference", &TrackType::autofit_preference); - add("description", &TrackType::description); add("object", &TrackType::object); add("state_bits", &Loader::state_bits); add("part", &Loader::part); diff --git a/source/libr2c2/tracktype.h b/source/libr2c2/tracktype.h index dd2a7c4..afc8521 100644 --- a/source/libr2c2/tracktype.h +++ b/source/libr2c2/tracktype.h @@ -4,11 +4,12 @@ #include #include "articlenumber.h" #include "geometry.h" +#include "objecttype.h" #include "trackpart.h" namespace R2C2 { -class TrackType +class TrackType: public ObjectType { public: struct Endpoint @@ -23,7 +24,7 @@ public: bool has_common_paths(const Endpoint &e) const { return paths&e.paths; } }; - class Loader: public Msp::DataFile::ObjectLoader + class Loader: public Msp::DataFile::DerivedObjectLoader { private: bool state_bits_set; @@ -38,8 +39,6 @@ public: }; private: - ArticleNumber art_nr; - std::string description; std::vector parts; std::vector endpoints; unsigned state_bits; @@ -49,8 +48,6 @@ private: public: TrackType(const ArticleNumber &); - const ArticleNumber &get_article_number() const { return art_nr; } - const std::string &get_description() const { return description; } float get_total_length() const; float get_path_length(int) const; unsigned get_paths() const; diff --git a/source/libr2c2/vehicle.cpp b/source/libr2c2/vehicle.cpp index 4259c7d..250aefd 100644 --- a/source/libr2c2/vehicle.cpp +++ b/source/libr2c2/vehicle.cpp @@ -14,11 +14,10 @@ using namespace Msp; namespace R2C2 { Vehicle::Vehicle(Layout &l, const VehicleType &t): - layout(l), + Object(l), type(t), next(0), prev(0), - direction(0), front_sensor(0), back_sensor(0) { @@ -38,6 +37,14 @@ Vehicle::~Vehicle() layout.remove_vehicle(*this); } +Vehicle *Vehicle::clone(Layout *to_layout) const +{ + Vehicle *veh = new Vehicle((to_layout ? *to_layout : layout), type); + veh->set_position(position); + veh->set_rotation(rotation); + return veh; +} + void Vehicle::attach_back(Vehicle &veh) { if(next || veh.prev) @@ -189,7 +196,7 @@ void Vehicle::update_position() position = tp.pos; position.z += layout.get_catalogue().get_rail_elevation(); - direction = tp.dir; + rotation = tp.dir; } void Vehicle::update_position_from(const Vehicle &veh) diff --git a/source/libr2c2/vehicle.h b/source/libr2c2/vehicle.h index 8990a5b..54054bb 100644 --- a/source/libr2c2/vehicle.h +++ b/source/libr2c2/vehicle.h @@ -2,6 +2,7 @@ #define LIBR2C2_VEHICLE_H_ #include "geometry.h" +#include "object.h" #include "vehicletype.h" namespace R2C2 { @@ -17,7 +18,7 @@ public: }; -class Vehicle +class Vehicle: public Object { public: enum PlaceMode @@ -68,13 +69,10 @@ private: TrackPoint get_point() const; }; - Layout &layout; const VehicleType &type; Vehicle *next; Vehicle *prev; TrackPosition track_pos; - Vector position; - float direction; std::vector axles; std::vector bogies; std::vector rods; @@ -85,7 +83,8 @@ public: Vehicle(Layout &, const VehicleType &); ~Vehicle(); - const VehicleType &get_type() const { return type; } + virtual Vehicle *clone(Layout * = 0) const; + virtual const VehicleType &get_type() const { return type; } void attach_back(Vehicle &); void attach_front(Vehicle &); @@ -94,14 +93,15 @@ public: Vehicle *get_next() const { return next; } Vehicle *get_previous() const { return prev; } + // TODO implement these - should call place() with suitable parameters + virtual void set_position(const Vector &) { } + virtual void set_rotation(float) { } void place(Track &, unsigned, float, PlaceMode = CENTER); void unplace(); void advance(float); Track *get_track() const { return track_pos.track; } unsigned get_entry() const { return track_pos.ep; } float get_offset() const { return track_pos.offs; } - const Vector &get_position() const { return position; } - float get_direction() const { return direction; } const Axle &get_fixed_axle(unsigned) const; const Bogie &get_bogie(unsigned) const; const Axle &get_bogie_axle(unsigned, unsigned) const; @@ -119,6 +119,9 @@ private: void adjust_for_distance(TrackPosition &, TrackPosition &, float, float = 0.5) const; TrackPoint get_point(const Vector &, const Vector &, float = 0.5) const; TrackPoint get_point(const TrackPosition &, float, float = 0.5) const; + +public: + virtual bool collide_ray(const Vector &, const Vector &) const { return false; } }; } // namespace R2C2 diff --git a/source/libr2c2/vehicletype.cpp b/source/libr2c2/vehicletype.cpp index 2da44cc..973070c 100644 --- a/source/libr2c2/vehicletype.cpp +++ b/source/libr2c2/vehicletype.cpp @@ -8,7 +8,7 @@ using namespace Msp; namespace R2C2 { VehicleType::VehicleType(const ArticleNumber &an): - art_nr(an), + ObjectType(an), locomotive(false), swap_direction(false), length(0), @@ -105,7 +105,7 @@ VehicleType::Rod::Rod(): VehicleType::Loader::Loader(VehicleType &vt): - DataFile::ObjectLoader(vt) + DataFile::DerivedObjectLoader(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); diff --git a/source/libr2c2/vehicletype.h b/source/libr2c2/vehicletype.h index d8bec87..841664e 100644 --- a/source/libr2c2/vehicletype.h +++ b/source/libr2c2/vehicletype.h @@ -2,15 +2,15 @@ #define LIBR2C2_VEHICLETYPE_H_ #include -#include "articlenumber.h" #include "geometry.h" +#include "objecttype.h" namespace R2C2 { -class VehicleType +class VehicleType: public ObjectType { public: - class Loader: public Msp::DataFile::ObjectLoader + class Loader: public Msp::DataFile::DerivedObjectLoader { private: std::map rod_tags; @@ -125,8 +125,6 @@ public: typedef std::map FunctionMap; private: - ArticleNumber art_nr; - std::string name; bool locomotive; FunctionMap functions; bool swap_direction; @@ -142,8 +140,6 @@ private: public: VehicleType(const ArticleNumber &); - const ArticleNumber &get_article_number() const { return art_nr; } - const std::string &get_name() const { return name; } bool is_locomotive() const { return locomotive; } unsigned get_max_function() const; const FunctionMap &get_functions() const { return functions; } -- 2.43.0