TAPs 0.7.7.3
TAPsBVHTree.cpp
Go to the documentation of this file.
00001 /******************************************************************************
00002 TAPsBVHTree.cpp
00003 
00004 BVHTree class is a class for any Boundary Volume Hierarchy Tree.
00005 
00006 SUKITTI PUNAK   (01/17/2006)
00007 UPDATE          (09/03/2010)
00008 ******************************************************************************/
00009 #include "TAPsBVHTree.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 and Destructor
00017 //-----------------------------------------------------------------------------
00018 template <typename T>
00019 BVHTree<T>::BVHTree ( 
00020     TransformationSupport<T> & transform, 
00021     Enum::CD type, 
00022     int numOfNodes, 
00023     BVHNode<T> * rootNode )
00024     : m_eType( type ), 
00025       m_iTotalNodes( numOfNodes ), 
00026       m_pRoot( rootNode ), 
00027       m_Transform( transform )
00028 {}
00029 //-----------------------------------------------------------------------------
00030 template <typename T>
00031 BVHTree<T>::~BVHTree ()
00032 {
00033     if ( m_pRoot ) {
00034         delete m_pRoot;
00035         m_pRoot = NULL;
00036     }
00037 }
00038 //-----------------------------------------------------------------------------
00039 
00040 
00041 
00042 
00043 #ifdef  TAPs_DEBUG_COLLISION_DETECTION
00044 //-----------------------------------------------------------------------------
00045 template <typename T>
00046 void BVHTree<T>::ClearFlags ()
00047 {
00048     if ( m_pRoot == NULL )  return;
00049     //---------------------------------------------------------------
00050     ClearFlags( m_pRoot );
00051 }
00052 //-----------------------------------------------------------------------------
00053 template <typename T>
00054 void BVHTree<T>::ClearFlags ( BVHNode<T> * const node )
00055 {
00056     node->flag = false;
00057     //---------------------------------------------------------------
00058     for ( int i = 0; i < node->GetNumOfChildren(); ++i ) {
00059         if ( node->Child(i) != NULL ) {
00060             ClearFlags( node->Child(i) );
00061         }
00062     }
00063 }
00064 //-----------------------------------------------------------------------------
00065 #endif//TAPs_DEBUG_COLLISION_DETECTION
00066 
00067 
00068 
00069 
00070 //=============================================================================
00071 // Tree Operations
00072 //-----------------------------------------------------------------------------
00073 // CountNodes
00074 template <typename T>
00075 int BVHTree<T>::CountNodes () const
00076 {
00077     if ( m_pRoot == NULL )      return 0;
00078     //---------------------------------------------------------------
00079     return CountNodes( m_pRoot );
00080 }
00081 //-----------------------------------------------------------------------------
00082 // CountNodes
00083 template <typename T>
00084 int BVHTree<T>::CountNodes ( BVHNode<T> const * const node ) const
00085 {
00086     //---------------------------------------------------------------
00087     int numOfNodes = 1;
00088     for ( int i = 0; i < node->GetNumOfChildren(); ++i ) {
00089         if ( node->Child(i) != NULL ) {
00090             numOfNodes += CountNodes( node->Child(i) );
00091         }
00092     }
00093     return numOfNodes;
00094 }
00095 //-----------------------------------------------------------------------------
00096 // CountLeafNodes
00097 template <typename T>
00098 int BVHTree<T>::CountLeafNodes () const
00099 {
00100     if ( m_pRoot == NULL )      return 0;
00101     //---------------------------------------------------------------
00102     return CountLeafNodes( m_pRoot );
00103 }
00104 //-----------------------------------------------------------------------------
00105 // CountLeafNodes
00106 template <typename T>
00107 int BVHTree<T>::CountLeafNodes ( BVHNode<T> const * const node ) const
00108 {
00109     //if ( node->listHEFace.size() == 1 ) {
00110     if ( node->IsLeaf() ) {
00111         return 1;
00112     }
00113     //---------------------------------------------------------------
00114     int numOfLeafNodes = 0;
00115     for ( int i = 0; i < node->GetNumOfChildren(); ++i ) {
00116         if ( node->Child(i) != NULL ) {
00117             numOfLeafNodes += CountLeafNodes( node->Child(i) );
00118         }
00119     }
00120     return numOfLeafNodes;
00121 }
00122 //-----------------------------------------------------------------------------
00123 // FindListOfLeafNodes
00124 template <typename T>
00125 void BVHTree<T>::FindListOfLeafNodes ( 
00126         BVHNode<T> * node, std::set< BVHNode<T> * > & leafNodeSet )
00127 {
00128     if ( node->IsLeaf() ) {
00129         leafNodeSet.insert( node );
00130         return;
00131     }
00132     //---------------------------------------------------------------
00133     for ( int i = 0; i < node->GetNumOfChildren(); ++i ) {
00134         if ( node->Child(i) != NULL ) {
00135             FindListOfLeafNodes( node->Child(i), leafNodeSet );
00136         }
00137     }
00138 }
00139 //-----------------------------------------------------------------------------
00140 // Display all nodes as string
00141 template <typename T>
00142 void BVHTree<T>::DisplayAllNodesAsString ( BVHNode<T> * node, std::string & str, int level ) const
00143 {
00144     std::stringstream ss;
00145     //---------------------------------------------------------------
00146     for ( int i = 0; i < node->GetNumOfChildren(); ++i ) {
00147         if ( node->Child(i) != NULL ) {
00148             DisplayAllNodesAsString( node->Child(i), str, level+1 );
00149         }
00150     }
00151     ss << "[Level "<<level<<"]" << "\tID: " << node->GetID();
00152     if ( node->IsLeaf() ) {
00153         ss << "\ta leaf node";
00154     }
00155     ss << "\n";
00156     str += ss.str();
00157 }
00158 //-----------------------------------------------------------------------------
00159 // Update
00160 template <typename T>
00161 void BVHTree<T>::Update ()
00162 {
00163     //std::cout << "BVHTree<T>::Update()\n";
00164 
00165     std::set< BVHNode<T> * > leafNodeSet;
00166     if ( !m_pRoot ) return;
00167     //FindListOfLeafNodes( m_pRoot, leafNodeSet );
00168     //Update( leafNodeSet );
00169     Update( GetListOfLeafNodes() );
00170 }
00171 //-----------------------------------------------------------------------------
00172 // Update
00173 template <typename T>
00174 void BVHTree<T>::Update ( std::set< BVHNode<T> * > & nodeSet )
00175 {
00176     if ( nodeSet.empty() )  return;
00177     std::set< BVHNode<T> * >::iterator nodeSetIterator;
00178     std::set< BVHNode<T> * > parentNodeSet;
00179     for ( nodeSetIterator = nodeSet.begin(); nodeSetIterator != nodeSet.end(); ++nodeSetIterator ) {
00180         (*nodeSetIterator)->Update();
00181         if ( (*nodeSetIterator)->Parent() ) {
00182             parentNodeSet.insert( (*nodeSetIterator)->Parent() );
00183         }
00184     }
00185     Update( parentNodeSet );
00186 }
00187 //-----------------------------------------------------------------------------
00188 
00189 
00190 /*
00191 //=============================================================================
00192 // CALCULATE AND SAVE TRANSFORMATIONS
00193 //-----------------------------------------------------------------------------
00194 template <typename T>
00195 void BVHTree<T>::CalAndSaveTransformations ( 
00196     BoundingVolume<T> const * const pBV )
00197 {
00198     // m_FwdTransformMatrix[0]
00199     m_FwdTransformMatrix[0].MakeIdentity();
00200 
00201     // m_FwdTransformMatrix[1]
00202     m_FwdTransformMatrix[1] = pBV->GetTransform().GetMatrixTransform();
00203 
00204     // Inversed Matrices
00205     m_InvTransformMatrix[0].MakeIdentity();
00206     m_InvTransformMatrix[1] = m_FwdTransformMatrix[1].GetInverse();
00207 }
00208 //-----------------------------------------------------------------------------
00209 template <typename T>
00210 void BVHTree<T>::CalAndSaveTransformations ( 
00211     BoundingVolume<T> const * const pBV, 
00212     Matrix4x4<T> const & transformB )
00213 {
00214     // m_FwdTransformMatrix[0]
00215     m_FwdTransformMatrix[0].MakeIdentity();
00216 
00217     // m_FwdTransformMatrix[1]
00218     m_FwdTransformMatrix[1] = pBV->GetTransform().GetMatrixTransform();
00219 
00220     // Inversed Matrices
00221     m_InvTransformMatrix[0].MakeIdentity();
00222     m_InvTransformMatrix[1] = m_FwdTransformMatrix[1].GetInverse();
00223 }
00224 //-----------------------------------------------------------------------------
00225 template <typename T>
00226 void BVHTree<T>::CalAndSaveTransformations ( 
00227     Matrix4x4<T> const & transformA, 
00228     BoundingVolume<T> const * const pBV )
00229 {
00230     // m_FwdTransformMatrix[0]
00231     m_FwdTransformMatrix[0].MakeIdentity();
00232 
00233     // m_FwdTransformMatrix[1]
00234     m_FwdTransformMatrix[1] = pBV->GetTransform().GetMatrixTransform();
00235 
00236     // Inversed Matrices
00237     m_InvTransformMatrix[0] = transformA.GetInverse();
00238     m_InvTransformMatrix[1] = m_FwdTransformMatrix[1].GetInverse();
00239 }
00240 //-----------------------------------------------------------------------------
00241 template <typename T>
00242 void BVHTree<T>::CalAndSaveTransformations ( 
00243     Matrix4x4<T> const & transformA, 
00244     BoundingVolume<T> const * const pBV, 
00245     Matrix4x4<T> const & transformB )
00246 {
00247     // m_FwdTransformMatrix[0]
00248     m_FwdTransformMatrix[0] = transformB;
00249 
00250     // m_FwdTransformMatrix[1]
00251     m_FwdTransformMatrix[1] = m_FwdTransformMatrix[0] * pBV->GetTransform().GetMatrixTransform();
00252 
00253     // Inversed Matrices
00254     m_InvTransformMatrix[0] = transformA.GetInverse();
00255     m_InvTransformMatrix[1] = m_FwdTransformMatrix[1].GetInverse();
00256 }
00257 //-----------------------------------------------------------------------------
00258 // CALCULATE AND SAVE TRANSFORMATIONS
00259 //=============================================================================
00260 //*/
00261 
00262 
00263 
00264 //*
00265 //=============================================================================
00266 // BINARY AABB BOUNDING VOLUME HIERARCHY TREE
00267 //-----------------------------------------------------------------------------
00268 template <typename T>
00269 BVHTree<T> * BVHTree<T>::BAABBBuild ( 
00270         TransformationSupport<T> & transform,   // I/O: Transform
00271         const std::list< HEFace<T> * > & heFaceList,    // I/P half-edge face list
00272         BVHTree<T> * cdtree )           // O/P pointer to BVHTree
00273 {
00274     //std::cout << "BAABBBuild (before): " << cdtree << std::endl;
00275     BVHNode<T> *node = CreateBVHNodeBAABB( NULL, heFaceList );
00276     cdtree = new BVHTree<T>( transform, Enum::BVH_TREE_BINARY_AABB, 1, node );
00277     //FindOBBOfFaceList( heFaceList, node );
00278     Vector3<T> U, V, W;
00279     FindOBBOfFaceList( heFaceList, node->GetCenter(), U, V, W );
00280 //  node->listHEFace  = heFaceList;         // DEBUG
00281     if ( node ) BAABBBuildChildren( node, heFaceList, U );
00282     //std::cout << "BAABBBuild (after): " << cdtree << std::endl;
00283     return cdtree;
00284 }
00285 //-----------------------------------------------------------------------------
00286 // Create binary child AABBs
00287 template <typename T>
00288 void BVHTree<T>::BAABBBuildChildren ( 
00289     BVHNode<T> * pParentNode, 
00290     const std::list< HEFace<T> * > & heFaceList, 
00291     Vector3<T> const & principleVector )
00292 {
00293     int size = static_cast<int>( heFaceList.size() );
00294     std::list< HEFace<T> * > leftGroup, rightGroup;
00295     //---------------------------------------------------------------
00296     assert( pParentNode );          // ASSERT
00297     BVHNode<T> * leftChild  = NULL;
00298     BVHNode<T> * rightChild = NULL;
00299     //---------------------------------------------------------------
00300     // CASE: one face
00301     // This is a leaf node.
00302     assert( size > 0 );         // ASSERT
00303     if ( 1 == size ) {
00304         return;
00305     }
00306     //---------------------------------------------------------------
00307     // CASE: two faces
00308     // Create Two Leaf Nodes
00309     if ( 2 == size ) {
00310         //-------------------------------------------------
00311         // Separate two faces into left and right groups
00312         std::list< HEFace<T> * >::const_iterator face = heFaceList.begin();
00313         leftGroup.push_back( *face );
00314         ++face;
00315         rightGroup.push_back( *face );
00316         //-------------------------------------------------
00317         // Create Left Leaf Node
00318         leftChild  = CreateBVHNodeBAABB( pParentNode, leftGroup );
00319 //      leftChild->listHEFace  = leftGroup;         // DEBUG
00320         pParentNode->Child( 0, leftChild );
00321         //-------------------------------------------------
00322         // Create Right Leaf Node
00323         rightChild = CreateBVHNodeBAABB( pParentNode, rightGroup );
00324 //      rightChild->listHEFace = rightGroup;        // DEBUG
00325         pParentNode->Child( 1, rightChild );
00326         return;
00327     }
00328     //---------------------------------------------------------------
00329     // CASE: more than two faces
00330     // Didive into two groups
00331     BAABBDivideToFaceGroups(    heFaceList, leftGroup, rightGroup, 
00332                                 pParentNode->GetCenter(), 
00333                                 principleVector );
00334     //---------------------------------------------------------------
00335     // CASE: more than two faces and the divider failed to divide the face list
00336     if (   static_cast<int>( leftGroup.size() )  == size 
00337         || static_cast<int>( rightGroup.size() ) == size ) {
00338         //std::cout << "Total    : " << size;
00339         //std::cout << "; Left  Grp: " << leftGroup.size();
00340         //std::cout << "; Right Grp: " << rightGroup.size() << std::endl;
00341         leftGroup.clear();
00342         rightGroup.clear();
00343         std::list< HEFace<T> * >::const_iterator face = heFaceList.begin();
00344         int i = 0;
00345         for ( ; i < size/2; ++i ) {
00346             leftGroup.push_back( *face );
00347             ++face;
00348         }
00349         for ( ; i < size; ++i ) {
00350             rightGroup.push_back( *face );
00351             ++face;
00352         }
00353     }
00354     Vector3<T> U, V, W;
00355     //---------------------------------------------------------------
00356     // Create Left Child Node
00357     leftChild  = CreateBVHNodeBAABB( pParentNode, leftGroup );
00358     FindOBBOfFaceList( leftGroup, leftChild->GetCenter(), U, V, W );
00359 //  leftChild->listHEFace  = leftGroup;         // DEBUG
00360     pParentNode->Child( 0, leftChild );
00361     BAABBBuildChildren( leftChild, leftGroup, U );
00362     //---------------------------------------------------------------
00363     // Create Right Child Node
00364     rightChild = CreateBVHNodeBAABB( pParentNode, rightGroup );
00365     FindOBBOfFaceList( rightGroup, rightChild->GetCenter(), U, V, W );
00366 //  rightChild->listHEFace = rightGroup;        // DEBUG
00367     pParentNode->Child( 1, rightChild );
00368     BAABBBuildChildren( rightChild, rightGroup, U );
00369 
00370     /*
00371     int size = static_cast<int>( heFaceList.size() );
00372     std::list< HEFace<T> * > leftGroup, rightGroup;
00373     //---------------------------------------------------------------
00374     // Didive into two groups
00375     BAABBDivideToFaceGroups(    heFaceList, leftGroup, rightGroup, 
00376                                 pParentNode->GetCenter(), 
00377                                 principleVector );
00378     //---------------------------------------------------------------
00379     assert( pParentNode );          // ASSERT
00380     BVHNode<T> * leftChild = NULL;
00381     BVHNode<T> * rightChild = NULL;
00382     if ( 2 < static_cast<int>( leftGroup.size() ) && static_cast<int>( leftGroup.size() ) < size ) {
00383         leftChild  = CreateBVHNodeBAABB( pParentNode, leftGroup );
00384         //FindOBBOfFaceList( leftGroup, leftChild );
00385         Vector3<T> U, V, W;
00386         FindOBBOfFaceList( leftGroup, leftChild->GetCenter(), U, V, W );
00387         leftChild->listHEFace  = leftGroup;         // DEBUG
00388         pParentNode->Child( 0, leftChild );
00389         BAABBBuildChildren( leftChild, leftGroup, U );
00390     }
00391     if ( 2 < static_cast<int>( rightGroup.size() ) && static_cast<int>( rightGroup.size() ) < size ) {
00392         rightChild = CreateBVHNodeBAABB( pParentNode, rightGroup );
00393         //FindOBBOfFaceList( rightGroup, rightChild );
00394         Vector3<T> U, V, W;
00395         FindOBBOfFaceList( rightGroup, rightChild->GetCenter(), U, V, W );
00396         rightChild->listHEFace = rightGroup;        // DEBUG
00397         pParentNode->Child( 1, rightChild );
00398         BAABBBuildChildren( rightChild, rightGroup, U );
00399     }
00400     //*/
00401 }
00402 //-----------------------------------------------------------------------------
00403 // Find the group that this face belongs to
00404 template <typename T>
00405 int BVHTree<T>::BAABBDetermineFaceGroup ( HEFace<T> * face, 
00406                                       const Vector3<T> & center, 
00407                                       const Vector3<T> & direction )
00408 {
00409     //-------------------------------------------------------------------------
00410     // Divided into an axis positive and negative
00411     //---------------------------------------------------------------
00412     // REMARK:
00413     //   To speed thing up, we can evaluate only the first vertex of the polygon.
00414     //---------------------------------------------------------------
00415     // Determine from all vertices
00416     int value = 0;
00417     HEHalfEdge<T> * firstHalfEdge = face->IncidentHalfEdge();
00418     HEHalfEdge<T> * halfEdge = firstHalfEdge;
00419     Vector3<T> vertex;
00420     do {
00421         //vertex = halfEdge->Vertex()->GetPosition() - center;
00422         //if ( vertex.GetX() >= 0 ) ++value;
00423         //else                      --value;
00424         if ( (halfEdge->Vertex()->GetPosition() - center) * direction >= 0 )
00425             ++value;
00426         else
00427             --value;
00428         halfEdge = halfEdge->Next();
00429     } while ( halfEdge != firstHalfEdge );
00430     //---------------------------------------------------------------
00431     // Determine the group (left or right)
00432     return  value >= 0 ? 1 : 0;
00433 }
00434 //-----------------------------------------------------------------------------
00435 template <typename T>
00436 void BVHTree<T>::BAABBDivideToFaceGroups ( 
00437                 const std::list< HEFace<T> * > & inputFaces,    // input
00438                 std::list< HEFace<T> * > & group1,              // output group1
00439                 std::list< HEFace<T> * > & group2,              // output group2
00440                 const Vector3<T> & center, 
00441                 const Vector3<T> & direction )
00442 {
00443     std::list< HEFace<T> * >::const_iterator face;
00444     for ( face = inputFaces.begin(); face != inputFaces.end(); ++face ) {
00445         if ( BAABBDetermineFaceGroup( *face, center, direction ) == 1 )
00446             group1.push_back( *face );
00447         else
00448             group2.push_back( *face );
00449     }
00450 }
00451 //-----------------------------------------------------------------------------
00452 // Create a new sphere bounding volume node from the face list
00453 template <typename T>
00454 BVHNode<T> * BVHTree<T>::CreateBVHNodeBAABB ( 
00455                         BVHNode<T> * pParentNode, 
00456                         const std::list< HEFace<T> * > & heFaceList )
00457 {
00458     //*
00459     Vector3<T> AABB[2];
00460     //HEVertex<T> * vertex = m_listVertex->Head();
00461     std::list< HEFace<T> * >::const_iterator face = heFaceList.begin();
00462     HEHalfEdge<T> * firstHalfEdge = (*face)->IncidentHalfEdge();
00463     HEHalfEdge<T> * halfEdge = firstHalfEdge;
00464     Vector3<T> vertex = halfEdge->Vertex()->GetPosition();
00465     AABB[0] = AABB[1] = vertex;
00466     //---------------------------------------------------------------
00467     // For Each Face
00468     for ( ; face != heFaceList.end(); ++face ) {
00469         halfEdge = firstHalfEdge = (*face)->IncidentHalfEdge();
00470         //-------------------------------------------------
00471         // For Each Vertex
00472         do {
00473             vertex = halfEdge->Vertex()->GetPosition();
00474             // Find the lowest an the highest of x, y, and z
00475             // AABB[0] is min and AABB[1] is max
00476             if      ( AABB[0][0] > vertex[0] )  AABB[0][0] = vertex[0];
00477             else if ( AABB[1][0] < vertex[0] )  AABB[1][0] = vertex[0];
00478             if      ( AABB[0][1] > vertex[1] )  AABB[0][1] = vertex[1];
00479             else if ( AABB[1][1] < vertex[1] )  AABB[1][1] = vertex[1];
00480             if      ( AABB[0][2] > vertex[2] )  AABB[0][2] = vertex[2];
00481             else if ( AABB[1][2] < vertex[2] )  AABB[1][2] = vertex[2];
00482             // Next vertex
00483             halfEdge = halfEdge->Next();
00484         } while ( halfEdge != firstHalfEdge );
00485     }
00486     /*
00487     //---------------------------------------------------------------
00488     // Find the bounding volume center from the AABB
00489     Vector3<T> vCenter( ( AABB[0][0] + AABB[1][0] ) / 2.0,
00490                         ( AABB[0][1] + AABB[1][1] ) / 2.0,
00491                         ( AABB[0][2] + AABB[1][2] ) / 2.0 );
00492     //*/
00493     /*
00494     //---------------------------------------------------------------
00495     // Find the Sphere Bounding Volume
00496     T radius = 0, squaredLength;
00497     for ( face = heFaceList.begin(); face != heFaceList.end(); ++face ) {
00498         halfEdge = firstHalfEdge = (*face)->IncidentHalfEdge();
00499         //-------------------------------------------------
00500         do {
00501             vertex = halfEdge->Vertex()->GetPosition();
00502             squaredLength = (vertex - vCenter).SquaredLength();
00503             if ( squaredLength > radius )   radius = squaredLength;
00504             halfEdge = halfEdge->Next();
00505         } while ( halfEdge != firstHalfEdge );
00506     }
00507     radius = sqrt( radius );
00508     //*/
00509     //---------------------------------------------------------------
00510     // Make the root node
00511     //-------------------------------------------
00512     // BVHNode Constructor
00513     //   BVHNode<T>(    Enum::CD type,
00514     //                  int id, 
00515     //                  BVHNode<T> * parent, 
00516     //                  BVHNode<T> ** children )
00517     //-------------------------------------------
00518     BVHNode<T> * node = new BVHNode<T>( Enum::BVH_NODE_BINARY_AABB, 
00519                                 -1, pParentNode, NULL );
00520     //std::cout << node << "\n";
00521     //std::cout << node->GetCenter() << std::endl;
00522     //node->SetCenter( vCenter );
00523     node->SetMinPt( AABB[0] );
00524     node->SetMaxPt( AABB[1] );
00525     //std::cout << node->GetCenter() << std::endl;
00526     //node->SetRadius( radius );
00527     return node;
00528 }
00529 //*/
00530 //-----------------------------------------------------------------------------
00531 //=============================================================================
00532 
00533 
00534 
00535 
00536 
00537 
00538 
00539 
00540 
00541 
00542 //*
00543 //=============================================================================
00544 // BINARY OBB BOUNDING VOLUME HIERARCHY TREE
00545 //-----------------------------------------------------------------------------
00546 template <typename T>
00547 BVHTree<T> * BVHTree<T>::BOBBBuild ( 
00548         TransformationSupport<T> & transform,   // I/O: Transform
00549         const std::list< HEFace<T> * > & heFaceList,    // I/P half-edge face list
00550         BVHTree<T> * cdtree )           // O/P pointer to BVHTree
00551 {
00552     //std::cout << "BOBBBuild (before): " << cdtree << std::endl;
00553     BVHNode<T> *node = CreateBVHNodeBOBB( NULL, heFaceList );
00554     cdtree = new BVHTree<T>( transform, Enum::BVH_TREE_BINARY_OBB, 1, node );
00555     //FindOBBOfFaceList( heFaceList, node );
00556     Vector3<T> U, V, W;
00557     FindOBBOfFaceList( heFaceList, node->GetCenter(), U, V, W );
00558     node->SetPrincipleComponents( U, V, W );
00559 //  node->listHEFace  = heFaceList;         // DEBUG
00560     if ( node ) BOBBBuildChildren( node, heFaceList, U );
00561     //std::cout << "BOBBBuild (after): " << cdtree << std::endl;
00562 
00563     FindListOfLeafNodes();
00564 
00565     return cdtree;
00566 }
00567 //-----------------------------------------------------------------------------
00568 // Create binary child OBBs
00569 template <typename T>
00570 void BVHTree<T>::BOBBBuildChildren ( 
00571     BVHNode<T> * pParentNode, 
00572     const std::list< HEFace<T> * > & heFaceList, 
00573     Vector3<T> const & principleVector )
00574 {
00575     int size = static_cast<int>( heFaceList.size() );
00576     std::list< HEFace<T> * > leftGroup, rightGroup;
00577     //---------------------------------------------------------------
00578     assert( pParentNode );          // ASSERT
00579     BVHNode<T> * leftChild  = NULL;
00580     BVHNode<T> * rightChild = NULL;
00581     //---------------------------------------------------------------
00582     // CASE: one face
00583     // This is a leaf node.
00584     assert( size > 0 );         // ASSERT
00585     if ( 1 == size ) {
00586         return;
00587     }
00588     //---------------------------------------------------------------
00589     // CASE: two faces
00590     // Create Two Leaf Nodes
00591     if ( 2 == size ) {
00592         //-------------------------------------------------
00593         // Separate two faces into left and right groups
00594         std::list< HEFace<T> * >::const_iterator face = heFaceList.begin();
00595         leftGroup.push_back( *face );
00596         ++face;
00597         rightGroup.push_back( *face );
00598         //-------------------------------------------------
00599         // Create Left Leaf Node
00600         leftChild  = CreateBVHNodeBOBB( pParentNode, leftGroup );
00601 //      leftChild->listHEFace  = leftGroup;         // DEBUG
00602         pParentNode->Child( 0, leftChild );
00603         //-------------------------------------------------
00604         // Create Right Leaf Node
00605         rightChild = CreateBVHNodeBOBB( pParentNode, rightGroup );
00606 //      rightChild->listHEFace = rightGroup;        // DEBUG
00607         pParentNode->Child( 1, rightChild );
00608         return;
00609     }
00610     //---------------------------------------------------------------
00611     // Didive into two groups
00612     // CASE: more than two faces
00613     BOBBDivideToFaceGroups( heFaceList, leftGroup, rightGroup, 
00614                                 pParentNode->GetCenter(), 
00615                                 principleVector );
00616     //---------------------------------------------------------------
00617     // CASE: more than two faces and the divider failed to divide the face list
00618     if (   static_cast<int>( leftGroup.size() )  == size 
00619         || static_cast<int>( rightGroup.size() ) == size ) {
00620         //std::cout << "Total    : " << size;
00621         //std::cout << "; Left  Grp: " << leftGroup.size();
00622         //std::cout << "; Right Grp: " << rightGroup.size() << std::endl;
00623         leftGroup.clear();
00624         rightGroup.clear();
00625         std::list< HEFace<T> * >::const_iterator face = heFaceList.begin();
00626         int i = 0;
00627         for ( ; i < size/2; ++i ) {
00628             leftGroup.push_back( *face );
00629             ++face;
00630         }
00631         for ( ; i < size; ++i ) {
00632             rightGroup.push_back( *face );
00633             ++face;
00634         }
00635     }
00636     Vector3<T> U, V, W;
00637     //---------------------------------------------------------------
00638     // Create Left Child Node
00639     leftChild  = CreateBVHNodeBOBB( pParentNode, leftGroup );
00640     FindOBBOfFaceList( leftGroup, leftChild->GetCenter(), U, V, W );
00641     leftChild->SetPrincipleComponents( U, V, W );
00642 //  leftChild->listHEFace  = leftGroup;         // DEBUG
00643     pParentNode->Child( 0, leftChild );
00644     BOBBBuildChildren( leftChild, leftGroup, U );
00645     //---------------------------------------------------------------
00646     // Create Right Child Node
00647     rightChild = CreateBVHNodeBOBB( pParentNode, rightGroup );
00648     FindOBBOfFaceList( rightGroup, rightChild->GetCenter(), U, V, W );
00649     rightChild->SetPrincipleComponents( U, V, W );
00650 //  rightChild->listHEFace = rightGroup;        // DEBUG
00651     pParentNode->Child( 1, rightChild );
00652     BOBBBuildChildren( rightChild, rightGroup, U );
00653 
00654     /*
00655     int size = static_cast<int>( heFaceList.size() );
00656     std::list< HEFace<T> * > leftGroup, rightGroup;
00657     //---------------------------------------------------------------
00658     // Didive into two groups
00659     BOBBDivideToFaceGroups( heFaceList, leftGroup, rightGroup, 
00660                                 pParentNode->GetCenter(), 
00661                                 principleVector );
00662     //---------------------------------------------------------------
00663     assert( pParentNode );          // ASSERT
00664     BVHNode<T> * leftChild = NULL;
00665     BVHNode<T> * rightChild = NULL;
00666     if ( 2 < static_cast<int>( leftGroup.size() ) && static_cast<int>( leftGroup.size() ) < size ) {
00667         leftChild  = CreateBVHNodeBOBB( pParentNode, leftGroup );
00668         //FindOBBOfFaceList( leftGroup, leftChild );
00669         Vector3<T> U, V, W;
00670         FindOBBOfFaceList( leftGroup, leftChild->GetCenter(), U, V, W );
00671         leftChild->SetPrincipleComponents( U, V, W );
00672         leftChild->listHEFace  = leftGroup;         // DEBUG
00673         pParentNode->Child( 0, leftChild );
00674         BOBBBuildChildren( leftChild, leftGroup, U );
00675     }
00676     if ( 2 < static_cast<int>( rightGroup.size() ) && static_cast<int>( rightGroup.size() ) < size ) {
00677         rightChild = CreateBVHNodeBOBB( pParentNode, rightGroup );
00678         //FindOBBOfFaceList( rightGroup, rightChild );
00679         Vector3<T> U, V, W;
00680         FindOBBOfFaceList( rightGroup, rightChild->GetCenter(), U, V, W );
00681         rightChild->SetPrincipleComponents( U, V, W );
00682         rightChild->listHEFace = rightGroup;        // DEBUG
00683         pParentNode->Child( 1, rightChild );
00684         BOBBBuildChildren( rightChild, rightGroup, U );
00685     }
00686     //*/
00687 }
00688 //-----------------------------------------------------------------------------
00689 // Find the group that this face belongs to
00690 template <typename T>
00691 int BVHTree<T>::BOBBDetermineFaceGroup ( HEFace<T> * face, 
00692                                       const Vector3<T> & center, 
00693                                       const Vector3<T> & direction )
00694 {
00695     //-------------------------------------------------------------------------
00696     // Divided into an axis positive and negative
00697     //---------------------------------------------------------------
00698     // REMARK:
00699     //   To speed thing up, we can evaluate only the first vertex of the polygon.
00700     //---------------------------------------------------------------
00701     // Determine from all vertices
00702     int value = 0;
00703     HEHalfEdge<T> * firstHalfEdge = face->IncidentHalfEdge();
00704     HEHalfEdge<T> * halfEdge = firstHalfEdge;
00705     Vector3<T> vertex;
00706     do {
00707         //vertex = halfEdge->Vertex()->GetPosition() - center;
00708         //if ( vertex.GetX() >= 0 ) ++value;
00709         //else                      --value;
00710         if ( (halfEdge->Vertex()->GetPosition() - center) * direction >= 0 )
00711             ++value;
00712         else
00713             --value;
00714         halfEdge = halfEdge->Next();
00715     } while ( halfEdge != firstHalfEdge );
00716     //---------------------------------------------------------------
00717     // Determine the group (left or right)
00718     return  value >= 0 ? 1 : 0;
00719 }
00720 //-----------------------------------------------------------------------------
00721 template <typename T>
00722 void BVHTree<T>::BOBBDivideToFaceGroups ( 
00723                 const std::list< HEFace<T> * > & inputFaces,    // input
00724                 std::list< HEFace<T> * > & group1,              // output group1
00725                 std::list< HEFace<T> * > & group2,              // output group2
00726                 const Vector3<T> & center, 
00727                 const Vector3<T> & direction )
00728 {
00729     std::list< HEFace<T> * >::const_iterator face;
00730     for ( face = inputFaces.begin(); face != inputFaces.end(); ++face ) {
00731         if ( BOBBDetermineFaceGroup( *face, center, direction ) == 1 )
00732             group1.push_back( *face );
00733         else
00734             group2.push_back( *face );
00735     }
00736 }
00737 //-----------------------------------------------------------------------------
00738 // Create a new sphere bounding volume node from the face list
00739 template <typename T>
00740 BVHNode<T> * BVHTree<T>::CreateBVHNodeBOBB ( 
00741                         BVHNode<T> * pParentNode, 
00742                         const std::list< HEFace<T> * > & heFaceList )
00743 {
00744     //*
00745     Vector3<T> AABB[2];
00746     //HEVertex<T> * vertex = m_listVertex->Head();
00747     std::list< HEFace<T> * >::const_iterator face = heFaceList.begin();
00748     HEHalfEdge<T> * firstHalfEdge = (*face)->IncidentHalfEdge();
00749     HEHalfEdge<T> * halfEdge = firstHalfEdge;
00750     Vector3<T> vertex = halfEdge->Vertex()->GetPosition();
00751     AABB[0] = AABB[1] = vertex;
00752     //---------------------------------------------------------------
00753     // For Each Face
00754     for ( ; face != heFaceList.end(); ++face ) {
00755         halfEdge = firstHalfEdge = (*face)->IncidentHalfEdge();
00756         //-------------------------------------------------
00757         // For Each Vertex
00758         do {
00759             vertex = halfEdge->Vertex()->GetPosition();
00760             // Find the lowest an the highest of x, y, and z
00761             // AABB[0] is min and AABB[1] is max
00762             if      ( AABB[0][0] > vertex[0] )  AABB[0][0] = vertex[0];
00763             else if ( AABB[1][0] < vertex[0] )  AABB[1][0] = vertex[0];
00764             if      ( AABB[0][1] > vertex[1] )  AABB[0][1] = vertex[1];
00765             else if ( AABB[1][1] < vertex[1] )  AABB[1][1] = vertex[1];
00766             if      ( AABB[0][2] > vertex[2] )  AABB[0][2] = vertex[2];
00767             else if ( AABB[1][2] < vertex[2] )  AABB[1][2] = vertex[2];
00768             // Next vertex
00769             halfEdge = halfEdge->Next();
00770         } while ( halfEdge != firstHalfEdge );
00771     }
00772     //---------------------------------------------------------------
00773     // Find the bounding volume center from the AABB
00774     Vector3<T> vCenter( ( AABB[0][0] + AABB[1][0] ) / 2.0,
00775                         ( AABB[0][1] + AABB[1][1] ) / 2.0,
00776                         ( AABB[0][2] + AABB[1][2] ) / 2.0 );
00777     /*
00778     //---------------------------------------------------------------
00779     // Find the Sphere Bounding Volume
00780     T radius = 0, squaredLength;
00781     for ( face = heFaceList.begin(); face != heFaceList.end(); ++face ) {
00782         halfEdge = firstHalfEdge = (*face)->IncidentHalfEdge();
00783         //-------------------------------------------------
00784         do {
00785             vertex = halfEdge->Vertex()->GetPosition();
00786             squaredLength = (vertex - vCenter).SquaredLength();
00787             if ( squaredLength > radius )   radius = squaredLength;
00788             halfEdge = halfEdge->Next();
00789         } while ( halfEdge != firstHalfEdge );
00790     }
00791     radius = sqrt( radius );
00792     //*/
00793     //---------------------------------------------------------------
00794     // Make the root node
00795     //-------------------------------------------
00796     // BVHNode Constructor
00797     //   BVHNode<T>(    Enum::CD type,
00798     //                  int id, 
00799     //                  BVHNode<T> * parent, 
00800     //                  BVHNode<T> ** children )
00801     //-------------------------------------------
00802     BVHNode<T> * node = new BVHNode<T>( Enum::BVH_NODE_BINARY_OBB, 
00803                                 -1, pParentNode, NULL );
00804     //std::cout << node << "\n";
00805     //std::cout << node->GetCenter() << std::endl;
00806     node->SetCenter( vCenter );
00807     //std::cout << node->GetCenter() << std::endl;
00808     //node->SetRadius( radius );
00809     return node;
00810 }
00811 //*/
00812 //-----------------------------------------------------------------------------
00813 //=============================================================================
00814 
00815 
00816 
00817 
00818 
00819 
00820 
00821 
00822 
00823 
00824 
00825 
00826 
00827 
00828 
00829 //=============================================================================
00830 //-----------------------------------------------------------------------------
00831 // Find OOB (Oriented Bounding Box) (see OBB of Gottschalk, et al.)
00832 // Gottschalk, et al. triangulate all polygons composed of more than three edges.
00833 // Then find 'mean' and 3-by-3 'covariance matrix'
00834 // This 'covariance matrix' is a symmetric matrix, hence all of its eigenvalue 
00835 // are real and its eigenvectors are mutually orthogonal.
00836 // The normalized eigenvectors are used as a basis for OBB.
00837 // Then find the extremal vertices along each axis of this basis, and size the 
00838 // bounding box, oriented with the basis vectors.
00839 // m = 1/(3n) * Sum_{i=0}^n ( p^i + q^i + r^i )
00840 // C_{jk} = 1/(3n) * Sum_{i=0}^n ( (p_j^ihat)*(p_k^ihat) + (q_j^ihat)*(q_k^ihat) + (r_j^ihat)*(r_k^ihat) )
00841 // where
00842 //   n is the number of triangles
00843 //   p^i, q^i, and r^i are the first, second, and third vertex of triangle i.
00844 //   p_j^ihat is the j component of first vertex subtracted by m_j
00845 //   remark: (i=x, j=y, k=z)
00846 //*****************************************************************************
00847 // m = 1/(3n) * Sum_{i=0}^n ( p^i + q^i + r^i )
00848 // C_{11} = 1/(3n) * Sum_{i=0}^n ( Sum_{v=0}^3 ( (v_i_x - m_x)^2 ) )
00849 // C_{22} = 1/(3n) * Sum_{i=0}^n ( Sum_{v=0}^3 ( (v_i_y - m_y)^2 ) )
00850 // C_{33} = 1/(3n) * Sum_{i=0}^n ( Sum_{v=0}^3 ( (v_i_z - m_y)^2 ) )
00851 // C_{12} = C_{21} = Sum_{i=0}^n ( Sum_{v=0}^3 ( (v_i_x - m_x)*(v_i_y - m_y) ) )
00852 // C_{13} = C_{31} = Sum_{i=0}^n ( Sum_{v=0}^3 ( (v_i_x - m_x)*(v_i_z - m_z) ) )
00853 // C_{23} = C_{32} = Sum_{i=0}^n ( Sum_{v=0}^3 ( (v_i_y - m_y)*(v_i_z - m_z) ) )
00854 // For a polygon with more than three vertices,
00855 //   the polygon is triangulated at its centroid.
00856 template <typename T>
00857 void BVHTree<T>::FindOBBOfFaceList ( 
00858             const std::list< HEFace<T> * > & heFaceList,    // I/P: face list
00859             Vector3<T> & center,    // O/P: center
00860             Vector3<T> & U,         // O/P: 1st principle component
00861             Vector3<T> & V,         // O/P: 2nd principle component
00862             Vector3<T> & W )        // O/P: 3rd principle component
00863 {
00864     //if ( heFaceList.size() == 0 ) return;
00865     assert( heFaceList.size() > 0 );            // ASSERT
00866     Vector3<T>      M( 0,0,0 );                 // Mean
00867     Matrix3x3<T>    C( 0,0,0,0,0,0,0,0,0 );     // Covariance Matrix
00868     //---------------------------------------------------------------
00869     std::list< HEFace<T> * >::const_iterator face;
00870     HEHalfEdge<T> * firstHalfEdge;
00871     HEHalfEdge<T> * halfEdge;
00872     Vector3<T>      vertex;
00873     Vector3<T>      centroid;
00874     int count, totalVertices = 0;
00875     //---------------------------------------------------------------
00876     // Calculate MEAN
00877     // For each face (polygon)
00878     for ( face = heFaceList.begin(); face != heFaceList.end(); ++face ) {
00879         //-------------------------------------------------
00880         // Determine the number of vertices of the face
00881         firstHalfEdge = halfEdge = (*face)->IncidentHalfEdge();
00882         count = 0;
00883         do {
00884             ++count;
00885             halfEdge = halfEdge->Next();    // next halfedge
00886         } while ( halfEdge != firstHalfEdge );
00887         //-------------------------------------------------
00888         // Triangle (or lower) Case
00889         if ( count <= 3 ) {
00890             totalVertices += count;
00891             do {
00892                 //-------------------------------
00893                 // Find Mean
00894                 M += halfEdge->Vertex()->GetPosition();
00895                 //-------------------------------
00896                 halfEdge = halfEdge->Next();    // next halfedge
00897             } while ( halfEdge != firstHalfEdge );
00898         }
00899         //-------------------------------------------------
00900         // Four or More Vertices Case
00901         else {
00902             totalVertices += 3*count;   // increased by 3 * count
00903             centroid.SetXYZ( 0,0,0 );
00904             do {
00905                 vertex = halfEdge->Vertex()->GetPosition();
00906                 centroid += vertex;
00907                 //-------------------------------
00908                 // Find Mean
00909                 M += vertex*2;
00910                 //-------------------------------
00911                 halfEdge = halfEdge->Next();    // next halfedge
00912             } while ( halfEdge != firstHalfEdge );
00913             //centroid /= count;
00914             M += centroid;
00915         }
00916         //-------------------------------------------------
00917     }
00918     M /= T(totalVertices);      // Final Mean
00919     //---------------------------------------------------------------
00920     // Calculate COVARIANCE MATRIX
00921     // For each face (polygon)
00922     for ( face = heFaceList.begin(); face != heFaceList.end(); ++face ) {
00923         //-------------------------------------------------
00924         // Determine the number of vertices of the face
00925         firstHalfEdge = halfEdge = (*face)->IncidentHalfEdge();
00926         count = 0;
00927         do {
00928             ++count;
00929             halfEdge = halfEdge->Next();    // next halfedge
00930         } while ( halfEdge != firstHalfEdge );
00931         //-------------------------------------------------
00932         // Triangle (or lower) Case
00933         if ( count <= 3 ) {
00934             //totalVertices += count;
00935             do {
00936                 vertex = halfEdge->Vertex()->GetPosition() - M;
00937                 //-------------------------------
00938                 // Covariance Matrix is a 3x3 symmatric matrix
00939                 C[0] += vertex.GetX() * vertex.GetX() * 2;  // C_{11}
00940                 C[4] += vertex.GetY() * vertex.GetY() * 2;  // C_{22}
00941                 C[8] += vertex.GetZ() * vertex.GetZ() * 2;  // C_{33}
00942                 C[1] += vertex.GetX() * vertex.GetY() * 2;  // C_{12} = C_{21}
00943                 C[2] += vertex.GetX() * vertex.GetZ() * 2;  // C_{13} = C_{31}
00944                 C[5] += vertex.GetY() * vertex.GetZ() * 2;  // C_{23} = C_{32}
00945                 //-------------------------------
00946                 halfEdge = halfEdge->Next();    // next halfedge
00947             } while ( halfEdge != firstHalfEdge );
00948         }
00949         //-------------------------------------------------
00950         // Four or More Vertices Case
00951         else {
00952             //totalVertices += 3*count; // increased by 3 * count
00953             centroid.SetXYZ( 0,0,0 );
00954             do {
00955                 vertex = halfEdge->Vertex()->GetPosition() - M;
00956                 centroid += vertex;
00957                 //-------------------------------
00958                 // Covariance Matrix is a 3x3 symmatric matrix
00959                 C[0] += vertex.GetX() * vertex.GetX();      // C_{11}
00960                 C[4] += vertex.GetY() * vertex.GetY();      // C_{22}
00961                 C[8] += vertex.GetZ() * vertex.GetZ();      // C_{33}
00962                 C[1] += vertex.GetX() * vertex.GetY();      // C_{12} = C_{21}
00963                 C[2] += vertex.GetX() * vertex.GetZ();      // C_{13} = C_{31}
00964                 C[5] += vertex.GetY() * vertex.GetZ();      // C_{23} = C_{32}
00965                 //-------------------------------
00966                 halfEdge = halfEdge->Next();    // next halfedge
00967             } while ( halfEdge != firstHalfEdge );
00968             vertex = centroid/T(count) - M;
00969             C[0] += vertex.GetX() * vertex.GetX();      // C_{11}
00970             C[4] += vertex.GetY() * vertex.GetY();      // C_{22}
00971             C[8] += vertex.GetZ() * vertex.GetZ();      // C_{33}
00972             C[1] += vertex.GetX() * vertex.GetY();      // C_{12} = C_{21}
00973             C[2] += vertex.GetX() * vertex.GetZ();      // C_{13} = C_{31}
00974             C[5] += vertex.GetY() * vertex.GetZ();      // C_{23} = C_{32}
00975         }
00976         //-------------------------------------------------
00977     }
00978     //---------------------------------------------------------------
00979     C[3] = C[1];
00980     C[6] = C[2];
00981     C[7] = C[5];
00982     C /= T(totalVertices);      // Final Covariance Matrix
00983     //---------------------------------------------------------------
00984     T l[3];
00985     CGMath<T>::EigValsVecsOf3x3SymMatrix( 
00986         C, l[0], l[1], l[2], U, V, W );
00987     //---------------------------------------------------------------
00988     // Find the length of each principle component
00989     Vector3<T> vec;
00990     T length, positive[3] = {0,0,0}, negative[3] = {0,0,0};
00991     //---------------------------------------------------------------
00992     // For each face (polygon)
00993     for ( face = heFaceList.begin(); face != heFaceList.end(); ++face ) {
00994         //-------------------------------------------------
00995         // For each vertex of the face
00996         firstHalfEdge = halfEdge = (*face)->IncidentHalfEdge();
00997         do {
00998             vec = halfEdge->Vertex()->GetPosition() - center;
00999             length = vec * U;
01000             if      ( length > positive[0] )    positive[0] = length;
01001             else if ( length < negative[0] )    negative[0] = length;
01002             length = vec * V;
01003             if      ( length > positive[1] )    positive[1] = length;
01004             else if ( length < negative[1] )    negative[1] = length;
01005             length = vec * W;
01006             if      ( length > positive[2] )    positive[2] = length;
01007             else if ( length < negative[2] )    negative[2] = length;
01008             halfEdge = halfEdge->Next();    // next halfedge
01009         } while ( halfEdge != firstHalfEdge );
01010         //-------------------------------------------------
01011     }
01012     //---------------------------------------------------------------
01013     // Adjust the center and the length of principle components
01014     T adjustedValue;
01015     length = (positive[0] - negative[0]) / T(2.0);
01016     adjustedValue = positive[0] - length;
01017     center = center + U*adjustedValue;
01018     U *= length;
01019     length = (positive[1] - negative[1]) / T(2.0);
01020     adjustedValue = positive[1] - length;
01021     center = center + V*adjustedValue;
01022     V *= length;
01023     length = (positive[2] - negative[2]) / T(2.0);
01024     adjustedValue = positive[2] - length;
01025     center = center + W*adjustedValue;
01026     W *= length;
01027     //---------------------------------------------------------------
01028 }
01029 //-----------------------------------------------------------------------------
01030 //=============================================================================
01031 
01032 //-----------------------------------------------------------------------------
01033 #if defined(__gl_h_) || defined(__GL_H__)
01034 //=============================================================================
01035 // DrawByOpenGL
01036 //-----------------------------------------------------------------------------
01037 template <typename T>
01038 void BVHTree<T>::DrawByOpenGL () const
01039 {
01040     if ( m_pRoot ) {
01041         glPushMatrix();
01042             GetTransform().TransformByOpenGLForDrawing();
01043             m_pRoot->DrawByOpenGL();
01044         glPopMatrix();
01045     }
01046 }
01047 //-----------------------------------------------------------------------------
01048 template <typename T>
01049 void BVHTree<T>::DrawByOpenGL ( int currentLevel, int startLevel, int endLevel ) const
01050 {
01051     if ( m_pRoot ) {
01052         glPushMatrix();
01053             GetTransform().TransformByOpenGLForDrawing();
01054             m_pRoot->DrawByOpenGL( currentLevel, startLevel, endLevel );
01055         glPopMatrix();
01056     }
01057 }
01058 //-----------------------------------------------------------------------------
01059 template <typename T>
01060 void BVHTree<T>::DrawByOpenGLOnlyEndLevel () const
01061 {
01062     if ( m_pRoot ) {
01063         glPushMatrix();
01064             GetTransform().TransformByOpenGLForDrawing();
01065             m_pRoot->DrawByOpenGLOnlyEndLevel();
01066         glPopMatrix();
01067     }
01068 }
01069 //-----------------------------------------------------------------------------
01070 template <typename T>
01071 void BVHTree<T>::DrawByOpenGLCollidedNodes () const
01072 {
01073     glPushMatrix();
01074         GetTransform().TransformByOpenGLForDrawing();
01075         for ( int i = 0; i < static_cast<int>( m_svCollidedNode.size() ); ++i ) {
01076             m_svCollidedNode[i]->DrawBV();
01077             m_svCollidedNode[i]->DrawPrim();
01078         }
01079     glPopMatrix();
01080 }
01081 //-----------------------------------------------------------------------------
01082 template <typename T>
01083 void BVHTree<T>::DrawByOpenGLCollidedNodesThat ( 
01084                     TransformationSupport<T> const & transformSupport ) const
01085 {
01086     glPushMatrix();
01087         transformSupport.TransformByOpenGLForDrawing();
01088         for ( int i = 0; i < static_cast<int>( m_svCollidedNode.size() ); ++i ) {
01089             m_svCollidedNodeThat[i]->DrawBV();
01090             m_svCollidedNodeThat[i]->DrawPrim();
01091         }
01092     glPopMatrix();
01093 }
01094 //-----------------------------------------------------------------------------
01095 #endif
01096 //=============================================================================
01097 END_NAMESPACE_TAPs
01098 //34567890123456789012345678901234567890123456789012345678901234567890123456789
01099 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines