![]() |
TAPs 0.7.7.3
|
00001 /****************************************************************************** 00002 TAPsBVHNode.hpp 00003 00004 BVHNode class is for a N Boundary Volume Hierarchy Node. 00005 00006 SUKITTI PUNAK (01/17/2006) 00007 UPDATE (10/14/2009) 00008 ******************************************************************************/ 00009 #include "TAPsBVHNode.hpp" 00010 // Using Inclusion Model (i.e. definitions are included in declarations) 00011 // (this name.cpp is included in name.hpp) 00012 // Each friend is defined directly inside its declaration. 00013 00014 BEGIN_NAMESPACE_TAPs 00015 //============================================================================= 00016 // Constructor(s) and Destructor 00017 //----------------------------------------------------------------------------- 00018 template <typename T> 00019 BVHNode<T>::BVHNode ( 00020 Enum::CD type, 00021 int id, 00022 BVHNode<T> * parent, 00023 BVHNode<T> ** children 00024 ) 00025 : m_eType( type ), 00026 //m_bIsLeaf( false ), 00027 m_iID( id ), 00028 m_pParent( parent ) 00029 00030 #ifdef TAPs_ENABLE_COLLISION_DETECTION_ON_OFF_STATUS 00031 , m_bOnForColDet( true ) 00032 #endif//TAPs_ENABLE_COLLISION_DETECTION_ON_OFF_STATUS 00033 00034 #ifdef TAPs_DEBUG_COLLISION_DETECTION 00035 , flag( false ) 00036 #endif//TAPs_DEBUG_COLLISION_DETECTION 00037 { 00038 InitChildren( type, children ); 00039 00040 //bDraw = false; // DEBUG 00041 } 00042 //----------------------------------------------------------------------------- 00043 template <typename T> 00044 BVHNode<T>::BVHNode ( 00045 int numOfChildren, 00046 Enum::CD type, 00047 int id, 00048 BVHNode<T> * parent, 00049 BVHNode<T> ** children 00050 ) 00051 : m_ieType( type ), 00052 //m_bIsLeaf( false ), 00053 m_iID( id ), 00054 m_pParent( parent ), 00055 m_iN( numOfChildren ) 00056 00057 #ifdef TAPs_ENABLE_COLLISION_DETECTION_ON_OFF_STATUS 00058 , m_bOnForColDet( true ) 00059 #endif//TAPs_ENABLE_COLLISION_DETECTION_ON_OFF_STATUS 00060 00061 #ifdef TAPs_DEBUG_COLLISION_DETECTION 00062 , flag( false ) 00063 #endif//TAPs_DEBUG_COLLISION_DETECTION 00064 { 00065 switch ( type ) { 00066 case Enum::BVH_NODE_GENERIC_SPHERE: 00067 case Enum::BVH_NODE_GENERIC_AABB: 00068 case Enum::BVH_NODE_GENERIC_OBB: 00069 InitChildren( m_iN, children ); 00070 break; 00071 default: 00072 std::cout << "ERROR: BVHNode<T> Constructor#2!" << std::endl; 00073 assert( false ); 00074 break; 00075 } 00076 00077 //bDraw = false; // DEBUG 00078 } 00079 //----------------------------------------------------------------------------- 00080 template <typename T> 00081 BVHNode<T>::BVHNode ( 00082 Enum::CD type, 00083 int id, 00084 BVHNode<T> * parent, 00085 Vector3<T> const & center, 00086 Vector3<T> const & U, 00087 Vector3<T> const & V, 00088 Vector3<T> const & W 00089 ) 00090 : m_eType( type ), 00091 //m_bIsLeaf( false ), 00092 m_iID( id ), 00093 m_pParent( parent ), 00094 m_vCenter( center ), 00095 m_vU( U ), 00096 m_vV( V ), 00097 m_vW( W ) 00098 00099 #ifdef TAPs_ENABLE_COLLISION_DETECTION_ON_OFF_STATUS 00100 , m_bOnForColDet( true ) 00101 #endif//TAPs_ENABLE_COLLISION_DETECTION_ON_OFF_STATUS 00102 00103 #ifdef TAPs_DEBUG_COLLISION_DETECTION 00104 , flag( false ) 00105 #endif//TAPs_DEBUG_COLLISION_DETECTION 00106 { 00107 InitChildren( type, NULL ); 00108 00109 //bDraw = false; // DEBUG 00110 } 00111 //----------------------------------------------------------------------------- 00112 // For constructing a leaf node 00113 template <typename T> 00114 BVHNode<T>::BVHNode ( 00115 int id, 00116 Enum::CD type, 00117 BVHNode<T> * parent ) 00118 : m_eType( type ), 00119 //m_bIsLeaf( false ), 00120 m_iID( id ), 00121 m_pParent( parent ), 00122 m_iN( 0 ), 00123 m_ppChild( NULL ) 00124 00125 #ifdef TAPs_ENABLE_COLLISION_DETECTION_ON_OFF_STATUS 00126 , m_bOnForColDet( true ) 00127 #endif//TAPs_ENABLE_COLLISION_DETECTION_ON_OFF_STATUS 00128 00129 #ifdef TAPs_DEBUG_COLLISION_DETECTION 00130 , flag( false ) 00131 #endif//TAPs_DEBUG_COLLISION_DETECTION 00132 { 00133 //bDraw = false; // DEBUG 00134 } 00135 //----------------------------------------------------------------------------- 00136 // StrInfo 00137 template <typename T> 00138 std::string BVHNode<T>::StrInfo () const 00139 { 00140 std::stringstream output; 00141 for ( int i = 0; i < m_iN; ++i ) { 00142 output << "\n\tChild Ptr#" << m_iN << ": " << m_ppChild[i]; 00143 } 00144 //----------------------------------------------------------- 00145 // Output the node info 00146 output << "\nThe node type is "; 00147 switch ( m_eType ) { 00148 case Enum::UNDEFINED_NODE: 00149 output << "UNDEFINED_NODE."; 00150 break; 00151 case Enum::BVH_NODE_BINARY_SPHERE: 00152 output << "BVH_NODE_BINARY_SPHERE." 00153 << " With Center at (" << m_vCenter[0] << ", " 00154 << m_vCenter[1] << ", " << m_vCenter[2] 00155 << ") and radius of " << m_vW[0]; 00156 break; 00157 default: 00158 output << "\nUnrecognized Node!"; 00159 break; 00160 } 00161 output << "\n"; 00162 return output.str(); 00163 } 00164 //----------------------------------------------------------------------------- 00165 template <typename T> 00166 BVHNode<T>::~BVHNode () 00167 { 00168 //std::cout << "Delete BVHNode ID: " << m_iID << std::endl; 00169 //--------------------------------------------------------------- 00170 // Delete All Children 00171 if ( m_ppChild ) { 00172 for ( int i = 0; i < m_iN; ++i ) { 00173 if ( m_ppChild[i] ) delete m_ppChild[i]; 00174 //m_ppChild[i] = NULL; 00175 } 00176 delete [] m_ppChild; 00177 //m_ppChild = NULL; 00178 } 00179 //--------------------------------------------------------------- 00180 // Set Parent Node 00181 if ( m_pParent ) { 00182 for ( int i = 0; i < m_iN; ++i ) { 00183 if ( m_pParent->m_ppChild[i] == this ) { 00184 m_pParent->m_ppChild[i] = NULL; 00185 break; 00186 } 00187 } 00188 //m_pParent = NULL; 00189 } 00190 } 00191 //----------------------------------------------------------------------------- 00192 template <typename T> 00193 void BVHNode<T>::InitChildren ( Enum::CD type, BVHNode<T> ** children ) 00194 { 00195 switch ( type ) { 00196 case Enum::BVH_NODE_BINARY_SPHERE: 00197 case Enum::BVH_NODE_BINARY_AABB: 00198 case Enum::BVH_NODE_BINARY_OBB: 00199 InitChildren( 2, children ); 00200 break; 00201 case Enum::BVH_NODE_QUAD_SPHERE: 00202 case Enum::BVH_NODE_QUAD_AABB: 00203 case Enum::BVH_NODE_QUAD_OBB: 00204 InitChildren( 4, children ); 00205 break; 00206 case Enum::BVH_NODE_OCTANT_SPHERE: 00207 case Enum::BVH_NODE_OCTANT_AABB: 00208 case Enum::BVH_NODE_OCTANT_OBB: 00209 InitChildren( 8, children ); 00210 break; 00211 default: 00212 std::cout << "Error: BVHNode<T>::InitChildren Fn!" << std::endl; 00213 assert( false ); 00214 break; 00215 } 00216 } 00217 //----------------------------------------------------------------------------- 00218 template <typename T> 00219 void BVHNode<T>::InitChildren ( int numOfChildren, BVHNode<T> ** children ) 00220 { 00221 m_iN = numOfChildren; 00222 /* 00223 //--------------------------------------------------------------- 00224 // For Leaf Node (i.e. No Children) 00225 if ( m_iN == 0 ) { 00226 m_ppChild = NULL; 00227 return; 00228 } 00229 //*/ 00230 //--------------------------------------------------------------- 00231 m_ppChild = new BVHNode<T> *[m_iN]; 00232 if ( children ) { 00233 for ( int i = 0; i < m_iN; ++i ) { 00234 m_ppChild[i] = children[i]; 00235 } 00236 } 00237 else { 00238 for ( int i = 0; i < m_iN; ++i ) { 00239 m_ppChild[i] = NULL; 00240 } 00241 } 00242 } 00243 //----------------------------------------------------------------------------- 00244 // Constructor(s) and Destructor 00245 //============================================================================= 00246 00247 00248 00249 00250 //============================================================================= 00251 // Node Operations 00252 //----------------------------------------------------------------------------- 00253 // Update 00254 // update only this node 00255 template <typename T> 00256 void BVHNode<T>::Update () 00257 { 00258 //--------------------------------------------------------------- 00259 switch ( m_eType ) { 00260 case Enum::BVH_NODE_BINARY_SPHERE: 00261 if ( m_ppChild[0] != NULL && m_ppChild[1] != NULL ) { 00262 Vector3<T> V = m_ppChild[0]->GetCenter() - m_ppChild[1]->GetCenter(); 00263 T a = m_ppChild[0]->GetRadius(); 00264 T b = m_ppChild[1]->GetRadius(); 00265 SetCenter( m_ppChild[1]->GetCenter() + V*a/(a+b) ); 00266 // m_vW[0] is m_tRadius 00267 SetRadius( ( m_ppChild[0]->GetRadius() + m_ppChild[1]->GetRadius() 00268 + V.Length() ) / T(2.0) ); 00269 } 00270 else if ( m_ppChild[0] == NULL && m_ppChild[1] == NULL ) { 00271 } 00272 else if ( m_ppChild[0] != NULL ) { 00273 SetCenter( m_ppChild[0]->GetCenter() ); 00274 // m_vW[0] is m_tRadius 00275 SetRadius( m_ppChild[0]->GetRadius() ); 00276 } 00277 else if ( m_ppChild[1] != NULL ) { 00278 SetCenter( m_ppChild[1]->GetCenter() ); 00279 // m_vW[0] is m_tRadius 00280 SetRadius( m_ppChild[1]->GetRadius() ); 00281 } 00282 break; 00283 case Enum::BVH_NODE_BINARY_AABB: 00284 break; 00285 case Enum::BVH_NODE_BINARY_OBB: 00286 break; 00287 case Enum::BVH_NODE_QUAD_SPHERE: 00288 break; 00289 case Enum::BVH_NODE_QUAD_AABB: 00290 break; 00291 case Enum::BVH_NODE_QUAD_OBB: 00292 break; 00293 case Enum::BVH_NODE_OCTANT_SPHERE: 00294 break; 00295 case Enum::BVH_NODE_OCTANT_AABB: 00296 break; 00297 case Enum::BVH_NODE_OCTANT_OBB: 00298 break; 00299 default: 00300 break; 00301 } 00302 } 00303 //----------------------------------------------------------------------------- 00304 // Node Operations 00305 //============================================================================= 00306 00307 00308 00309 00310 /* 00311 //----------------------------------------------------------------------------- 00312 // TestOverlapWith 00313 template <typename T> 00314 T BVHNode<T>::TestOverlapWith ( BVHNode<T> const * const that ) const 00315 { 00316 switch ( m_eType ) { 00317 case Enum::BVH_NODE_BINARY_SPHERE: 00318 case Enum::BVH_NODE_QUAD_SPHERE: 00319 case Enum::BVH_NODE_OCTANT_SPHERE: 00320 case Enum::BVH_NODE_GENERIC_SPHERE: 00321 case Enum::BVH_NODE_LEAF_SPHERE_HALFEDGE_APRIM: 00322 case Enum::BVH_NODE_LEAF_SPHERE_HALFEDGE_PRIMS: 00323 switch ( that->m_eType ) { 00324 case Enum::BVH_NODE_BINARY_SPHERE: 00325 case Enum::BVH_NODE_QUAD_SPHERE: 00326 case Enum::BVH_NODE_OCTANT_SPHERE: 00327 case Enum::BVH_NODE_GENERIC_SPHERE: 00328 case Enum::BVH_NODE_LEAF_SPHERE_HALFEDGE_APRIM: 00329 return ( GetCenter() - that->GetCenter() ).Length() 00330 - ( GetRadius() + that->GetRadius() ); // m_vW[0] is m_tRadius 00331 break; 00332 case Enum::BVH_NODE_LEAF_SPHERE_HALFEDGE_PRIMS: 00333 return ( GetCenter() - that->GetCenter() ).Length() 00334 - ( GetRadius() + that->GetRadius() ); // m_vW[0] is m_tRadius 00335 break; 00336 default: 00337 std::cout << "Error: BVHNode<T>::TestOverlapWith Fn!" << std::endl; 00338 assert( false ); 00339 break; 00340 } 00341 break; 00342 default: 00343 std::cout << "Error: BVHNode<T>::TestOverlapWith Fn!" << std::endl; 00344 assert( false ); 00345 break; 00346 } 00347 return -777; // -777 is an Error Code 00348 } 00349 //----------------------------------------------------------------------------- 00350 // TestOverlapWithNoPrimitiveTests 00351 template <typename T> 00352 T BVHNode<T>::TestOverlapWithNoPrimitiveTests ( BVHNode<T> const * const that ) const 00353 { 00354 switch ( m_eType ) { 00355 case Enum::BVH_NODE_BINARY_SPHERE: 00356 case Enum::BVH_NODE_QUAD_SPHERE: 00357 case Enum::BVH_NODE_OCTANT_SPHERE: 00358 case Enum::BVH_NODE_GENERIC_SPHERE: 00359 case Enum::BVH_NODE_LEAF_SPHERE_HALFEDGE_APRIM: 00360 case Enum::BVH_NODE_LEAF_SPHERE_HALFEDGE_PRIMS: 00361 switch ( that->m_eType ) { 00362 case Enum::BVH_NODE_BINARY_SPHERE: 00363 case Enum::BVH_NODE_QUAD_SPHERE: 00364 case Enum::BVH_NODE_OCTANT_SPHERE: 00365 case Enum::BVH_NODE_GENERIC_SPHERE: 00366 case Enum::BVH_NODE_LEAF_SPHERE_HALFEDGE_APRIM: 00367 return ( GetCenter() - that->GetCenter() ).Length() 00368 - ( GetRadius() + that->GetRadius() ); // m_vW[0] is m_tRadius 00369 break; 00370 case Enum::BVH_NODE_LEAF_SPHERE_HALFEDGE_PRIMS: 00371 return ( GetCenter() - that->GetCenter() ).Length() 00372 - ( GetRadius() + that->GetRadius() ); // m_vW[0] is m_tRadius 00373 break; 00374 default: 00375 std::cout << "Error: BVHNode<T>::TestOverlapWith Fn!" << std::endl; 00376 assert( false ); 00377 break; 00378 } 00379 break; 00380 default: 00381 std::cout << "Error: BVHNode<T>::TestOverlapWith Fn!" << std::endl; 00382 assert( false ); 00383 break; 00384 } 00385 return -777; // -777 is an Error Code 00386 } 00387 //----------------------------------------------------------------------------- 00388 //*/ 00389 00390 00391 00392 00393 //============================================================================= 00394 // Sphere-BVSphere Intersection Test (BinarySphereTree vs BinarySphereTree) 00395 //----------------------------------------------------------------------------- 00396 // TestOverlapSphereWithSphere #1 00397 template <typename T> 00398 T BVHNode<T>::TestOverlapSphereWithSphere ( BVHNode<T> const * const that ) const 00399 { 00400 //return ( GetCenter() - that->GetCenter() ).Length() - ( GetRadius() + that->GetRadius() ); 00401 return TestOverlapSphereWithSphere_NoPrimitiveTests( that ); 00402 } 00403 //----------------------------------------------------------------------------- 00404 // TestOverlapSphereWithSphere #2 00405 template <typename T> 00406 T BVHNode<T>::TestOverlapSphereWithSphere ( 00407 BVHNode<T> const * const that, 00408 Matrix4x4<T> const & thatTransform ) const 00409 { 00410 //Vector3<T> cB = (thatTransform * Vector4<T>( that->GetCenter() )).GetVector3(); 00411 //return ( GetCenter() - cB ).Length() - ( GetRadius() + that->GetRadius() ); 00412 return TestOverlapSphereWithSphere_NoPrimitiveTests( that, thatTransform ); 00413 } 00414 //----------------------------------------------------------------------------- 00415 // TestOverlapSphereWithSphere #3 00416 template <typename T> 00417 T BVHNode<T>::TestOverlapSphereWithSphere ( 00418 Matrix4x4<T> const & thisTransform, 00419 BVHNode<T> const * const that ) const 00420 { 00421 //Vector3<T> cA = (thisTransform * Vector4<T>( GetCenter() )).GetVector3(); 00422 //return ( cA - that->GetCenter() ).Length() - ( GetRadius() + that->GetRadius() ); 00423 return TestOverlapSphereWithSphere_NoPrimitiveTests( thisTransform, that ); 00424 } 00425 //----------------------------------------------------------------------------- 00426 // TestOverlapSphereWithSphere #4 00427 template <typename T> 00428 T BVHNode<T>::TestOverlapSphereWithSphere ( 00429 Matrix4x4<T> const & thisTransform, 00430 BVHNode<T> const * const that, 00431 Matrix4x4<T> const & thatTransform ) const 00432 { 00433 //Vector3<T> cA = (thisTransform * Vector4<T>( GetCenter() )).GetVector3(); 00434 //Vector3<T> cB = (thatTransform * Vector4<T>( that->GetCenter() )).GetVector3(); 00435 //return ( cA - cB ).Length() - ( GetRadius() + that->GetRadius() ); 00436 return TestOverlapSphereWithSphere_NoPrimitiveTests( thisTransform, that, thatTransform ); 00437 } 00438 //----------------------------------------------------------------------------- 00439 00440 00441 //----------------------------------------------------------------------------- 00442 // TestOverlapSphereWithSphere_NoPrimitiveTests #1 00443 template <typename T> 00444 T BVHNode<T>::TestOverlapSphereWithSphere_NoPrimitiveTests ( BVHNode<T> const * const that ) const 00445 { 00446 #ifdef TAPs_ENABLE_COLLISION_DETECTION_ON_OFF_STATUS 00447 if ( !GetOnStatus() ) return 1; 00448 #endif//TAPs_ENABLE_COLLISION_DETECTION_ON_OFF_STATUS 00449 00450 return ( GetCenter() - that->GetCenter() ).Length() - ( GetRadius() + that->GetRadius() ); 00451 } 00452 //----------------------------------------------------------------------------- 00453 // TestOverlapSphereWithSphere_NoPrimitiveTests #2 00454 template <typename T> 00455 T BVHNode<T>::TestOverlapSphereWithSphere_NoPrimitiveTests ( 00456 BVHNode<T> const * const that, 00457 Matrix4x4<T> const & thatTransform ) const 00458 { 00459 #ifdef TAPs_ENABLE_COLLISION_DETECTION_ON_OFF_STATUS 00460 if ( !GetOnStatus() ) return 1; 00461 #endif//TAPs_ENABLE_COLLISION_DETECTION_ON_OFF_STATUS 00462 00463 Vector3<T> cB = (thatTransform * Vector4<T>( that->GetCenter() )).GetVector3(); 00464 return ( GetCenter() - cB ).Length() - ( GetRadius() + that->GetRadius() ); 00465 } 00466 //----------------------------------------------------------------------------- 00467 // TestOverlapSphereWithSphere_NoPrimitiveTests #3 00468 template <typename T> 00469 T BVHNode<T>::TestOverlapSphereWithSphere_NoPrimitiveTests ( 00470 Matrix4x4<T> const & thisTransform, 00471 BVHNode<T> const * const that ) const 00472 { 00473 #ifdef TAPs_ENABLE_COLLISION_DETECTION_ON_OFF_STATUS 00474 if ( !GetOnStatus() ) return 1; 00475 #endif//TAPs_ENABLE_COLLISION_DETECTION_ON_OFF_STATUS 00476 00477 Vector3<T> cA = (thisTransform * Vector4<T>( GetCenter() )).GetVector3(); 00478 return ( cA - that->GetCenter() ).Length() - ( GetRadius() + that->GetRadius() ); 00479 } 00480 //----------------------------------------------------------------------------- 00481 // TestOverlapSphereWithSphere_NoPrimitiveTests #4 00482 template <typename T> 00483 T BVHNode<T>::TestOverlapSphereWithSphere_NoPrimitiveTests ( 00484 Matrix4x4<T> const & thisTransform, 00485 BVHNode<T> const * const that, 00486 Matrix4x4<T> const & thatTransform ) const 00487 { 00488 #ifdef TAPs_ENABLE_COLLISION_DETECTION_ON_OFF_STATUS 00489 if ( !GetOnStatus() ) return 1; 00490 #endif//TAPs_ENABLE_COLLISION_DETECTION_ON_OFF_STATUS 00491 00492 Vector3<T> cA = (thisTransform * Vector4<T>( GetCenter() )).GetVector3(); 00493 Vector3<T> cB = (thatTransform * Vector4<T>( that->GetCenter() )).GetVector3(); 00494 return ( cA - cB ).Length() - ( GetRadius() + that->GetRadius() ); 00495 } 00496 //----------------------------------------------------------------------------- 00497 // Sphere-Sphere Intersection Test (BinarySphereTree vs BinarySphereTree) 00498 //============================================================================= 00499 00500 00501 00502 00503 //============================================================================= 00504 // Sphere-BVSphere Intersection Test (BinarySphereTree vs Sphere BV) 00505 //----------------------------------------------------------------------------- 00506 // TestOverlapSphereWithBVSphere_NoPrimitiveTests #1 00507 template <typename T> 00508 T BVHNode<T>::TestOverlapSphereWithBVSphere_NoPrimitiveTests ( 00509 Vector3<T> const & centerOfBVSphere, 00510 T radiusOfBVSphere 00511 ) const 00512 { 00513 #ifdef TAPs_ENABLE_COLLISION_DETECTION_ON_OFF_STATUS 00514 if ( !GetOnStatus() ) return 1; 00515 #endif//TAPs_ENABLE_COLLISION_DETECTION_ON_OFF_STATUS 00516 00517 return ( GetCenter() - centerOfBVSphere ).Length() - ( GetRadius() + radiusOfBVSphere ); 00518 } 00519 //----------------------------------------------------------------------------- 00520 // TestOverlapSphereWithBVSphere_NoPrimitiveTests #2 00521 template <typename T> 00522 T BVHNode<T>::TestOverlapSphereWithBVSphere_NoPrimitiveTests ( 00523 Matrix4x4<T> const & transformA, 00524 Vector3<T> const & centerOfBVSphere, 00525 T radiusOfBVSphere 00526 ) const 00527 { 00528 #ifdef TAPs_ENABLE_COLLISION_DETECTION_ON_OFF_STATUS 00529 if ( !GetOnStatus() ) return 1; 00530 #endif//TAPs_ENABLE_COLLISION_DETECTION_ON_OFF_STATUS 00531 00532 Vector3<T> cA = (transformA * Vector4<T>( GetCenter() )).GetVector3(); 00533 return ( cA - centerOfBVSphere ).Length() - ( GetRadius() + radiusOfBVSphere ); 00534 } 00535 //----------------------------------------------------------------------------- 00536 // Sphere-BVSphere Intersection Test (BinarySphereTree vs Sphere BV) 00537 //============================================================================= 00538 00539 00540 00541 00542 //============================================================================= 00543 // Sphere-BVCylinder Intersection Test (BinarySphereTree vs Cylinder BV) 00544 //----------------------------------------------------------------------------- 00545 // TestOverlapSphereWithBVCylinder_NoPrimitiveTests #1 00546 template <typename T> 00547 bool BVHNode<T>::TestOverlapSphereWithBVCylinder_AtOrigin_NoPrimitiveTests ( 00548 T radiusOfBVCylinder, 00549 T heightOfBVCylinder 00550 ) const 00551 { 00552 #ifdef TAPs_ENABLE_COLLISION_DETECTION_ON_OFF_STATUS 00553 if ( !GetOnStatus() ) return 1; 00554 #endif//TAPs_ENABLE_COLLISION_DETECTION_ON_OFF_STATUS 00555 00556 return TAPs::CGMath<T>::CD_CylinderAtOrigin_vs_Sphere( radiusOfBVCylinder, heightOfBVCylinder, GetCenter(), GetRadius() ); 00557 } 00558 //----------------------------------------------------------------------------- 00559 // TestOverlapSphereWithBVSphere_NoPrimitiveTests #2 00560 template <typename T> 00561 bool BVHNode<T>::TestOverlapSphereWithBVCylinder_AtOrigin_NoPrimitiveTests ( 00562 Matrix4x4<T> const & transformA, 00563 T radiusOfBVCylinder, 00564 T heightOfBVCylinder 00565 ) const 00566 { 00567 #ifdef TAPs_ENABLE_COLLISION_DETECTION_ON_OFF_STATUS 00568 if ( !GetOnStatus() ) return 1; 00569 #endif//TAPs_ENABLE_COLLISION_DETECTION_ON_OFF_STATUS 00570 00571 // Sphere's center and radius after the transformation 00572 Vector3<T> cA = (transformA * Vector4<T>( GetCenter() )).GetVector3(); 00573 T rA = ( (transformA * Vector4<T>( GetRadius()+GetCenter()[0], GetCenter()[1], GetCenter()[2], 1 )).GetVector3() - cA ).Length(); 00574 return TAPs::CGMath<T>::CD_CylinderAtOrigin_vs_Sphere( radiusOfBVCylinder, heightOfBVCylinder, cA, rA ); 00575 } 00576 //----------------------------------------------------------------------------- 00577 // Sphere-BVSphere Intersection Test (BinarySphereTree vs Sphere BV) 00578 //============================================================================= 00579 00580 00581 00582 00583 #if defined(__gl_h_) || defined(__GL_H__) 00584 //============================================================================= 00585 // DrawByOpenGL 00586 //----------------------------------------------------------------------------- 00587 template <typename T> GLuint BVHNode<T>::m_uiDisplayList = 0; 00588 //----------------------------------------------------------------------------- 00589 template <typename T> 00590 void BVHNode<T>::DrawByOpenGL () const 00591 { 00592 DrawBV(); 00593 00594 // Draw child nodes 00595 for ( int i = 0; i < m_iN; ++i ) { 00596 if ( m_ppChild[i] ) { 00597 std::cout << *m_ppChild[i] << "\n"; 00598 m_ppChild[i]->DrawByOpenGL(); 00599 } 00600 } 00601 } 00602 //----------------------------------------------------------------------------- 00603 template <typename T> 00604 void BVHNode<T>::DrawByOpenGL ( 00605 int currentLevel, int startLevel, int endLevel ) const 00606 { 00607 if ( startLevel <= currentLevel && currentLevel <= endLevel ) { 00608 DrawBV(); 00609 } 00610 00611 // Draw child nodes 00612 ++currentLevel; 00613 for ( int i = 0; i < m_iN; ++i ) { 00614 if ( m_ppChild[i] ) { 00615 float div = static_cast<GLfloat>(m_iN); 00616 m_ppChild[i]->DrawByOpenGL( currentLevel, startLevel, endLevel ); 00617 } 00618 } 00619 } 00620 //----------------------------------------------------------------------------- 00621 template <typename T> 00622 void BVHNode<T>::DrawByOpenGLOnlyEndLevel () const 00623 { 00624 bool draw = true; 00625 for ( int i = 0; i < m_iN; ++i ) { 00626 if ( m_ppChild[i] ) draw = false; 00627 } 00628 if ( draw ) DrawBV(); 00629 00630 // Draw child nodes 00631 for ( int i = 0; i < m_iN; ++i ) { 00632 if ( m_ppChild[i] ) { 00633 m_ppChild[i]->DrawByOpenGLOnlyEndLevel(); 00634 } 00635 } 00636 } 00637 //----------------------------------------------------------------------------- 00638 template <typename T> 00639 void BVHNode<T>::DrawBV ( GLenum drawStyle ) const 00640 { 00641 switch ( m_eType ) { 00642 //----------------------------------------------------------- 00643 // DRAW SPHERE BVH 00644 case Enum::BVH_NODE_BINARY_SPHERE: 00645 case Enum::BVH_NODE_QUAD_SPHERE: 00646 case Enum::BVH_NODE_OCTANT_SPHERE: 00647 case Enum::BVH_NODE_GENERIC_SPHERE: 00648 DrawSphereBV(); 00649 break; 00650 //----------------------------------------------------------- 00651 // DRAW AABB BVH 00652 case Enum::BVH_NODE_BINARY_AABB: 00653 case Enum::BVH_NODE_QUAD_AABB: 00654 case Enum::BVH_NODE_OCTANT_AABB: 00655 case Enum::BVH_NODE_GENERIC_AABB: 00656 DrawAABBBV(); 00657 break; 00658 //----------------------------------------------------------- 00659 // DRAW OBB BVH 00660 case Enum::BVH_NODE_BINARY_OBB: 00661 case Enum::BVH_NODE_QUAD_OBB: 00662 case Enum::BVH_NODE_OCTANT_OBB: 00663 case Enum::BVH_NODE_GENERIC_OBB: 00664 DrawOBBBV(); 00665 break; 00666 } 00667 } 00668 //----------------------------------------------------------------------------- 00669 template <typename T> 00670 void BVHNode<T>::DrawSphereBV ( GLenum drawStyle ) const 00671 { 00672 //--------------------------------------------------------------- 00673 //std::cout << "Draw SPHERE Bounding Volume\n"; 00674 00675 if ( !m_uiDisplayList ) { 00676 00677 #ifdef TAPs_DEBUG_COLLISION_DETECTION 00678 00679 m_uiDisplayList = glGenLists( 2 ); 00680 GLUquadricObj *qObj = gluNewQuadric(); 00681 glNewList( m_uiDisplayList, GL_COMPILE ); 00682 gluQuadricDrawStyle( qObj, GLU_LINE ); 00683 gluSphere( qObj, 1, 9, 9 ); 00684 //gluSphere( qObj, 1, 12, 12 ); 00685 //gluSphere( qObj, 1, 15, 15 ); 00686 glEndList(); 00687 glNewList( m_uiDisplayList+1, GL_COMPILE ); 00688 gluQuadricDrawStyle( qObj, GLU_FILL ); 00689 gluSphere( qObj, 1, 9, 9 ); 00690 //gluSphere( qObj, 1, 12, 12 ); 00691 //gluSphere( qObj, 1, 15, 15 ); 00692 glEndList(); 00693 gluDeleteQuadric( qObj ); 00694 00695 #else //TAPs_DEBUG_COLLISION_DETECTION 00696 00697 m_uiDisplayList = glGenLists( 1 ); 00698 GLUquadricObj *qObj = gluNewQuadric(); 00699 glNewList( m_uiDisplayList, GL_COMPILE ); 00700 // GLenum drawStyle 00701 // GLU_FILL 00702 // GLU_LINE 00703 // GLU_SILHOUETTE 00704 // GLU_POINT 00705 gluQuadricDrawStyle( qObj, GLU_LINE ); 00706 gluSphere( qObj, 1, 9, 9 ); 00707 //gluSphere( qObj, 1, 12, 12 ); 00708 //gluSphere( qObj, 1, 15, 15 ); 00709 glEndList(); 00710 gluDeleteQuadric( qObj ); 00711 00712 #endif//TAPs_DEBUG_COLLISION_DETECTION 00713 00714 } 00715 //--------------------------------------------------------------- 00716 glPushMatrix(); 00717 glTranslatef( static_cast<GLfloat>(GetCenter()[0]), static_cast<GLfloat>(GetCenter()[1]), static_cast<GLfloat>(GetCenter()[2]) ); 00718 glScalef( static_cast<GLfloat>(GetRadius()), static_cast<GLfloat>(GetRadius()), static_cast<GLfloat>(GetRadius()) ); 00719 00720 #ifdef TAPs_DEBUG_COLLISION_DETECTION 00721 if ( flag ) glCallList( m_uiDisplayList ); 00722 else glCallList( m_uiDisplayList+1 ); 00723 #else //TAPs_DEBUG_COLLISION_DETECTION 00724 glCallList( m_uiDisplayList ); 00725 #endif//TAPs_DEBUG_COLLISION_DETECTION 00726 00727 //------------------------------------------------- 00728 // Draw the sphere center 00729 //glScalef( 0.1, 0.1, 0.1 ); 00730 //glCallList( m_uiDisplayList ); 00731 glPopMatrix(); 00732 } 00733 //----------------------------------------------------------------------------- 00734 template <typename T> 00735 void BVHNode<T>::DrawAABBBV ( GLenum drawStyle ) const 00736 { 00737 //--------------------------------------------------------------- 00738 //std::cout << "Draw AABB Bounding Volume\n"; 00739 Vector3<T> pt[8]; 00740 // m_vV is the min point 00741 // m_vW is the max point 00742 // 00743 // 3------2 00744 // /| /| y 00745 // / 0----/-1 | 00746 // 7----- 6 / 0--x 00747 // |/ |/ / 00748 // 4------5 z 00749 pt[0] = GetMinPt(); // Point#0 is the min point 00750 pt[1].SetXYZ( GetMaxPt()[0], GetMinPt()[1], GetMinPt()[2] ); // Point#1 00751 pt[2].SetXYZ( GetMaxPt()[0], GetMaxPt()[1], GetMinPt()[2] ); // Point#2 00752 pt[3].SetXYZ( GetMinPt()[0], GetMaxPt()[1], GetMinPt()[2] ); // Point#3 00753 pt[4].SetXYZ( GetMinPt()[0], GetMinPt()[1], GetMaxPt()[2] ); // Point#4 00754 pt[5].SetXYZ( GetMaxPt()[0], GetMinPt()[1], GetMaxPt()[2] ); // Point#5 00755 pt[6] = GetMaxPt(); // Point#6 is the max point 00756 pt[7].SetXYZ( GetMinPt()[0], GetMaxPt()[1], GetMaxPt()[2] ); // Point#7 00757 /* 00758 pt[0] = m_vV; // Point#0 is the min point 00759 pt[1].SetXYZ( m_vW[0], m_vV[1], m_vV[2] ); // Point#1 00760 pt[2].SetXYZ( m_vW[0], m_vW[1], m_vV[2] ); // Point#2 00761 pt[3].SetXYZ( m_vV[0], m_vW[1], m_vV[2] ); // Point#3 00762 pt[4].SetXYZ( m_vV[0], m_vV[1], m_vW[2] ); // Point#4 00763 pt[5].SetXYZ( m_vW[0], m_vV[1], m_vW[2] ); // Point#5 00764 pt[6] = m_vW; // Point#6 is the max point 00765 pt[7].SetXYZ( m_vV[0], m_vW[1], m_vW[2] ); // Point#7 00766 //*/ 00767 glPushMatrix(); 00768 glBegin( GL_LINE_LOOP ); 00769 glVertex3f( static_cast<GLfloat>(pt[0][0]), static_cast<GLfloat>(pt[0][1]), static_cast<GLfloat>(pt[0][2]) ); 00770 glVertex3f( static_cast<GLfloat>(pt[1][0]), static_cast<GLfloat>(pt[1][1]), static_cast<GLfloat>(pt[1][2]) ); 00771 glVertex3f( static_cast<GLfloat>(pt[2][0]), static_cast<GLfloat>(pt[2][1]), static_cast<GLfloat>(pt[2][2]) ); 00772 glVertex3f( static_cast<GLfloat>(pt[3][0]), static_cast<GLfloat>(pt[3][1]), static_cast<GLfloat>(pt[3][2]) ); 00773 glEnd(); 00774 glBegin( GL_LINE_LOOP ); 00775 glVertex3f( static_cast<GLfloat>(pt[4][0]), static_cast<GLfloat>(pt[4][1]), static_cast<GLfloat>(pt[4][2]) ); 00776 glVertex3f( static_cast<GLfloat>(pt[5][0]), static_cast<GLfloat>(pt[5][1]), static_cast<GLfloat>(pt[5][2]) ); 00777 glVertex3f( static_cast<GLfloat>(pt[6][0]), static_cast<GLfloat>(pt[6][1]), static_cast<GLfloat>(pt[6][2]) ); 00778 glVertex3f( static_cast<GLfloat>(pt[7][0]), static_cast<GLfloat>(pt[7][1]), static_cast<GLfloat>(pt[7][2]) ); 00779 glEnd(); 00780 glBegin( GL_LINES ); 00781 glVertex3f( static_cast<GLfloat>(pt[0][0]), static_cast<GLfloat>(pt[0][1]), static_cast<GLfloat>(pt[0][2]) ); 00782 glVertex3f( static_cast<GLfloat>(pt[4][0]), static_cast<GLfloat>(pt[4][1]), static_cast<GLfloat>(pt[4][2]) ); 00783 glVertex3f( static_cast<GLfloat>(pt[1][0]), static_cast<GLfloat>(pt[1][1]), static_cast<GLfloat>(pt[1][2]) ); 00784 glVertex3f( static_cast<GLfloat>(pt[5][0]), static_cast<GLfloat>(pt[5][1]), static_cast<GLfloat>(pt[5][2]) ); 00785 glVertex3f( static_cast<GLfloat>(pt[2][0]), static_cast<GLfloat>(pt[2][1]), static_cast<GLfloat>(pt[2][2]) ); 00786 glVertex3f( static_cast<GLfloat>(pt[6][0]), static_cast<GLfloat>(pt[6][1]), static_cast<GLfloat>(pt[6][2]) ); 00787 glVertex3f( static_cast<GLfloat>(pt[3][0]), static_cast<GLfloat>(pt[3][1]), static_cast<GLfloat>(pt[3][2]) ); 00788 glVertex3f( static_cast<GLfloat>(pt[7][0]), static_cast<GLfloat>(pt[7][1]), static_cast<GLfloat>(pt[7][2]) ); 00789 glEnd(); 00790 glPopMatrix(); 00791 } 00792 //----------------------------------------------------------------------------- 00793 template <typename T> 00794 void BVHNode<T>::DrawOBBBV ( GLenum drawStyle ) const 00795 { 00796 //--------------------------------------------------------------- 00797 //std::cout << "Draw OBB Bounding Volume\n"; 00798 if ( !m_uiDisplayList ) { 00799 m_uiDisplayList = glGenLists( 1 ); 00800 GLUquadricObj *qObj = gluNewQuadric(); 00801 glNewList( m_uiDisplayList, GL_COMPILE ); 00802 gluQuadricDrawStyle( qObj, drawStyle ); 00803 gluSphere( qObj, 1, 9, 9 ); 00804 //gluSphere( qObj, 1, 12, 12 ); 00805 //gluSphere( qObj, 1, 15, 15 ); 00806 glEndList(); 00807 gluDeleteQuadric( qObj ); 00808 } 00809 //--------------------------------------------------------------- 00810 // Draw The Center of OBB Bounding Volume by a sphere 00811 T length = Get3rdPrincipleComponent().Length() / T(20.0); 00812 glPushMatrix(); 00813 glTranslatef( static_cast<GLfloat>(GetCenter()[0]), static_cast<GLfloat>(GetCenter()[1]), static_cast<GLfloat>(GetCenter()[2]) ); 00814 // m_vW[0] is m_tRadius 00815 glScalef( static_cast<GLfloat>(length), static_cast<GLfloat>(length), static_cast<GLfloat>(length) ); 00816 glCallList( m_uiDisplayList ); 00817 glPopMatrix(); 00818 //--------------------------------------------------------------- 00819 // Draw OBB Bounding Box 00820 Vector3<T> pt[8]; 00821 pt[0] = m_vV + m_vU + m_vW; 00822 pt[1] = m_vV + m_vU - m_vW; 00823 pt[2] = m_vV - m_vU - m_vW; 00824 pt[3] = m_vV - m_vU + m_vW; 00825 pt[4] = -pt[2]; 00826 pt[5] = -pt[3]; 00827 pt[6] = -pt[0]; 00828 pt[7] = -pt[1]; 00829 glPushMatrix(); 00830 glTranslatef( static_cast<GLfloat>(GetCenter()[0]), static_cast<GLfloat>(GetCenter()[1]), static_cast<GLfloat>(GetCenter()[2]) ); 00831 glBegin( GL_LINE_LOOP ); 00832 glVertex3f( static_cast<GLfloat>(pt[0][0]), static_cast<GLfloat>(pt[0][1]), static_cast<GLfloat>(pt[0][2]) ); 00833 glVertex3f( static_cast<GLfloat>(pt[1][0]), static_cast<GLfloat>(pt[1][1]), static_cast<GLfloat>(pt[1][2]) ); 00834 glVertex3f( static_cast<GLfloat>(pt[2][0]), static_cast<GLfloat>(pt[2][1]), static_cast<GLfloat>(pt[2][2]) ); 00835 glVertex3f( static_cast<GLfloat>(pt[3][0]), static_cast<GLfloat>(pt[3][1]), static_cast<GLfloat>(pt[3][2]) ); 00836 glEnd(); 00837 glBegin( GL_LINE_LOOP ); 00838 glVertex3f( static_cast<GLfloat>(pt[4][0]), static_cast<GLfloat>(pt[4][1]), static_cast<GLfloat>(pt[4][2]) ); 00839 glVertex3f( static_cast<GLfloat>(pt[5][0]), static_cast<GLfloat>(pt[5][1]), static_cast<GLfloat>(pt[5][2]) ); 00840 glVertex3f( static_cast<GLfloat>(pt[6][0]), static_cast<GLfloat>(pt[6][1]), static_cast<GLfloat>(pt[6][2]) ); 00841 glVertex3f( static_cast<GLfloat>(pt[7][0]), static_cast<GLfloat>(pt[7][1]), static_cast<GLfloat>(pt[7][2]) ); 00842 glEnd(); 00843 glBegin( GL_LINES ); 00844 glVertex3f( static_cast<GLfloat>(pt[0][0]), static_cast<GLfloat>(pt[0][1]), static_cast<GLfloat>(pt[0][2]) ); 00845 glVertex3f( static_cast<GLfloat>(pt[4][0]), static_cast<GLfloat>(pt[4][1]), static_cast<GLfloat>(pt[4][2]) ); 00846 glVertex3f( static_cast<GLfloat>(pt[1][0]), static_cast<GLfloat>(pt[1][1]), static_cast<GLfloat>(pt[1][2]) ); 00847 glVertex3f( static_cast<GLfloat>(pt[5][0]), static_cast<GLfloat>(pt[5][1]), static_cast<GLfloat>(pt[5][2]) ); 00848 glVertex3f( static_cast<GLfloat>(pt[2][0]), static_cast<GLfloat>(pt[2][1]), static_cast<GLfloat>(pt[2][2]) ); 00849 glVertex3f( static_cast<GLfloat>(pt[6][0]), static_cast<GLfloat>(pt[6][1]), static_cast<GLfloat>(pt[6][2]) ); 00850 glVertex3f( static_cast<GLfloat>(pt[3][0]), static_cast<GLfloat>(pt[3][1]), static_cast<GLfloat>(pt[3][2]) ); 00851 glVertex3f( static_cast<GLfloat>(pt[7][0]), static_cast<GLfloat>(pt[7][1]), static_cast<GLfloat>(pt[7][2]) ); 00852 glEnd(); 00853 glPopMatrix(); 00854 //--------------------------------------------------------------- 00855 // Draw Principle Components 00856 //* 00857 glDisable( GL_LIGHTING ); 00858 glPushMatrix(); 00859 glTranslatef( static_cast<GLfloat>(GetCenter()[0]), static_cast<GLfloat>(GetCenter()[1]), static_cast<GLfloat>(GetCenter()[2]) ); 00860 glBegin( GL_LINES ); 00861 //--------------------------------------------- 00862 // 1st principle component 00863 glColor3f( 1, 0, 0 ); 00864 glVertex3f( 0, 0, 0 ); 00865 glVertex3f( static_cast<GLfloat>(m_vU[0]), static_cast<GLfloat>(m_vU[1]), static_cast<GLfloat>(m_vU[2]) ); 00866 //--------------------------------------------- 00867 // 2nd principle component 00868 glColor3f( 0, 1, 0 ); 00869 glVertex3f( 0, 0, 0 ); 00870 glVertex3f( static_cast<GLfloat>(m_vV[0]), static_cast<GLfloat>(m_vV[1]), static_cast<GLfloat>(m_vV[2]) ); 00871 //--------------------------------------------- 00872 // 3rd principle component 00873 glColor3f( 0, 0, 1 ); 00874 glVertex3f( 0, 0, 0 ); 00875 glVertex3f( static_cast<GLfloat>(m_vW[0]), static_cast<GLfloat>(m_vW[1]), static_cast<GLfloat>(m_vW[2]) ); 00876 glEnd(); 00877 glPopMatrix(); 00878 glEnable( GL_LIGHTING ); 00879 //*/ 00880 } 00881 //----------------------------------------------------------------------------- 00882 #endif // #if defined(__gl_h_) || defined(__GL_H__) 00883 //============================================================================= 00884 END_NAMESPACE_TAPs 00885 //34567890123456789012345678901234567890123456789012345678901234567890123456789 00886 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----