X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Flibr2c2%2Fsignal.cpp;h=650c36232e87d82559fc36cfbb6aba2bc160ab55;hb=b88d3630a0e3fdd763db018bbe5dbfe3180a95f2;hp=a8b0be029799afdcec0c5c379b2788e31919583d;hpb=176634834df3ac62646d1aec78e35f9364750d7d;p=r2c2.git diff --git a/source/libr2c2/signal.cpp b/source/libr2c2/signal.cpp index a8b0be0..650c362 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; @@ -48,12 +56,15 @@ void Signal::set_position(const Vector &p) for(set::const_iterator i=tracks.begin(); i!=tracks.end(); ++i) if(!(*i)->get_type().is_turnout()) { - TrackPoint n = (*i)->get_nearest_point(p); - float d = distance(p, n.pos); + Snap sn; + sn.position = p; + sn.rotation = rotation; + (*i)->snap(sn, 1000, SNAP_SEGMENT); + float d = distance(p, sn.position); if(dget_type().get_endpoints().size(); for(unsigned j=0; jget_endpoint_direction(j)-direction; + float a = track->get_snap_node(j).rotation-rotation; while(a<-M_PI/2) a += M_PI*2; while(a>M_PI*3/2) @@ -82,23 +93,61 @@ 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(); } +unsigned Signal::get_n_snap_nodes() const +{ + return 1; +} + +Snap Signal::get_snap_node(unsigned i) const +{ + if(i>=1) + throw out_of_range("Signal::get_snap_node"); + + Snap sn; + sn.position = position; + sn.rotation = rotation; + return sn; +} + +SnapType Signal::get_default_snap_type_to(const Object &other) const +{ + if(dynamic_cast(&other)) + return SNAP_SEGMENT; + + return NO_SNAP; +} + +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 +225,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 +234,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 +244,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