00001 // Filename: collisionEntry.I 00002 // Created by: drose (16Mar02) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved 00008 // 00009 // All use of this software is subject to the terms of the Panda 3d 00010 // Software license. You should have received a copy of this license 00011 // along with this source code; you will also find a current copy of 00012 // the license at http://www.panda3d.org/license.txt . 00013 // 00014 // To contact the maintainers of this program write to 00015 // panda3d@yahoogroups.com . 00016 // 00017 //////////////////////////////////////////////////////////////////// 00018 00019 00020 //////////////////////////////////////////////////////////////////// 00021 // Function: CollisionEntry::Constructor 00022 // Access: Public 00023 // Description: 00024 //////////////////////////////////////////////////////////////////// 00025 INLINE CollisionEntry:: 00026 CollisionEntry() { 00027 _flags = 0; 00028 } 00029 00030 //////////////////////////////////////////////////////////////////// 00031 // Function: CollisionEntry::get_from 00032 // Access: Public 00033 // Description: Returns the CollisionSolid pointer for the particular 00034 // solid that triggered this collision. 00035 //////////////////////////////////////////////////////////////////// 00036 INLINE const CollisionSolid *CollisionEntry:: 00037 get_from() const { 00038 return _from; 00039 } 00040 00041 //////////////////////////////////////////////////////////////////// 00042 // Function: CollisionEntry::has_into 00043 // Access: Public 00044 // Description: Returns true if the "into" solid is, in fact, a 00045 // CollisionSolid, and its pointer is known (in which 00046 // case get_into() may be called to retrieve it). If 00047 // this returns false, the collision was detected into a 00048 // GeomNode, and there is no CollisionSolid pointer to 00049 // be retrieved. 00050 //////////////////////////////////////////////////////////////////// 00051 INLINE bool CollisionEntry:: 00052 has_into() const { 00053 return (_into != (CollisionSolid *)NULL); 00054 } 00055 00056 //////////////////////////////////////////////////////////////////// 00057 // Function: CollisionEntry::get_into 00058 // Access: Public 00059 // Description: Returns the CollisionSolid pointer for the particular 00060 // solid was collided into. This pointer might be NULL 00061 // if the collision was into a piece of visible 00062 // geometry, instead of a normal CollisionSolid 00063 // collision; see has_into(). 00064 //////////////////////////////////////////////////////////////////// 00065 INLINE const CollisionSolid *CollisionEntry:: 00066 get_into() const { 00067 return _into; 00068 } 00069 00070 //////////////////////////////////////////////////////////////////// 00071 // Function: CollisionEntry::get_from_node 00072 // Access: Public 00073 // Description: Returns the node that contains the CollisionSolid 00074 // that triggered this collision. This will be a node 00075 // that has been added to a CollisionTraverser via 00076 // add_collider(). 00077 //////////////////////////////////////////////////////////////////// 00078 INLINE CollisionNode *CollisionEntry:: 00079 get_from_node() const { 00080 return _from_node; 00081 } 00082 00083 //////////////////////////////////////////////////////////////////// 00084 // Function: CollisionEntry::get_from_space 00085 // Access: Public 00086 // Description: Returns the global coordinate space of the 00087 // CollisionNode returned by get_from_node(), as of the 00088 // time of the collision. This will be equivalent to a 00089 // wrt() from the node to render. 00090 //////////////////////////////////////////////////////////////////// 00091 INLINE const LMatrix4f &CollisionEntry:: 00092 get_from_space() const { 00093 return _from_space; 00094 } 00095 00096 //////////////////////////////////////////////////////////////////// 00097 // Function: CollisionEntry::get_into_node 00098 // Access: Public 00099 // Description: Returns the node that contains the CollisionSolid 00100 // that was collided into. This returns a PandaNode 00101 // pointer instead of something more specific, because 00102 // it might be either a CollisionNode or a GeomNode. 00103 // 00104 // Also see get_into_node_path(). 00105 //////////////////////////////////////////////////////////////////// 00106 INLINE PandaNode *CollisionEntry:: 00107 get_into_node() const { 00108 return _into_node; 00109 } 00110 00111 //////////////////////////////////////////////////////////////////// 00112 // Function: CollisionEntry::get_into_node_path 00113 // Access: Public 00114 // Description: Returns the NodePath that represents the specific 00115 // CollisionNode or GeomNode instance that was collided 00116 // into. This is the same node returned by 00117 // get_into_node(), represented as a NodePath; however, 00118 // it may be more useful because the NodePath can 00119 // resolve the particular instance of the node, if there 00120 // is more than one. 00121 //////////////////////////////////////////////////////////////////// 00122 INLINE const NodePath &CollisionEntry:: 00123 get_into_node_path() const { 00124 return _into_node_path; 00125 } 00126 00127 //////////////////////////////////////////////////////////////////// 00128 // Function: CollisionEntry::get_into_space 00129 // Access: Public 00130 // Description: Returns the global coordinate space of the 00131 // CollisionNode or GeomNode returned by 00132 // get_into_node(), as of the time of the collision. 00133 //////////////////////////////////////////////////////////////////// 00134 INLINE const LMatrix4f &CollisionEntry:: 00135 get_into_space() const { 00136 return _into_space; 00137 } 00138 00139 //////////////////////////////////////////////////////////////////// 00140 // Function: CollisionEntry::get_wrt_space 00141 // Access: Public 00142 // Description: 00143 //////////////////////////////////////////////////////////////////// 00144 INLINE const LMatrix4f &CollisionEntry:: 00145 get_wrt_space() const { 00146 return _wrt_space; 00147 } 00148 00149 //////////////////////////////////////////////////////////////////// 00150 // Function: CollisionEntry::get_inv_wrt_space 00151 // Access: Public 00152 // Description: 00153 //////////////////////////////////////////////////////////////////// 00154 INLINE const LMatrix4f &CollisionEntry:: 00155 get_inv_wrt_space() const { 00156 return _inv_wrt_space; 00157 } 00158 00159 //////////////////////////////////////////////////////////////////// 00160 // Function: CollisionEntry::set_from_velocity 00161 // Access: Public 00162 // Description: Indicates the velocity associated with the "from" 00163 // object, in the object's coordinate space. 00164 //////////////////////////////////////////////////////////////////// 00165 INLINE void CollisionEntry:: 00166 set_from_velocity(const LVector3f &vel) { 00167 _from_velocity = vel; 00168 _flags |= F_has_from_velocity; 00169 } 00170 00171 //////////////////////////////////////////////////////////////////// 00172 // Function: CollisionEntry::has_from_velocity 00173 // Access: Public 00174 // Description: Returns true if the "from" object had an indicated 00175 // velocity, false otherwise. 00176 //////////////////////////////////////////////////////////////////// 00177 INLINE bool CollisionEntry:: 00178 has_from_velocity() const { 00179 return (_flags & F_has_from_velocity) != 0; 00180 } 00181 00182 //////////////////////////////////////////////////////////////////// 00183 // Function: CollisionEntry::get_from_velocity 00184 // Access: Public 00185 // Description: Returns the instantaneous velocity of the "from" 00186 // object, in its own coordinate space. This represents 00187 // the delta between its current position and its 00188 // position last frame. 00189 //////////////////////////////////////////////////////////////////// 00190 INLINE const LVector3f &CollisionEntry:: 00191 get_from_velocity() const { 00192 nassertr(has_from_velocity(), _from_velocity); 00193 return _from_velocity; 00194 } 00195 00196 //////////////////////////////////////////////////////////////////// 00197 // Function: CollisionEntry::set_into_intersection_point 00198 // Access: Public 00199 // Description: 00200 //////////////////////////////////////////////////////////////////// 00201 INLINE void CollisionEntry:: 00202 set_into_intersection_point(const LPoint3f &point) { 00203 _into_intersection_point = point; 00204 _flags |= F_has_into_intersection_point; 00205 } 00206 00207 //////////////////////////////////////////////////////////////////// 00208 // Function: CollisionEntry::has_into_intersection_point 00209 // Access: Public 00210 // Description: Returns true if the detected collision knows its 00211 // intersection point in the coordinate space of the 00212 // collided-into object, false otherwise. 00213 //////////////////////////////////////////////////////////////////// 00214 INLINE bool CollisionEntry:: 00215 has_into_intersection_point() const { 00216 return (_flags & F_has_into_intersection_point) != 0; 00217 } 00218 00219 //////////////////////////////////////////////////////////////////// 00220 // Function: CollisionEntry::get_into_intersection_point 00221 // Access: Public 00222 // Description: Returns the intersection point in the coordinate 00223 // space of the collided-into object. It is an error to 00224 // call this if has_into_intersection_point() returns 00225 // false. 00226 //////////////////////////////////////////////////////////////////// 00227 INLINE const LPoint3f &CollisionEntry:: 00228 get_into_intersection_point() const { 00229 nassertr(has_into_intersection_point(), _into_intersection_point); 00230 return _into_intersection_point; 00231 } 00232 00233 //////////////////////////////////////////////////////////////////// 00234 // Function: CollisionEntry::has_from_intersection_point 00235 // Access: Public 00236 // Description: Returns true if the detected collision knows its 00237 // intersection point in the coordinate space of the 00238 // colliding object, false otherwise. 00239 //////////////////////////////////////////////////////////////////// 00240 INLINE bool CollisionEntry:: 00241 has_from_intersection_point() const { 00242 // Since we derive the from_intersection_point from the 00243 // into_intersection_point, this is really the same question. 00244 return has_into_intersection_point(); 00245 } 00246 00247 //////////////////////////////////////////////////////////////////// 00248 // Function: CollisionEntry::get_from_intersection_point 00249 // Access: Public 00250 // Description: Returns the intersection point in the coordinate 00251 // space of the colliding object. It is an error to 00252 // call this if has_from_intersection_point() returns 00253 // false. 00254 //////////////////////////////////////////////////////////////////// 00255 INLINE LPoint3f CollisionEntry:: 00256 get_from_intersection_point() const { 00257 return get_into_intersection_point() * get_inv_wrt_space(); 00258 } 00259 00260 //////////////////////////////////////////////////////////////////// 00261 // Function: CollisionEntry::set_into_surface_normal 00262 // Access: Public 00263 // Description: 00264 //////////////////////////////////////////////////////////////////// 00265 INLINE void CollisionEntry:: 00266 set_into_surface_normal(const LVector3f &normal) { 00267 _into_surface_normal = normal; 00268 _flags |= F_has_into_surface_normal; 00269 } 00270 00271 //////////////////////////////////////////////////////////////////// 00272 // Function: CollisionEntry::has_into_surface_normal 00273 // Access: Public 00274 // Description: Returns true if the detected collision knows the 00275 // surface normal of the collided-into object at the 00276 // point of the collision, false otherwise. 00277 //////////////////////////////////////////////////////////////////// 00278 INLINE bool CollisionEntry:: 00279 has_into_surface_normal() const { 00280 return (_flags & F_has_into_surface_normal) != 0; 00281 } 00282 00283 //////////////////////////////////////////////////////////////////// 00284 // Function: CollisionEntry::get_into_surface_normal 00285 // Access: Public 00286 // Description: Returns the surface normal of the collided-into 00287 // object at the point of the collision. It is an error 00288 // to call this if has_into_surface_normal() returns 00289 // false. 00290 //////////////////////////////////////////////////////////////////// 00291 INLINE const LVector3f &CollisionEntry:: 00292 get_into_surface_normal() const { 00293 nassertr(has_into_surface_normal(), _into_surface_normal); 00294 return _into_surface_normal; 00295 } 00296 00297 //////////////////////////////////////////////////////////////////// 00298 // Function: CollisionEntry::set_from_surface_normal 00299 // Access: Public 00300 // Description: 00301 //////////////////////////////////////////////////////////////////// 00302 INLINE void CollisionEntry:: 00303 set_from_surface_normal(const LVector3f &normal) { 00304 _from_surface_normal = normal; 00305 _flags |= F_has_from_surface_normal; 00306 } 00307 00308 //////////////////////////////////////////////////////////////////// 00309 // Function: CollisionEntry::has_from_surface_normal 00310 // Access: Public 00311 // Description: Returns true if the detected collision knows the 00312 // surface normal of the collided-into object at the 00313 // point of the collision, false otherwise. 00314 //////////////////////////////////////////////////////////////////// 00315 INLINE bool CollisionEntry:: 00316 has_from_surface_normal() const { 00317 return (_flags & (F_has_into_surface_normal | F_has_from_surface_normal)) != 0; 00318 } 00319 00320 //////////////////////////////////////////////////////////////////// 00321 // Function: CollisionEntry::get_from_surface_normal 00322 // Access: Public 00323 // Description: Returns the surface normal of the collided-into 00324 // object at the point of the collision, in the space of 00325 // the collided-from object. It is an error to call 00326 // this if has_from_surface_normal() returns false. 00327 //////////////////////////////////////////////////////////////////// 00328 INLINE const LVector3f &CollisionEntry:: 00329 get_from_surface_normal() const { 00330 nassertr(has_from_surface_normal(), _from_surface_normal); 00331 if ((_flags & F_has_from_surface_normal) == 0) { 00332 ((CollisionEntry *)this)->compute_from_surface_normal(); 00333 } 00334 return _from_surface_normal; 00335 } 00336 00337 00338 //////////////////////////////////////////////////////////////////// 00339 // Function: CollisionEntry::set_into_depth 00340 // Access: Public 00341 // Description: 00342 //////////////////////////////////////////////////////////////////// 00343 INLINE void CollisionEntry:: 00344 set_into_depth(float depth) { 00345 _into_depth = depth; 00346 _flags |= F_has_into_depth; 00347 } 00348 00349 //////////////////////////////////////////////////////////////////// 00350 // Function: CollisionEntry::has_into_depth 00351 // Access: Public 00352 // Description: Returns true if the collision entry knows how "deep" 00353 // the collision was into the collided-into object; that 00354 // is, how far into the surface of the collided-into 00355 // object the colliding object has penetrated. 00356 //////////////////////////////////////////////////////////////////// 00357 INLINE bool CollisionEntry:: 00358 has_into_depth() const { 00359 return (_flags & F_has_into_depth) != 0; 00360 } 00361 00362 //////////////////////////////////////////////////////////////////// 00363 // Function: CollisionEntry::get_into_depth 00364 // Access: Public 00365 // Description: Returns how "deep" the collision was into the 00366 // collided-into object; that is, how far into the 00367 // surface of the collided-into object the colliding 00368 // object has penetrated. It is an error to call this 00369 // if has_into_depth() returns false. 00370 //////////////////////////////////////////////////////////////////// 00371 INLINE float CollisionEntry:: 00372 get_into_depth() const { 00373 nassertr(has_into_depth(), 0.0); 00374 return _into_depth; 00375 } 00376 00377 //////////////////////////////////////////////////////////////////// 00378 // Function: CollisionEntry::set_from_depth 00379 // Access: Public 00380 // Description: 00381 //////////////////////////////////////////////////////////////////// 00382 INLINE void CollisionEntry:: 00383 set_from_depth(float depth) { 00384 _from_depth = depth; 00385 _flags |= F_has_from_depth; 00386 } 00387 00388 //////////////////////////////////////////////////////////////////// 00389 // Function: CollisionEntry::has_from_depth 00390 // Access: Public 00391 // Description: Returns true if the collision entry knows how "deep" 00392 // the collision was from the collided-from object; that 00393 // is, how far from the surface of the collided-from 00394 // object the colliding object has penetrated. 00395 //////////////////////////////////////////////////////////////////// 00396 INLINE bool CollisionEntry:: 00397 has_from_depth() const { 00398 return (_flags & F_has_from_depth) != 0; 00399 } 00400 00401 //////////////////////////////////////////////////////////////////// 00402 // Function: CollisionEntry::get_from_depth 00403 // Access: Public 00404 // Description: Returns how "deep" the collision was from the 00405 // collided-from object; that is, how far from the 00406 // surface of the collided-from object the colliding 00407 // object has penetrated. It is an error to call this 00408 // if has_from_depth() returns false. 00409 //////////////////////////////////////////////////////////////////// 00410 INLINE float CollisionEntry:: 00411 get_from_depth() const { 00412 nassertr(has_from_depth(), 0.0); 00413 return _from_depth; 00414 } 00415 00416 //////////////////////////////////////////////////////////////////// 00417 // Function: CollisionEntry::test_intersection 00418 // Access: Private 00419 // Description: This is intended to be called only by the 00420 // CollisionTraverser. It requests the CollisionEntry 00421 // to start the intersection test between the from and 00422 // into solids stored within it, passing the result (if 00423 // positive) to the indicated CollisionHandler. 00424 //////////////////////////////////////////////////////////////////// 00425 INLINE void CollisionEntry:: 00426 test_intersection(CollisionHandler *record, 00427 const CollisionTraverser *trav) const { 00428 PT(CollisionEntry) result = get_from()->test_intersection(*this); 00429 #ifdef DO_COLLISION_RECORDING 00430 if (trav->has_recorder()) { 00431 if (result != (CollisionEntry *)NULL) { 00432 trav->get_recorder()->collision_tested(*result, true); 00433 } else { 00434 trav->get_recorder()->collision_tested(*this, false); 00435 } 00436 } 00437 #endif // DO_COLLISION_RECORDING 00438 if (result != (CollisionEntry *)NULL) { 00439 record->add_entry(result); 00440 } 00441 }