#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");
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;
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;
}
}
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