Panda3D
collisionBox.I
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file collisionBox.I
10  * @author amith tudur
11  * @date 2009-07-31
12  */
13 
14 /**
15  * Create the Box by giving a Center and distances of each of the sides of
16  * box from the Center.
17  */
18 INLINE CollisionBox::
19 CollisionBox(const LPoint3 &center, PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) :
20  _center(center), _x(x), _y(y), _z(z)
21 {
22  _min = LPoint3(_center.get_x() - _x, _center.get_y() - _y, _center.get_z() - _z);
23  _max = LPoint3(_center.get_x() + _x, _center.get_y() + _y, _center.get_z() + _z);
24  _radius = sqrt(_x*_x + _y*_y + _z*_z);
25  for(int v = 0; v < 8; v++)
26  _vertex[v] = get_point_aabb(v);
27  for(int p = 0; p < 6; p++)
28  _planes[p] = set_plane(p);
29  setup_box();
30 }
31 
32 /**
33  * Create the Box by Specifying the Diagonal Points
34  */
35 INLINE CollisionBox::
36 CollisionBox(const LPoint3 &min, const LPoint3 &max) :
37  _min(min), _max(max)
38 {
39  _center = (_min + _max) / 2;
40  _x = _center.get_x() - _min.get_x();
41  _y = _center.get_y() - _min.get_y();
42  _z = _center.get_z() - _min.get_z();
43  _radius = sqrt(_x*_x + _y*_y + _z*_z);
44  for(int v = 0; v < 8; v++)
45  _vertex[v] = get_point_aabb(v);
46  for(int p = 0; p < 6; p++)
47  _planes[p] = set_plane(p);
48  setup_box();
49 }
50 
51 /**
52  * Creates an invalid Box. Only used when reading from a bam file.
53  */
54 INLINE CollisionBox::
55 CollisionBox() {
56 }
57 
58 /**
59  *
60  */
61 INLINE CollisionBox::
62 CollisionBox(const CollisionBox &copy) :
63  CollisionSolid(copy),
64  _center(copy._center),
65  _min(copy._min),
66  _max(copy._max),
67  _x(copy._x ),
68  _y(copy._y ),
69  _z(copy._z ),
70  _radius(copy._radius )
71 {
72  for(int v = 0; v < 8; v++)
73  _vertex[v] = copy._vertex[v];
74  for(int p = 0; p < 6; p++)
75  _planes[p] = copy._planes[p];
76  setup_box();
77 }
78 
79 /**
80  * Flushes the PStatCollectors used during traversal.
81  */
82 INLINE void CollisionBox::
84  _volume_pcollector.flush_level();
85  _test_pcollector.flush_level();
86 }
87 
88 /**
89  *
90  */
91 INLINE void CollisionBox::
92 set_center(const LPoint3 &center) {
93  _center = center;
94  mark_internal_bounds_stale();
95  mark_viz_stale();
96 }
97 
98 /**
99  *
100  */
101 INLINE void CollisionBox::
102 set_center(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) {
103  set_center(LPoint3(x, y, z));
104 }
105 
106 /**
107  *
108  */
109 INLINE const LPoint3 &CollisionBox::
110 get_center() const {
111  return _center;
112 }
113 
114 /**
115  *
116  */
117 INLINE const LPoint3 &CollisionBox::
118 get_min() const {
119  return _min;
120 }
121 
122 /**
123  *
124  */
125 INLINE const LPoint3 &CollisionBox::
126 get_max() const {
127  return _max;
128 }
129 
130 /**
131  *
132  */
133 INLINE LVector3 CollisionBox::
134 get_dimensions() const {
135  return _max - _min;
136 }
137 
138 /**
139  * Returns 8: the number of vertices of a rectangular solid.
140  */
141 INLINE int CollisionBox::
142 get_num_points() const {
143  return 8;
144 }
145 
146 /**
147  * Returns the nth vertex of the OBB.
148  */
149 INLINE LPoint3 CollisionBox::
150 get_point(int n) const {
151  nassertr(n >= 0 && n < 8, LPoint3::zero());
152  return _vertex[n];
153 }
154 
155 
156 /**
157  * Returns the nth vertex of the Axis Aligned Bounding Box.
158  */
159 INLINE LPoint3 CollisionBox::
160 get_point_aabb(int n) const {
161  nassertr(n >= 0 && n < 8, LPoint3::zero());
162 
163  // We do some trickery assuming that _min and _max are consecutive in
164  // memory.
165  const LPoint3 *a = &_min;
166  return LPoint3(a[(n>>2)&1][0], a[(n>>1)&1][1], a[(n)&1][2]);
167 }
168 
169 /**
170  * Returns 6: the number of faces of a rectangular solid.
171  */
172 INLINE int CollisionBox::
173 get_num_planes() const {
174  return 6;
175 }
176 
177 /**
178  * Returns the nth face of the rectangular solid.
179  */
180 INLINE LPlane CollisionBox::
181 get_plane(int n) const {
182  nassertr(n >= 0 && n < 6, LPlane());
183  return _planes[n];
184 }
185 
186 /**
187  * Creates the nth face of the rectangular solid.
188  */
189 INLINE LPlane CollisionBox::
190 set_plane(int n) const {
191  nassertr(n >= 0 && n < 6, LPlane());
192  return LPlane(get_point(plane_def[n][0]),
193  get_point(plane_def[n][1]),
194  get_point(plane_def[n][2]));
195 }
196 
197 
198 /**
199  * Returns true if the 2-d v1 is to the right of v2.
200  */
201 INLINE bool CollisionBox::
202 is_right(const LVector2 &v1, const LVector2 &v2) {
203  return (v1[0] * v2[1] - v1[1] * v2[0]) > 1.0e-6f;
204 }
205 
206 /**
207  * Returns the linear distance of p to the line defined by f and f+v, where v
208  * is a normalized vector. The result is negative if p is left of the line,
209  * positive if it is right of the line.
210  */
211 INLINE PN_stdfloat CollisionBox::
212 dist_to_line(const LPoint2 &p,
213  const LPoint2 &f, const LVector2 &v) {
214  LVector2 v1 = (p - f);
215  return (v1[0] * v[1] - v1[1] * v[0]);
216 }
217 
218 /**
219  * Assuming the indicated point in 3-d space lies within the polygon's plane,
220  * returns the corresponding point in the polygon's 2-d definition space.
221  */
222 INLINE LPoint2 CollisionBox::
223 to_2d(const LVecBase3 &point3d, int plane) const {
224  LPoint3 point = LPoint3(point3d) * _to_2d_mat[plane];
225  return LPoint2(point[0], point[2]);
226 }
227 
228 /**
229  * Fills the indicated matrix with the appropriate rotation transform to move
230  * points from the 2-d plane into the 3-d (X, 0, Z) plane.
231  */
232 INLINE void CollisionBox::
233 calc_to_3d_mat(LMatrix4 &to_3d_mat,int plane) const {
234  // We have to be explicit about the coordinate system--we specifically mean
235  // CS_zup_right, because that points the forward vector down the Y axis and
236  // moves the coords in (X, 0, Z). We want this effect regardless of the
237  // user's coordinate system of choice.
238 
239  // The up vector, on the other hand, is completely arbitrary.
240 
241  look_at(to_3d_mat, -get_plane(plane).get_normal(),
242  LVector3(0.0f, 0.0f, 1.0f), CS_zup_right);
243  to_3d_mat.set_row(3, get_plane(plane).get_point());
244 }
245 
246 /**
247  * Fills the indicated matrix with the appropriate rotation transform to move
248  * points from the 2-d plane into the 3-d (X, 0, Z) plane.
249  *
250  * This is essentially similar to calc_to_3d_mat, except that the matrix is
251  * rederived from whatever is stored in _to_2d_mat, guaranteeing that it will
252  * match whatever algorithm produced that one, even if it was produced on a
253  * different machine with different numerical precision.
254  */
255 INLINE void CollisionBox::
256 rederive_to_3d_mat(LMatrix4 &to_3d_mat, int plane) const {
257  to_3d_mat.invert_from(_to_2d_mat[plane]);
258 }
259 
260 /**
261  * Extrude the indicated point in the polygon's 2-d definition space back into
262  * 3-d coordinates.
263  */
264 INLINE LPoint3 CollisionBox::
265 to_3d(const LVecBase2 &point2d, const LMatrix4 &to_3d_mat) {
266  return LPoint3(point2d[0], 0.0f, point2d[1]) * to_3d_mat;
267 }
268 
269 /**
270  *
271  */
272 INLINE CollisionBox::PointDef::
273 PointDef(const LPoint2 &p, const LVector2 &v) : _p(p), _v(v) {
274 }
275 
276 /**
277  *
278  */
279 INLINE CollisionBox::PointDef::
280 PointDef(PN_stdfloat x, PN_stdfloat y) : _p(x, y), _v(0.0f, 0.0f) {
281 }
282 
283 /**
284  *
285  */
286 INLINE CollisionBox::PointDef::
287 PointDef(const CollisionBox::PointDef &copy) : _p(copy._p), _v(copy._v) {
288 }
289 
290 /**
291  *
292  */
293 INLINE void CollisionBox::PointDef::
294 operator = (const CollisionBox::PointDef &copy) {
295  _p = copy._p;
296  _v = copy._v;
297 }
298 
299 /**
300  * returns the points that form the nth plane
301  */
304  return _points[n];
305 }
void calc_to_3d_mat(LMatrix4 &to_3d_mat, int plane) const
Fills the indicated matrix with the appropriate rotation transform to move points from the 2-d plane ...
Definition: collisionBox.I:233
void setup_box()
Compute parameters for each of the box's sides.
The abstract base class for all things that can collide with other things in the world,...
A cuboid collision volume or object.
Definition: collisionBox.h:27
LPoint2 to_2d(const LVecBase3 &point3d, int plane) const
Assuming the indicated point in 3-d space lies within the polygon's plane, returns the corresponding ...
Definition: collisionBox.I:223
static LPoint3 to_3d(const LVecBase2 &point2d, const LMatrix4 &to_3d_mat)
Extrude the indicated point in the polygon's 2-d definition space back into 3-d coordinates.
Definition: collisionBox.I:265
LPoint3 get_point_aabb(int n) const
Returns the nth vertex of the Axis Aligned Bounding Box.
Definition: collisionBox.I:160
int get_num_points() const
Returns 8: the number of vertices of a rectangular solid.
Definition: collisionBox.I:142
int get_num_planes() const
Returns 6: the number of faces of a rectangular solid.
Definition: collisionBox.I:173
LPlane set_plane(int n) const
Creates the nth face of the rectangular solid.
Definition: collisionBox.I:190
LPlane get_plane(int n) const
Returns the nth face of the rectangular solid.
Definition: collisionBox.I:181
static void flush_level()
Flushes the PStatCollectors used during traversal.
Definition: collisionBox.I:83
LPoint3 get_point(int n) const
Returns the nth vertex of the OBB.
Definition: collisionBox.I:150
Points get_plane_points(int n)
returns the points that form the nth plane
Definition: collisionBox.I:303
void rederive_to_3d_mat(LMatrix4 &to_3d_mat, int plane) const
Fills the indicated matrix with the appropriate rotation transform to move points from the 2-d plane ...
Definition: collisionBox.I:256