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