![]() |
TAPs 0.7.7.3
|
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----+----