]> git.tdb.fi Git - r2c2.git/blob - source/libr2c2/object.cpp
Add a dialog to display telemetry data from the driver
[r2c2.git] / source / libr2c2 / object.cpp
1 #include <stdexcept>
2 #include "object.h"
3
4 using namespace std;
5 using namespace Msp;
6
7 namespace R2C2 {
8
9 Object::Object(Layout &l):
10         layout(l),
11         shape(0)
12 { }
13
14 Snap Object::get_snap_node(unsigned) const
15 {
16         throw out_of_range("Object::get_snap_node");
17 }
18
19 bool Object::snap(Snap &sn, float limit, SnapType what) const
20 {
21         if(what&SNAP_NODE)
22         {
23                 unsigned nsn = get_n_snap_nodes();
24                 for(unsigned i=0; i<nsn; ++i)
25                 {
26                         Snap node = get_snap_node(i);
27                         Vector span = sn.position-node.position;
28                         if(dot(span, span)<limit*limit)
29                         {
30                                 sn = node;
31                                 return true;
32                         }
33                 }
34         }
35
36         return false;
37 }
38
39 bool Object::snap_to(const Object &other, float limit, SnapType what)
40 {
41         if(what==SNAP_DEFAULT)
42                 what = get_default_snap_type_to(other);
43
44         if(!what)
45                 return false;
46
47         unsigned nsn = get_n_snap_nodes();
48         for(unsigned i=0; i<nsn; ++i)
49         {
50                 Snap sn = get_snap_node(i);
51                 Snap ssn = sn;
52                 if(other.snap(ssn, limit, what))
53                 {
54                         if(what==SNAP_NODE)
55                                 set_rotation(rotation+ssn.rotation-sn.rotation-Angle::half_turn());
56                         else
57                         {
58                                 Angle adiff = wrap_balanced((ssn.rotation-sn.rotation)*2.0f)/2.0f;
59                                 set_rotation(rotation+adiff);
60                         }
61                         sn = get_snap_node(i);
62                         set_position(position+ssn.position-sn.position);
63                         return true;
64                 }
65         }
66
67         return false;
68 }
69
70 Object *Object::get_link(unsigned) const
71 {
72         throw out_of_range("Object::get_link");
73 }
74
75 bool Object::break_link(Object &other)
76 {
77         unsigned nls = get_n_link_slots();
78         for(unsigned i=0; i<nls; ++i)
79                 if(get_link(i)==&other)
80                         return break_link(i);
81
82         return false;
83 }
84
85 void Object::break_links()
86 {
87         unsigned nls = get_n_link_slots();
88         for(unsigned i=0; i<nls; ++i)
89                 break_link(i);
90 }
91
92 const Shape *Object::get_shape() const
93 {
94         if(shape)
95                 return shape;
96         return get_type().get_shape();
97 }
98
99 bool Object::collide_ray(const Ray &ray, float *d) const
100 {
101         const Shape *s = get_shape();
102         if(!s)
103                 return false;
104
105         Transform reverse_trans = Transform::rotation(rotation, Vector(0, 0, -1))*
106                 Transform::translation(-position);
107         if(d)
108         {
109                 vector<Geometry::SurfacePoint<float, 3> > points = s->get_intersections(reverse_trans.transform(ray));
110                 if(points.empty())
111                         return false;
112                 *d = points.front().distance;
113                 return true;
114         }
115         else
116                 return s->check_intersection(reverse_trans.transform(ray));
117 }
118
119 BoundingBox Object::get_bounding_box() const
120 {
121         const Shape *s = get_shape();
122         if(!s)
123                 return BoundingBox();
124
125         Transform trans = Transform::translation(position)*
126                 Transform::rotation(rotation, Vector(0, 0, 1));
127         return trans.transform(s->get_axis_aligned_bounding_box());
128 }
129
130 } // namespace R2C2