Panda3D
collisionEntry.I
1 // Filename: collisionEntry.I
2 // Created by: drose (16Mar02)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 
16 ////////////////////////////////////////////////////////////////////
17 // Function: CollisionEntry::Constructor
18 // Access: Published
19 // Description:
20 ////////////////////////////////////////////////////////////////////
21 INLINE CollisionEntry::
22 CollisionEntry() {
23  _flags = 0;
24  // > 1. means collision didn't happen
25  _t = 2.f;
26 }
27 
28 ////////////////////////////////////////////////////////////////////
29 // Function: CollisionEntry::get_from
30 // Access: Published
31 // Description: Returns the CollisionSolid pointer for the particular
32 // solid that triggered this collision.
33 ////////////////////////////////////////////////////////////////////
34 INLINE const CollisionSolid *CollisionEntry::
35 get_from() const {
36  return _from;
37 }
38 
39 ////////////////////////////////////////////////////////////////////
40 // Function: CollisionEntry::has_into
41 // Access: Published
42 // Description: Returns true if the "into" solid is, in fact, a
43 // CollisionSolid, and its pointer is known (in which
44 // case get_into() may be called to retrieve it). If
45 // this returns false, the collision was detected into a
46 // GeomNode, and there is no CollisionSolid pointer to
47 // be retrieved.
48 ////////////////////////////////////////////////////////////////////
49 INLINE bool CollisionEntry::
50 has_into() const {
51  return (_into != (CollisionSolid *)NULL);
52 }
53 
54 ////////////////////////////////////////////////////////////////////
55 // Function: CollisionEntry::get_into
56 // Access: Published
57 // Description: Returns the CollisionSolid pointer for the particular
58 // solid was collided into. This pointer might be NULL
59 // if the collision was into a piece of visible
60 // geometry, instead of a normal CollisionSolid
61 // collision; see has_into().
62 ////////////////////////////////////////////////////////////////////
63 INLINE const CollisionSolid *CollisionEntry::
64 get_into() const {
65  return _into;
66 }
67 
68 ////////////////////////////////////////////////////////////////////
69 // Function: CollisionEntry::get_from_node
70 // Access: Published
71 // Description: Returns the node that contains the CollisionSolid
72 // that triggered this collision. This will be a node
73 // that has been added to a CollisionTraverser via
74 // add_collider().
75 ////////////////////////////////////////////////////////////////////
77 get_from_node() const {
78  return _from_node;
79 }
80 
81 ////////////////////////////////////////////////////////////////////
82 // Function: CollisionEntry::get_into_node
83 // Access: Published
84 // Description: Returns the node that contains the CollisionSolid
85 // that was collided into. This returns a PandaNode
86 // pointer instead of something more specific, because
87 // it might be either a CollisionNode or a GeomNode.
88 //
89 // Also see get_into_node_path().
90 ////////////////////////////////////////////////////////////////////
92 get_into_node() const {
93  return _into_node;
94 }
95 
96 ////////////////////////////////////////////////////////////////////
97 // Function: CollisionEntry::get_from_node_path
98 // Access: Published
99 // Description: Returns the NodePath that represents the
100 // CollisionNode that contains the CollisionSolid that
101 // triggered this collision. This will be a NodePath
102 // that has been added to a CollisionTraverser via
103 // add_collider().
104 ////////////////////////////////////////////////////////////////////
107  return _from_node_path;
108 }
109 
110 ////////////////////////////////////////////////////////////////////
111 // Function: CollisionEntry::get_into_node_path
112 // Access: Published
113 // Description: Returns the NodePath that represents the specific
114 // CollisionNode or GeomNode instance that was collided
115 // into. This is the same node returned by
116 // get_into_node(), represented as a NodePath; however,
117 // it may be more useful because the NodePath can
118 // resolve the particular instance of the node, if there
119 // is more than one.
120 ////////////////////////////////////////////////////////////////////
123  return _into_node_path;
124 }
125 
126 ////////////////////////////////////////////////////////////////////
127 // Function: CollisionEntry::set_t
128 // Access: Published
129 // Description: Sets a time value for this collision relative to
130 // other CollisionEntries
131 ////////////////////////////////////////////////////////////////////
132 INLINE void CollisionEntry::
133 set_t(PN_stdfloat t) {
134  nassertv(!cnan(t));
135  _t = t;
136 }
137 
138 ////////////////////////////////////////////////////////////////////
139 // Function: CollisionEntry::set_t
140 // Access: Published
141 // Description: returns time value for this collision relative to
142 // other CollisionEntries
143 ////////////////////////////////////////////////////////////////////
144 INLINE PN_stdfloat CollisionEntry::
145 get_t() const {
146  return _t;
147 }
148 
149 ////////////////////////////////////////////////////////////////////
150 // Function: CollisionEntry::collided
151 // Access: Published
152 // Description: returns true if this represents an actual collision
153 // as opposed to a potential collision, needed for
154 // iterative collision resolution where path of
155 // collider changes mid-frame
156 ////////////////////////////////////////////////////////////////////
157 INLINE bool CollisionEntry::
158 collided() const {
159  return ((0.f <= _t) && (_t <= 1.f));
160 }
161 
162 ////////////////////////////////////////////////////////////////////
163 // Function: CollisionEntry::reset_collided
164 // Access: Published
165 // Description: prepare for another collision test
166 ////////////////////////////////////////////////////////////////////
167 INLINE void CollisionEntry::
169  _t = 2.f;
170 }
171 
172 ////////////////////////////////////////////////////////////////////
173 // Function: CollisionEntry::get_respect_prev_transform
174 // Access: Published
175 // Description: Returns true if the collision was detected by a
176 // CollisionTraverser whose respect_prev_transform
177 // flag was set true, meaning we should consider motion
178 // significant in evaluating collisions.
179 ////////////////////////////////////////////////////////////////////
180 INLINE bool CollisionEntry::
182  return (_flags & F_respect_prev_transform) != 0;
183 }
184 
185 
186 ////////////////////////////////////////////////////////////////////
187 // Function: CollisionEntry::set_surface_point
188 // Access: Published
189 // Description: Stores the point, on the surface of the "into"
190 // object, at which a collision is detected.
191 //
192 // This point is specified in the coordinate space of
193 // the "into" object.
194 ////////////////////////////////////////////////////////////////////
195 INLINE void CollisionEntry::
196 set_surface_point(const LPoint3 &point) {
197  nassertv(!point.is_nan());
198  _surface_point = point;
199  _flags |= F_has_surface_point;
200 }
201 
202 ////////////////////////////////////////////////////////////////////
203 // Function: CollisionEntry::set_surface_normal
204 // Access: Published
205 // Description: Stores the surface normal of the "into" object at the
206 // point of the intersection.
207 //
208 // This normal is specified in the coordinate space of
209 // the "into" object.
210 ////////////////////////////////////////////////////////////////////
211 INLINE void CollisionEntry::
212 set_surface_normal(const LVector3 &normal) {
213  nassertv(!normal.is_nan());
214  _surface_normal = normal;
215  _flags |= F_has_surface_normal;
216 }
217 
218 ////////////////////////////////////////////////////////////////////
219 // Function: CollisionEntry::set_interior_point
220 // Access: Published
221 // Description: Stores the point, within the interior of the "into"
222 // object, which represents the depth to which the
223 // "from" object has penetrated. This can also be
224 // described as the intersection point on the surface of
225 // the "from" object (which is inside the "into"
226 // object).
227 //
228 // This point is specified in the coordinate space of
229 // the "into" object.
230 ////////////////////////////////////////////////////////////////////
231 INLINE void CollisionEntry::
233  nassertv(!point.is_nan());
234  _interior_point = point;
235  _flags |= F_has_interior_point;
236 }
237 
238 ////////////////////////////////////////////////////////////////////
239 // Function: CollisionEntry::has_surface_point
240 // Access: Published
241 // Description: Returns true if the surface point has been specified,
242 // false otherwise. See get_surface_point(). Some
243 // types of collisions may not compute the surface
244 // point.
245 ////////////////////////////////////////////////////////////////////
246 INLINE bool CollisionEntry::
248  return (_flags & F_has_surface_point) != 0;
249 }
250 
251 ////////////////////////////////////////////////////////////////////
252 // Function: CollisionEntry::has_surface_normal
253 // Access: Published
254 // Description: Returns true if the surface normal has been specified,
255 // false otherwise. See get_surface_normal(). Some
256 // types of collisions may not compute the surface
257 // normal.
258 ////////////////////////////////////////////////////////////////////
259 INLINE bool CollisionEntry::
261  return (_flags & F_has_surface_normal) != 0;
262 }
263 
264 ////////////////////////////////////////////////////////////////////
265 // Function: CollisionEntry::has_interior_point
266 // Access: Published
267 // Description: Returns true if the interior point has been specified,
268 // false otherwise. See get_interior_point(). Some
269 // types of collisions may not compute the interior
270 // point.
271 ////////////////////////////////////////////////////////////////////
272 INLINE bool CollisionEntry::
274  return (_flags & F_has_interior_point) != 0;
275 }
276 
277 ////////////////////////////////////////////////////////////////////
278 // Function: CollisionEntry::set_contact_pos
279 // Access: Published
280 // Description: Stores the position of the "from" object at the
281 // instant at which the collision is first detected.
282 //
283 // This position is specified in the coordinate space of
284 // the "into" object.
285 ////////////////////////////////////////////////////////////////////
286 INLINE void CollisionEntry::
288  nassertv(!pos.is_nan());
289  _contact_pos = pos;
290  _flags |= F_has_contact_pos;
291 }
292 
293 ////////////////////////////////////////////////////////////////////
294 // Function: CollisionEntry::set_contact_normal
295 // Access: Published
296 // Description: Stores the surface normal of the "into" object at the
297 // contact pos.
298 //
299 // This normal is specified in the coordinate space of
300 // the "into" object.
301 ////////////////////////////////////////////////////////////////////
302 INLINE void CollisionEntry::
303 set_contact_normal(const LVector3 &normal) {
304  nassertv(!normal.is_nan());
305  _contact_normal = normal;
306  _flags |= F_has_contact_normal;
307 }
308 
309 ////////////////////////////////////////////////////////////////////
310 // Function: CollisionEntry::has_contact_pos
311 // Access: Published
312 // Description: Returns true if the contact position has been specified,
313 // false otherwise. See get_contact_pos(). Some
314 // types of collisions may not compute the contact
315 // pos.
316 ////////////////////////////////////////////////////////////////////
317 INLINE bool CollisionEntry::
319  return (_flags & F_has_contact_pos) != 0;
320 }
321 
322 ////////////////////////////////////////////////////////////////////
323 // Function: CollisionEntry::has_contact_normal
324 // Access: Published
325 // Description: Returns true if the contact normal has been specified,
326 // false otherwise. See get_contact_normal(). Some
327 // types of collisions may not compute the contact
328 // normal.
329 ////////////////////////////////////////////////////////////////////
330 INLINE bool CollisionEntry::
332  return (_flags & F_has_contact_normal) != 0;
333 }
334 
335 ////////////////////////////////////////////////////////////////////
336 // Function: CollisionEntry::get_wrt_space
337 // Access: Public
338 // Description: Returns the relative transform of the from node as
339 // seen from the into node.
340 ////////////////////////////////////////////////////////////////////
341 INLINE CPT(TransformState) CollisionEntry::
342 get_wrt_space() const {
343  return _from_node_path.get_transform(_into_node_path);
344 }
345 
346 ////////////////////////////////////////////////////////////////////
347 // Function: CollisionEntry::get_inv_wrt_space
348 // Access: Public
349 // Description: Returns the relative transform of the into node as
350 // seen from the from node.
351 ////////////////////////////////////////////////////////////////////
352 INLINE CPT(TransformState) CollisionEntry::
353 get_inv_wrt_space() const {
354  return _into_node_path.get_transform(_from_node_path);
355 }
356 
357 ////////////////////////////////////////////////////////////////////
358 // Function: CollisionEntry::get_wrt_prev_space
359 // Access: Public
360 // Description: Returns the relative transform of the from node as
361 // seen from the into node, as of the previous frame
362 // (according to set_prev_transform(), set_fluid_pos(),
363 // etc.)
364 ////////////////////////////////////////////////////////////////////
365 INLINE CPT(TransformState) CollisionEntry::
366 get_wrt_prev_space() const {
368  return _from_node_path.get_prev_transform(_into_node_path);
369  } else {
370  return get_wrt_space();
371  }
372 }
373 
374 ////////////////////////////////////////////////////////////////////
375 // Function: CollisionEntry::get_wrt_mat
376 // Access: Public
377 // Description: Returns the relative transform of the from node as
378 // seen from the into node.
379 ////////////////////////////////////////////////////////////////////
380 INLINE const LMatrix4 &CollisionEntry::
381 get_wrt_mat() const {
382  return get_wrt_space()->get_mat();
383 }
384 
385 ////////////////////////////////////////////////////////////////////
386 // Function: CollisionEntry::get_inv_wrt_mat
387 // Access: Public
388 // Description: Returns the relative transform of the into node as
389 // seen from the from node.
390 ////////////////////////////////////////////////////////////////////
391 INLINE const LMatrix4 &CollisionEntry::
392 get_inv_wrt_mat() const {
393  return get_inv_wrt_space()->get_mat();
394 }
395 
396 ////////////////////////////////////////////////////////////////////
397 // Function: CollisionEntry::get_wrt_prev_mat
398 // Access: Public
399 // Description: Returns the relative transform of the from node as
400 // seen from the into node, as of the previous frame
401 // (according to set_prev_transform(), set_fluid_pos(),
402 // etc.)
403 ////////////////////////////////////////////////////////////////////
404 INLINE const LMatrix4 &CollisionEntry::
405 get_wrt_prev_mat() const {
406  return get_wrt_prev_space()->get_mat();
407 }
408 
409 ////////////////////////////////////////////////////////////////////
410 // Function: CollisionEntry::get_into_clip_planes
411 // Access: Public
412 // Description: Returns the ClipPlaneAttrib, if any, that is applied
413 // to the into_node_path, or NULL if there is no clip
414 // plane in effect.
415 ////////////////////////////////////////////////////////////////////
416 INLINE const ClipPlaneAttrib *CollisionEntry::
417 get_into_clip_planes() const {
418  if ((_flags & F_checked_clip_planes) == 0) {
419  ((CollisionEntry *)this)->check_clip_planes();
420  }
421  return _into_clip_planes;
422 }
423 
424 ////////////////////////////////////////////////////////////////////
425 // Function: CollisionEntry::test_intersection
426 // Access: Private
427 // Description: This is intended to be called only by the
428 // CollisionTraverser. It requests the CollisionEntry
429 // to start the intersection test between the from and
430 // into solids stored within it, passing the result (if
431 // positive) to the indicated CollisionHandler.
432 ////////////////////////////////////////////////////////////////////
433 INLINE void CollisionEntry::
434 test_intersection(CollisionHandler *record,
435  const CollisionTraverser *trav) const {
436  PT(CollisionEntry) result = get_from()->test_intersection(*this);
437 #ifdef DO_COLLISION_RECORDING
438  if (trav->has_recorder()) {
439  if (result != (CollisionEntry *)NULL) {
440  trav->get_recorder()->collision_tested(*result, true);
441  } else {
442  trav->get_recorder()->collision_tested(*this, false);
443  }
444  }
445 #endif // DO_COLLISION_RECORDING
446 #ifdef DO_PSTATS
447  ((CollisionSolid *)get_into())->get_test_pcollector().add_level(1);
448 #endif // DO_PSTATS
449  // if there was no collision detected but the handler wants to know about all
450  // potential collisions, create a "didn't collide" collision entry for it
451  if (record->wants_all_potential_collidees() && result == (CollisionEntry *)NULL) {
452  result = new CollisionEntry(*this);
453  result->reset_collided();
454  }
455  if (result != (CollisionEntry *)NULL) {
456  record->add_entry(result);
457  }
458 }
459 
460 INLINE ostream &
461 operator << (ostream &out, const CollisionEntry &entry) {
462  entry.output(out);
463  return out;
464 }
bool has_surface_point() const
Returns true if the surface point has been specified, false otherwise.
A basic node of the scene graph or data graph.
Definition: pandaNode.h:72
The abstract interface to a number of classes that decide what to do when a collision is detected...
NodePath get_into_node_path() const
Returns the NodePath that represents the specific CollisionNode or GeomNode instance that was collide...
bool wants_all_potential_collidees() const
Returns true if handler wants to know about all solids that are within the collider&#39;s bounding volume...
The abstract base class for all things that can collide with other things in the world, and all the things they can collide with (except geometry).
bool has_contact_normal() const
Returns true if the contact normal has been specified, false otherwise.
void set_contact_normal(const LVector3 &normal)
Stores the surface normal of the "into" object at the contact pos.
bool collided() const
returns true if this represents an actual collision as opposed to a potential collision, needed for iterative collision resolution where path of collider changes mid-frame
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
Definition: lvector3.h:100
This functions similarly to a LightAttrib.
void set_t(PN_stdfloat t)
Sets a time value for this collision relative to other CollisionEntries.
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
Definition: lpoint3.h:99
bool is_nan() const
Returns true if any component of the vector is not-a-number, false otherwise.
Definition: lvecBase3.h:464
void set_interior_point(const LPoint3 &point)
Stores the point, within the interior of the "into" object, which represents the depth to which the "...
bool has_into() const
Returns true if the "into" solid is, in fact, a CollisionSolid, and its pointer is known (in which ca...
bool has_surface_normal() const
Returns true if the surface normal has been specified, false otherwise.
const CollisionSolid * get_into() const
Returns the CollisionSolid pointer for the particular solid was collided into.
This is a 4-by-4 transform matrix.
Definition: lmatrix.h:451
Defines a single collision event.
PN_stdfloat get_t() const
returns time value for this collision relative to other CollisionEntries
CollisionNode * get_from_node() const
Returns the node that contains the CollisionSolid that triggered this collision.
bool has_contact_pos() const
Returns true if the contact position has been specified, false otherwise.
void set_contact_pos(const LPoint3 &pos)
Stores the position of the "from" object at the instant at which the collision is first detected...
A node in the scene graph that can hold any number of CollisionSolids.
Definition: collisionNode.h:33
bool has_interior_point() const
Returns true if the interior point has been specified, false otherwise.
PandaNode * get_into_node() const
Returns the node that contains the CollisionSolid that was collided into.
NodePath get_from_node_path() const
Returns the NodePath that represents the CollisionNode that contains the CollisionSolid that triggere...
This class manages the traversal through the scene graph to detect collisions.
virtual void add_entry(CollisionEntry *entry)
Called between a begin_group() .
const TransformState * get_transform(Thread *current_thread=Thread::get_current_thread()) const
Returns the complete transform object set on this node.
Definition: nodePath.cxx:925
void set_surface_point(const LPoint3 &point)
Stores the point, on the surface of the "into" object, at which a collision is detected.
bool get_respect_prev_transform() const
Returns true if the collision was detected by a CollisionTraverser whose respect_prev_transform flag ...
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:165
void set_surface_normal(const LVector3 &normal)
Stores the surface normal of the "into" object at the point of the intersection.
void reset_collided()
prepare for another collision test
const TransformState * get_prev_transform(Thread *current_thread=Thread::get_current_thread()) const
Returns the transform that has been set as this node&#39;s "previous" position.
Definition: nodePath.cxx:1019
const CollisionSolid * get_from() const
Returns the CollisionSolid pointer for the particular solid that triggered this collision.