TAPs 0.7.7.3
TAPsBVHNode.cpp
Go to the documentation of this file.
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----+----
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines