]> git.tdb.fi Git - r2c2.git/blobdiff - source/libr2c2/object.cpp
Avoid negative values of wait_time
[r2c2.git] / source / libr2c2 / object.cpp
index 1b48a862ae6b634c499fa49c094e54bc5c41cb05..7a896b6581b40c849e5a3296c513260038b4c230 100644 (file)
@@ -2,9 +2,15 @@
 #include "object.h"
 
 using namespace std;
+using namespace Msp;
 
 namespace R2C2 {
 
+Object::Object(Layout &l):
+       layout(l),
+       shape(0)
+{ }
+
 Snap Object::get_snap_node(unsigned) const
 {
        throw out_of_range("Object::get_snap_node");
@@ -18,8 +24,8 @@ bool Object::snap(Snap &sn, float limit, SnapType what) const
                for(unsigned i=0; i<nsn; ++i)
                {
                        Snap node = get_snap_node(i);
-                       Vector d(sn.position.x-node.position.x, sn.position.y-node.position.y, sn.position.z-node.position.z);
-                       if(d.x*d.x+d.y*d.y<limit*limit)
+                       Vector span = sn.position-node.position;
+                       if(dot(span, span)<limit*limit)
                        {
                                sn = node;
                                return true;
@@ -45,11 +51,15 @@ bool Object::snap_to(const Object &other, float limit, SnapType what)
                Snap ssn = sn;
                if(other.snap(ssn, limit, what))
                {
-                       set_rotation(rotation+ssn.rotation-sn.rotation-M_PI);
+                       if(what==SNAP_NODE)
+                               set_rotation(rotation+ssn.rotation-sn.rotation-Angle::half_turn());
+                       else
+                       {
+                               Angle adiff = wrap_balanced((ssn.rotation-sn.rotation)*2.0f)/2.0f;
+                               set_rotation(rotation+adiff);
+                       }
                        sn = get_snap_node(i);
-                       position.x += ssn.position.x-sn.position.x;
-                       position.y += ssn.position.y-sn.position.y;
-                       position.z += ssn.position.z-sn.position.z;
+                       set_position(position+ssn.position-sn.position);
                        return true;
                }
        }
@@ -57,4 +67,64 @@ bool Object::snap_to(const Object &other, float limit, SnapType what)
        return false;
 }
 
+Object *Object::get_link(unsigned) const
+{
+       throw out_of_range("Object::get_link");
+}
+
+bool Object::break_link(Object &other)
+{
+       unsigned nls = get_n_link_slots();
+       for(unsigned i=0; i<nls; ++i)
+               if(get_link(i)==&other)
+                       return break_link(i);
+
+       return false;
+}
+
+void Object::break_links()
+{
+       unsigned nls = get_n_link_slots();
+       for(unsigned i=0; i<nls; ++i)
+               break_link(i);
+}
+
+const Shape *Object::get_shape() const
+{
+       if(shape)
+               return shape;
+       return get_type().get_shape();
+}
+
+bool Object::collide_ray(const Ray &ray, float *d) const
+{
+       const Shape *s = get_shape();
+       if(!s)
+               return false;
+
+       Transform reverse_trans = Transform::rotation(rotation, Vector(0, 0, -1))*
+               Transform::translation(-position);
+       if(d)
+       {
+               vector<Geometry::SurfacePoint<float, 3> > points = s->get_intersections(reverse_trans.transform(ray));
+               if(points.empty())
+                       return false;
+               *d = points.front().distance;
+               return true;
+       }
+       else
+               return s->check_intersection(reverse_trans.transform(ray));
+}
+
+BoundingBox Object::get_bounding_box() const
+{
+       const Shape *s = get_shape();
+       if(!s)
+               return BoundingBox();
+
+       Transform trans = Transform::translation(position)*
+               Transform::rotation(rotation, Vector(0, 0, 1));
+       return trans.transform(s->get_axis_aligned_bounding_box());
+}
+
 } // namespace R2C2