Panda3D
 All Classes Functions Variables Enumerations
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(PN_stdfloat t) {
00134   nassertv(!cnan(t));
00135   _t = t;
00136 }
00137 
00138 ////////////////////////////////////////////////////////////////////
00139 //     Function: CollisionEntry::set_t
00140 //       Access: Published
00141 //  Description: returns time value for this collision relative to
00142 //               other CollisionEntries
00143 ////////////////////////////////////////////////////////////////////
00144 INLINE PN_stdfloat CollisionEntry::
00145 get_t() const {
00146   return _t;
00147 }
00148 
00149 ////////////////////////////////////////////////////////////////////
00150 //     Function: CollisionEntry::collided
00151 //       Access: Published
00152 //  Description: returns true if this represents an actual collision
00153 //               as opposed to a potential collision, needed for
00154 //               iterative collision resolution where path of
00155 //               collider changes mid-frame
00156 ////////////////////////////////////////////////////////////////////
00157 INLINE bool CollisionEntry::
00158 collided() const {
00159   return ((0.f <= _t) && (_t <= 1.f));
00160 }
00161 
00162 ////////////////////////////////////////////////////////////////////
00163 //     Function: CollisionEntry::reset_collided
00164 //       Access: Published
00165 //  Description: prepare for another collision test
00166 ////////////////////////////////////////////////////////////////////
00167 INLINE void CollisionEntry::
00168 reset_collided() {
00169   _t = 2.f;
00170 }
00171 
00172 ////////////////////////////////////////////////////////////////////
00173 //     Function: CollisionEntry::get_respect_prev_transform
00174 //       Access: Published
00175 //  Description: Returns true if the collision was detected by a
00176 //               CollisionTraverser whose respect_prev_transform
00177 //               flag was set true, meaning we should consider motion
00178 //               significant in evaluating collisions.
00179 ////////////////////////////////////////////////////////////////////
00180 INLINE bool CollisionEntry::
00181 get_respect_prev_transform() const {
00182   return (_flags & F_respect_prev_transform) != 0;
00183 }
00184 
00185 
00186 ////////////////////////////////////////////////////////////////////
00187 //     Function: CollisionEntry::set_surface_point
00188 //       Access: Published
00189 //  Description: Stores the point, on the surface of the "into"
00190 //               object, at which a collision is detected.
00191 //
00192 //               This point is specified in the coordinate space of
00193 //               the "into" object.
00194 ////////////////////////////////////////////////////////////////////
00195 INLINE void CollisionEntry::
00196 set_surface_point(const LPoint3 &point) {
00197   nassertv(!point.is_nan());
00198   _surface_point = point;
00199   _flags |= F_has_surface_point;
00200 }
00201 
00202 ////////////////////////////////////////////////////////////////////
00203 //     Function: CollisionEntry::set_surface_normal
00204 //       Access: Published
00205 //  Description: Stores the surface normal of the "into" object at the
00206 //               point of the intersection.
00207 //
00208 //               This normal is specified in the coordinate space of
00209 //               the "into" object.
00210 ////////////////////////////////////////////////////////////////////
00211 INLINE void CollisionEntry::
00212 set_surface_normal(const LVector3 &normal) {
00213   nassertv(!normal.is_nan());
00214   _surface_normal = normal;
00215   _flags |= F_has_surface_normal;
00216 }
00217 
00218 ////////////////////////////////////////////////////////////////////
00219 //     Function: CollisionEntry::set_interior_point
00220 //       Access: Published
00221 //  Description: Stores the point, within the interior of the "into"
00222 //               object, which represents the depth to which the
00223 //               "from" object has penetrated.  This can also be
00224 //               described as the intersection point on the surface of
00225 //               the "from" object (which is inside the "into"
00226 //               object).
00227 //
00228 //               This point is specified in the coordinate space of
00229 //               the "into" object.
00230 ////////////////////////////////////////////////////////////////////
00231 INLINE void CollisionEntry::
00232 set_interior_point(const LPoint3 &point) {
00233   nassertv(!point.is_nan());
00234   _interior_point = point;
00235   _flags |= F_has_interior_point;
00236 }
00237 
00238 ////////////////////////////////////////////////////////////////////
00239 //     Function: CollisionEntry::has_surface_point
00240 //       Access: Published
00241 //  Description: Returns true if the surface point has been specified,
00242 //               false otherwise.  See get_surface_point().  Some
00243 //               types of collisions may not compute the surface
00244 //               point.
00245 ////////////////////////////////////////////////////////////////////
00246 INLINE bool CollisionEntry::
00247 has_surface_point() const {
00248   return (_flags & F_has_surface_point) != 0;
00249 }
00250 
00251 ////////////////////////////////////////////////////////////////////
00252 //     Function: CollisionEntry::has_surface_normal
00253 //       Access: Published
00254 //  Description: Returns true if the surface normal has been specified,
00255 //               false otherwise.  See get_surface_normal().  Some
00256 //               types of collisions may not compute the surface
00257 //               normal.
00258 ////////////////////////////////////////////////////////////////////
00259 INLINE bool CollisionEntry::
00260 has_surface_normal() const {
00261   return (_flags & F_has_surface_normal) != 0;
00262 }
00263 
00264 ////////////////////////////////////////////////////////////////////
00265 //     Function: CollisionEntry::has_interior_point
00266 //       Access: Published
00267 //  Description: Returns true if the interior point has been specified,
00268 //               false otherwise.  See get_interior_point().  Some
00269 //               types of collisions may not compute the interior
00270 //               point.
00271 ////////////////////////////////////////////////////////////////////
00272 INLINE bool CollisionEntry::
00273 has_interior_point() const {
00274   return (_flags & F_has_interior_point) != 0;
00275 }
00276 
00277 ////////////////////////////////////////////////////////////////////
00278 //     Function: CollisionEntry::set_contact_pos
00279 //       Access: Published
00280 //  Description: Stores the position of the "from" object at the
00281 //               instant at which the collision is first detected.
00282 //
00283 //               This position is specified in the coordinate space of
00284 //               the "into" object.
00285 ////////////////////////////////////////////////////////////////////
00286 INLINE void CollisionEntry::
00287 set_contact_pos(const LPoint3 &pos) {
00288   nassertv(!pos.is_nan());
00289   _contact_pos = pos;
00290   _flags |= F_has_contact_pos;
00291 }
00292 
00293 ////////////////////////////////////////////////////////////////////
00294 //     Function: CollisionEntry::set_contact_normal
00295 //       Access: Published
00296 //  Description: Stores the surface normal of the "into" object at the
00297 //               contact pos.
00298 //
00299 //               This normal is specified in the coordinate space of
00300 //               the "into" object.
00301 ////////////////////////////////////////////////////////////////////
00302 INLINE void CollisionEntry::
00303 set_contact_normal(const LVector3 &normal) {
00304   nassertv(!normal.is_nan());
00305   _contact_normal = normal;
00306   _flags |= F_has_contact_normal;
00307 }
00308 
00309 ////////////////////////////////////////////////////////////////////
00310 //     Function: CollisionEntry::has_contact_pos
00311 //       Access: Published
00312 //  Description: Returns true if the contact position has been specified,
00313 //               false otherwise.  See get_contact_pos().  Some
00314 //               types of collisions may not compute the contact
00315 //               pos.
00316 ////////////////////////////////////////////////////////////////////
00317 INLINE bool CollisionEntry::
00318 has_contact_pos() const {
00319   return (_flags & F_has_contact_pos) != 0;
00320 }
00321 
00322 ////////////////////////////////////////////////////////////////////
00323 //     Function: CollisionEntry::has_contact_normal
00324 //       Access: Published
00325 //  Description: Returns true if the contact normal has been specified,
00326 //               false otherwise.  See get_contact_normal().  Some
00327 //               types of collisions may not compute the contact
00328 //               normal.
00329 ////////////////////////////////////////////////////////////////////
00330 INLINE bool CollisionEntry::
00331 has_contact_normal() const {
00332   return (_flags & F_has_contact_normal) != 0;
00333 }
00334 
00335 ////////////////////////////////////////////////////////////////////
00336 //     Function: CollisionEntry::get_wrt_space
00337 //       Access: Public
00338 //  Description: Returns the relative transform of the from node as
00339 //               seen from the into node.
00340 ////////////////////////////////////////////////////////////////////
00341 INLINE CPT(TransformState) CollisionEntry::
00342 get_wrt_space() const {
00343   return _from_node_path.get_transform(_into_node_path);
00344 }
00345 
00346 ////////////////////////////////////////////////////////////////////
00347 //     Function: CollisionEntry::get_inv_wrt_space
00348 //       Access: Public
00349 //  Description: Returns the relative transform of the into node as
00350 //               seen from the from node.
00351 ////////////////////////////////////////////////////////////////////
00352 INLINE CPT(TransformState) CollisionEntry::
00353 get_inv_wrt_space() const {
00354   return _into_node_path.get_transform(_from_node_path);
00355 }
00356 
00357 ////////////////////////////////////////////////////////////////////
00358 //     Function: CollisionEntry::get_wrt_prev_space
00359 //       Access: Public
00360 //  Description: Returns the relative transform of the from node as
00361 //               seen from the into node, as of the previous frame
00362 //               (according to set_prev_transform(), set_fluid_pos(),
00363 //               etc.)
00364 ////////////////////////////////////////////////////////////////////
00365 INLINE CPT(TransformState) CollisionEntry::
00366 get_wrt_prev_space() const {
00367   if (get_respect_prev_transform()) {
00368     return _from_node_path.get_prev_transform(_into_node_path);
00369   } else {
00370     return get_wrt_space();
00371   }
00372 }
00373 
00374 ////////////////////////////////////////////////////////////////////
00375 //     Function: CollisionEntry::get_wrt_mat
00376 //       Access: Public
00377 //  Description: Returns the relative transform of the from node as
00378 //               seen from the into node.
00379 ////////////////////////////////////////////////////////////////////
00380 INLINE const LMatrix4 &CollisionEntry::
00381 get_wrt_mat() const {
00382   return get_wrt_space()->get_mat();
00383 }
00384 
00385 ////////////////////////////////////////////////////////////////////
00386 //     Function: CollisionEntry::get_inv_wrt_mat
00387 //       Access: Public
00388 //  Description: Returns the relative transform of the into node as
00389 //               seen from the from node.
00390 ////////////////////////////////////////////////////////////////////
00391 INLINE const LMatrix4 &CollisionEntry::
00392 get_inv_wrt_mat() const {
00393   return get_inv_wrt_space()->get_mat();
00394 }
00395 
00396 ////////////////////////////////////////////////////////////////////
00397 //     Function: CollisionEntry::get_wrt_prev_mat
00398 //       Access: Public
00399 //  Description: Returns the relative transform of the from node as
00400 //               seen from the into node, as of the previous frame
00401 //               (according to set_prev_transform(), set_fluid_pos(),
00402 //               etc.)
00403 ////////////////////////////////////////////////////////////////////
00404 INLINE const LMatrix4 &CollisionEntry::
00405 get_wrt_prev_mat() const {
00406   return get_wrt_prev_space()->get_mat();
00407 }
00408 
00409 ////////////////////////////////////////////////////////////////////
00410 //     Function: CollisionEntry::get_into_clip_planes
00411 //       Access: Public
00412 //  Description: Returns the ClipPlaneAttrib, if any, that is applied
00413 //               to the into_node_path, or NULL if there is no clip
00414 //               plane in effect.
00415 ////////////////////////////////////////////////////////////////////
00416 INLINE const ClipPlaneAttrib *CollisionEntry::
00417 get_into_clip_planes() const {
00418   if ((_flags & F_checked_clip_planes) == 0) {
00419     ((CollisionEntry *)this)->check_clip_planes();
00420   }
00421   return _into_clip_planes;
00422 }
00423 
00424 ////////////////////////////////////////////////////////////////////
00425 //     Function: CollisionEntry::test_intersection
00426 //       Access: Private
00427 //  Description: This is intended to be called only by the
00428 //               CollisionTraverser.  It requests the CollisionEntry
00429 //               to start the intersection test between the from and
00430 //               into solids stored within it, passing the result (if
00431 //               positive) to the indicated CollisionHandler.
00432 ////////////////////////////////////////////////////////////////////
00433 INLINE void CollisionEntry::
00434 test_intersection(CollisionHandler *record, 
00435                   const CollisionTraverser *trav) const {
00436   PT(CollisionEntry) result = get_from()->test_intersection(*this);
00437 #ifdef DO_COLLISION_RECORDING
00438   if (trav->has_recorder()) {
00439     if (result != (CollisionEntry *)NULL) {
00440       trav->get_recorder()->collision_tested(*result, true);
00441     } else {
00442       trav->get_recorder()->collision_tested(*this, false);
00443     }
00444   }
00445 #endif  // DO_COLLISION_RECORDING
00446 #ifdef DO_PSTATS
00447   ((CollisionSolid *)get_into())->get_test_pcollector().add_level(1);
00448 #endif  // DO_PSTATS
00449   // if there was no collision detected but the handler wants to know about all
00450   // potential collisions, create a "didn't collide" collision entry for it
00451   if (record->wants_all_potential_collidees() && result == (CollisionEntry *)NULL) {
00452     result = new CollisionEntry(*this);
00453     result->reset_collided();
00454   }
00455   if (result != (CollisionEntry *)NULL) {
00456     record->add_entry(result);
00457   }
00458 }
00459 
00460 INLINE ostream &
00461 operator << (ostream &out, const CollisionEntry &entry) {
00462   entry.output(out);
00463   return out;
00464 }
 All Classes Functions Variables Enumerations