Panda3D
|
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 }