]> git.tdb.fi Git - r2c2.git/blobdiff - source/libr2c2/track.cpp
Add a common base class for tangible objects
[r2c2.git] / source / libr2c2 / track.cpp
index d4e9d12d8ef7b08682f0f9c97d5f4cb36a3cce38..b679af783867f72746793f205179f004a9e02baa 100644 (file)
@@ -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<DataFile::Statement> &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<Track>(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)