Panda3D

collisionEntry.I

00001 // Filename: collisionEntry.I
00002 // Created by:  drose (16Mar02)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 
00016 ////////////////////////////////////////////////////////////////////
00017 //     Function: CollisionEntry::Constructor
00018 //       Access: Published
00019 //  Description:
00020 ////////////////////////////////////////////////////////////////////
00021 INLINE CollisionEntry::
00022 CollisionEntry() {
00023   _flags = 0;
00024   // > 1. means collision didn't happen
00025   _t = 2.f;
00026 }
00027 
00028 ////////////////////////////////////////////////////////////////////
00029 //     Function: CollisionEntry::get_from
00030 //       Access: Published
00031 //  Description: Returns the CollisionSolid pointer for the particular
00032 //               solid that triggered this collision.
00033 ////////////////////////////////////////////////////////////////////
00034 INLINE const CollisionSolid *CollisionEntry::
00035 get_from() const {
00036   return _from;
00037 }
00038 
00039 ////////////////////////////////////////////////////////////////////
00040 //     Function: CollisionEntry::has_into
00041 //       Access: Published
00042 //  Description: Returns true if the "into" solid is, in fact, a
00043 //               CollisionSolid, and its pointer is known (in which
00044 //               case get_into() may be called to retrieve it).  If
00045 //               this returns false, the collision was detected into a
00046 //               GeomNode, and there is no CollisionSolid pointer to
00047 //               be retrieved.
00048 ////////////////////////////////////////////////////////////////////
00049 INLINE bool CollisionEntry::
00050 has_into() const {
00051   return (_into != (CollisionSolid *)NULL);
00052 }
00053 
00054 ////////////////////////////////////////////////////////////////////
00055 //     Function: CollisionEntry::get_into
00056 //       Access: Published
00057 //  Description: Returns the CollisionSolid pointer for the particular
00058 //               solid was collided into.  This pointer might be NULL
00059 //               if the collision was into a piece of visible
00060 //               geometry, instead of a normal CollisionSolid
00061 //               collision; see has_into().
00062 ////////////////////////////////////////////////////////////////////
00063 INLINE const CollisionSolid *CollisionEntry::
00064 get_into() const {
00065   return _into;
00066 }
00067 
00068 ////////////////////////////////////////////////////////////////////
00069 //     Function: CollisionEntry::get_from_node
00070 //       Access: Published
00071 //  Description: Returns the node that contains the CollisionSolid
00072 //               that triggered this collision.  This will be a node
00073 //               that has been added to a CollisionTraverser via
00074 //               add_collider().
00075 ////////////////////////////////////////////////////////////////////
00076 INLINE CollisionNode *CollisionEntry::
00077 get_from_node() const {
00078   return _from_node;
00079 }
00080 
00081 ////////////////////////////////////////////////////////////////////
00082 //     Function: CollisionEntry::get_into_node
00083 //       Access: Published
00084 //  Description: Returns the node that contains the CollisionSolid
00085 //               that was collided into.  This returns a PandaNode
00086 //               pointer instead of something more specific, because
00087 //               it might be either a CollisionNode or a GeomNode.
00088 //
00089 //               Also see get_into_node_path().
00090 ////////////////////////////////////////////////////////////////////
00091 INLINE PandaNode *CollisionEntry::
00092 get_into_node() const {
00093   return _into_node;
00094 }
00095 
00096 ////////////////////////////////////////////////////////////////////
00097 //     Function: CollisionEntry::get_from_node_path
00098 //       Access: Published
00099 //  Description: Returns the NodePath that represents the
00100 //               CollisionNode that contains the CollisionSolid that
00101 //               triggered this collision.  This will be a NodePath
00102 //               that has been added to a CollisionTraverser via
00103 //               add_collider().
00104 ////////////////////////////////////////////////////////////////////
00105 INLINE NodePath CollisionEntry::
00106 get_from_node_path() const {
00107   return _from_node_path;
00108 }
00109 
00110 ////////////////////////////////////////////////////////////////////
00111 //     Function: CollisionEntry::get_into_node_path
00112 //       Access: Published
00113 //  Description: Returns the NodePath that represents the specific
00114 //               CollisionNode or GeomNode instance that was collided
00115 //               into.  This is the same node returned by
00116 //               get_into_node(), represented as a NodePath; however,
00117 //               it may be more useful because the NodePath can
00118 //               resolve the particular instance of the node, if there
00119 //               is more than one.
00120 ////////////////////////////////////////////////////////////////////
00121 INLINE NodePath CollisionEntry::
00122 get_into_node_path() const {
00123   return _into_node_path;
00124 }
00125 
00126 ////////////////////////////////////////////////////////////////////
00127 //     Function: CollisionEntry::set_t
00128 //       Access: Published
00129 //  Description: Sets a time value for this collision relative to
00130 //               other CollisionEntries
00131 ////////////////////////////////////////////////////////////////////
00132 INLINE void CollisionEntry::
00133 set_t(float t) {
00134   _t = t;
00135 }
00136 
00137 ////////////////////////////////////////////////////////////////////
00138 //     Function: CollisionEntry::set_t
00139 //       Access: Published
00140 //  Description: returns time value for this collision relative to
00141 //               other CollisionEntries
00142 ////////////////////////////////////////////////////////////////////
00143 INLINE float CollisionEntry::
00144 get_t() const {
00145   return _t;
00146 }
00147 
00148 ////////////////////////////////////////////////////////////////////
00149 //     Function: CollisionEntry::collided
00150 //       Access: Published
00151 //  Description: returns true if this represents an actual collision
00152 //               as opposed to a potential collision, needed for
00153 //               iterative collision resolution where path of
00154 //               collider changes mid-frame
00155 ////////////////////////////////////////////////////////////////////
00156 INLINE bool CollisionEntry::
00157 collided() const {
00158   return ((0.f <= _t) && (_t <= 1.f));
00159 }
00160 
00161 ////////////////////////////////////////////////////////////////////
00162 //     Function: CollisionEntry::reset_collided
00163 //       Access: Published
00164 //  Description: prepare for another collision test
00165 ////////////////////////////////////////////////////////////////////
00166 INLINE void CollisionEntry::
00167 reset_collided() {
00168   _t = 2.f;
00169 }
00170 
00171 ////////////////////////////////////////////////////////////////////
00172 //     Function: CollisionEntry::get_respect_prev_transform
00173 //       Access: Published
00174 //  Description: Returns true if the collision was detected by a
00175 //               CollisionTraverser whose respect_prev_transform
00176 //               flag was set true, meaning we should consider motion
00177 //               significant in evaluating collisions.
00178 ////////////////////////////////////////////////////////////////////
00179 INLINE bool CollisionEntry::
00180 get_respect_prev_transform() const {
00181   return (_flags & F_respect_prev_transform) != 0;
00182 }
00183 
00184 
00185 ////////////////////////////////////////////////////////////////////
00186 //     Function: CollisionEntry::set_surface_point
00187 //       Access: Published
00188 //  Description: Stores the point, on the surface of the "into"
00189 //               object, at which a collision is detected.
00190 //
00191 //               This point is specified in the coordinate space of
00192 //               the "into" object.
00193 ////////////////////////////////////////////////////////////////////
00194 INLINE void CollisionEntry::
00195 set_surface_point(const LPoint3f &point) {
00196   _surface_point = point;
00197   _flags |= F_has_surface_point;
00198 }
00199 
00200 ////////////////////////////////////////////////////////////////////
00201 //     Function: CollisionEntry::set_surface_normal
00202 //       Access: Published
00203 //  Description: Stores the surface normal of the "into" object at the
00204 //               point of the intersection.
00205 //
00206 //               This normal is specified in the coordinate space of
00207 //               the "into" object.
00208 ////////////////////////////////////////////////////////////////////
00209 INLINE void CollisionEntry::
00210 set_surface_normal(const LVector3f &normal) {
00211   _surface_normal = normal;
00212   _flags |= F_has_surface_normal;
00213 }
00214 
00215 ////////////////////////////////////////////////////////////////////
00216 //     Function: CollisionEntry::set_interior_point
00217 //       Access: Published
00218 //  Description: Stores the point, within the interior of the "into"
00219 //               object, which represents the depth to which the
00220 //               "from" object has penetrated.  This can also be
00221 //               described as the intersection point on the surface of
00222 //               the "from" object (which is inside the "into"
00223 //               object).
00224 //
00225 //               This point is specified in the coordinate space of
00226 //               the "into" object.
00227 ////////////////////////////////////////////////////////////////////
00228 INLINE void CollisionEntry::
00229 set_interior_point(const LPoint3f &point) {
00230   _interior_point = point;
00231   _flags |= F_has_interior_point;
00232 }
00233 
00234 ////////////////////////////////////////////////////////////////////
00235 //     Function: CollisionEntry::has_surface_point
00236 //       Access: Published
00237 //  Description: Returns true if the surface point has been specified,
00238 //               false otherwise.  See get_surface_point().  Some
00239 //               types of collisions may not compute the surface
00240 //               point.
00241 ////////////////////////////////////////////////////////////////////
00242 INLINE bool CollisionEntry::
00243 has_surface_point() const {
00244   return (_flags & F_has_surface_point) != 0;
00245 }
00246 
00247 ////////////////////////////////////////////////////////////////////
00248 //     Function: CollisionEntry::has_surface_normal
00249 //       Access: Published
00250 //  Description: Returns true if the surface normal has been specified,
00251 //               false otherwise.  See get_surface_normal().  Some
00252 //               types of collisions may not compute the surface
00253 //               normal.
00254 ////////////////////////////////////////////////////////////////////
00255 INLINE bool CollisionEntry::
00256 has_surface_normal() const {
00257   return (_flags & F_has_surface_normal) != 0;
00258 }
00259 
00260 ////////////////////////////////////////////////////////////////////
00261 //     Function: CollisionEntry::has_interior_point
00262 //       Access: Published
00263 //  Description: Returns true if the interior point has been specified,
00264 //               false otherwise.  See get_interior_point().  Some
00265 //               types of collisions may not compute the interior
00266 //               point.
00267 ////////////////////////////////////////////////////////////////////
00268 INLINE bool CollisionEntry::
00269 has_interior_point() const {
00270   return (_flags & F_has_interior_point) != 0;
00271 }
00272 
00273 ////////////////////////////////////////////////////////////////////
00274 //     Function: CollisionEntry::set_contact_pos
00275 //       Access: Published
00276 //  Description: Stores the position of the "from" object at the
00277 //               instant at which the collision is first detected.
00278 //
00279 //               This position is specified in the coordinate space of
00280 //               the "into" object.
00281 ////////////////////////////////////////////////////////////////////
00282 INLINE void CollisionEntry::
00283 set_contact_pos(const LPoint3f &pos) {
00284   _contact_pos = pos;
00285   _flags |= F_has_contact_pos;
00286 }
00287 
00288 ////////////////////////////////////////////////////////////////////
00289 //     Function: CollisionEntry::set_contact_normal
00290 //       Access: Published
00291 //  Description: Stores the surface normal of the "into" object at the
00292 //               contact pos.
00293 //
00294 //               This normal is specified in the coordinate space of
00295 //               the "into" object.
00296 ////////////////////////////////////////////////////////////////////
00297 INLINE void CollisionEntry::
00298 set_contact_normal(const LVector3f &normal) {
00299   _contact_normal = normal;
00300   _flags |= F_has_contact_normal;
00301 }
00302 
00303 ////////////////////////////////////////////////////////////////////
00304 //     Function: CollisionEntry::has_contact_pos
00305 //       Access: Published
00306 //  Description: Returns true if the contact position has been specified,
00307 //               false otherwise.  See get_contact_pos().  Some
00308 //               types of collisions may not compute the contact
00309 //               pos.
00310 ////////////////////////////////////////////////////////////////////
00311 INLINE bool CollisionEntry::
00312 has_contact_pos() const {
00313   return (_flags & F_has_contact_pos) != 0;
00314 }
00315 
00316 ////////////////////////////////////////////////////////////////////
00317 //     Function: CollisionEntry::has_contact_normal
00318 //       Access: Published
00319 //  Description: Returns true if the contact normal has been specified,
00320 //               false otherwise.  See get_contact_normal().  Some
00321 //               types of collisions may not compute the contact
00322 //               normal.
00323 ////////////////////////////////////////////////////////////////////
00324 INLINE bool CollisionEntry::
00325 has_contact_normal() const {
00326   return (_flags & F_has_contact_normal) != 0;
00327 }
00328 
00329 ////////////////////////////////////////////////////////////////////
00330 //     Function: CollisionEntry::get_wrt_space
00331 //       Access: Public
00332 //  Description: Returns the relative transform of the from node as
00333 //               seen from the into node.
00334 ////////////////////////////////////////////////////////////////////
00335 INLINE CPT(TransformState) CollisionEntry::
00336 get_wrt_space() const {
00337   return _from_node_path.get_transform(_into_node_path);
00338 }
00339 
00340 ////////////////////////////////////////////////////////////////////
00341 //     Function: CollisionEntry::get_inv_wrt_space
00342 //       Access: Public
00343 //  Description: Returns the relative transform of the into node as
00344 //               seen from the from node.
00345 ////////////////////////////////////////////////////////////////////
00346 INLINE CPT(TransformState) CollisionEntry::
00347 get_inv_wrt_space() const {
00348   return _into_node_path.get_transform(_from_node_path);
00349 }
00350 
00351 ////////////////////////////////////////////////////////////////////
00352 //     Function: CollisionEntry::get_wrt_prev_space
00353 //       Access: Public
00354 //  Description: Returns the relative transform of the from node as
00355 //               seen from the into node, as of the previous frame
00356 //               (according to set_prev_transform(), set_fluid_pos(),
00357 //               etc.)
00358 ////////////////////////////////////////////////////////////////////
00359 INLINE CPT(TransformState) CollisionEntry::
00360 get_wrt_prev_space() const {
00361   if (get_respect_prev_transform()) {
00362     return _from_node_path.get_prev_transform(_into_node_path);
00363   } else {
00364     return get_wrt_space();
00365   }
00366 }
00367 
00368 ////////////////////////////////////////////////////////////////////
00369 //     Function: CollisionEntry::get_wrt_mat
00370 //       Access: Public
00371 //  Description: Returns the relative transform of the from node as
00372 //               seen from the into node.
00373 ////////////////////////////////////////////////////////////////////
00374 INLINE const LMatrix4f &CollisionEntry::
00375 get_wrt_mat() const {
00376   return get_wrt_space()->get_mat();
00377 }
00378 
00379 ////////////////////////////////////////////////////////////////////
00380 //     Function: CollisionEntry::get_inv_wrt_mat
00381 //       Access: Public
00382 //  Description: Returns the relative transform of the into node as
00383 //               seen from the from node.
00384 ////////////////////////////////////////////////////////////////////
00385 INLINE const LMatrix4f &CollisionEntry::
00386 get_inv_wrt_mat() const {
00387   return get_inv_wrt_space()->get_mat();
00388 }
00389 
00390 ////////////////////////////////////////////////////////////////////
00391 //     Function: CollisionEntry::get_wrt_prev_mat
00392 //       Access: Public
00393 //  Description: Returns the relative transform of the from node as
00394 //               seen from the into node, as of the previous frame
00395 //               (according to set_prev_transform(), set_fluid_pos(),
00396 //               etc.)
00397 ////////////////////////////////////////////////////////////////////
00398 INLINE const LMatrix4f &CollisionEntry::
00399 get_wrt_prev_mat() const {
00400   return get_wrt_prev_space()->get_mat();
00401 }
00402 
00403 ////////////////////////////////////////////////////////////////////
00404 //     Function: CollisionEntry::get_into_clip_planes
00405 //       Access: Public
00406 //  Description: Returns the ClipPlaneAttrib, if any, that is applied
00407 //               to the into_node_path, or NULL if there is no clip
00408 //               plane in effect.
00409 ////////////////////////////////////////////////////////////////////
00410 INLINE const ClipPlaneAttrib *CollisionEntry::
00411 get_into_clip_planes() const {
00412   if ((_flags & F_checked_clip_planes) == 0) {
00413     ((CollisionEntry *)this)->check_clip_planes();
00414   }
00415   return _into_clip_planes;
00416 }
00417 
00418 ////////////////////////////////////////////////////////////////////
00419 //     Function: CollisionEntry::test_intersection
00420 //       Access: Private
00421 //  Description: This is intended to be called only by the
00422 //               CollisionTraverser.  It requests the CollisionEntry
00423 //               to start the intersection test between the from and
00424 //               into solids stored within it, passing the result (if
00425 //               positive) to the indicated CollisionHandler.
00426 ////////////////////////////////////////////////////////////////////
00427 INLINE void CollisionEntry::
00428 test_intersection(CollisionHandler *record, 
00429                   const CollisionTraverser *trav) const {
00430   PT(CollisionEntry) result = get_from()->test_intersection(*this);
00431 #ifdef DO_COLLISION_RECORDING
00432   if (trav->has_recorder()) {
00433     if (result != (CollisionEntry *)NULL) {
00434       trav->get_recorder()->collision_tested(*result, true);
00435     } else {
00436       trav->get_recorder()->collision_tested(*this, false);
00437     }
00438   }
00439 #endif  // DO_COLLISION_RECORDING
00440 #ifdef DO_PSTATS
00441   ((CollisionSolid *)get_into())->get_test_pcollector().add_level(1);
00442 #endif  // DO_PSTATS
00443   // if there was no collision detected but the handler wants to know about all
00444   // potential collisions, create a "didn't collide" collision entry for it
00445   if (record->wants_all_potential_collidees() && result == (CollisionEntry *)NULL) {
00446     result = new CollisionEntry(*this);
00447     result->reset_collided();
00448   }
00449   if (result != (CollisionEntry *)NULL) {
00450     record->add_entry(result);
00451   }
00452 }
00453 
00454 INLINE ostream &
00455 operator << (ostream &out, const CollisionEntry &entry) {
00456   entry.output(out);
00457   return out;
00458 }
 All Classes Functions Variables Enumerations