![]() |
TAPs 0.7.7.3
|
00001 /****************************************************************************** 00002 TAPsModelSurgicalSutureWithHeadNeedle_CD.cpp 00003 ******************************************************************************/ 00008 /****************************************************************************** 00009 SUKITTI PUNAK (08/21/2009) 00010 UPDATE (09/03/2010) 00011 ******************************************************************************/ 00012 #include "TAPsModelSurgicalSutureWithHeadNeedle_CD.hpp" 00013 // Using Inclusion Model (i.e. definitions are included in declarations) 00014 // (this name.cpp is included in name.hpp) 00015 // Each friend is defined directly inside its declaration. 00016 00017 BEGIN_NAMESPACE_TAPs 00018 //============================================================================= 00019 //----------------------------------------------------------------------------- 00020 00021 // Constructor 00022 template <typename T> 00023 ModelSurgicalSutureWithHeadNeedle_CD<T>::ModelSurgicalSutureWithHeadNeedle_CD () : 00024 m_BVHTree( NULL ), 00025 m_pNeedleSharpPt( NULL ), 00026 m_pNeedleSutureConnectingPt( NULL ) 00027 {} 00028 00029 00030 // Destructor 00031 template <typename T> 00032 ModelSurgicalSutureWithHeadNeedle_CD<T>::~ModelSurgicalSutureWithHeadNeedle_CD () 00033 { 00034 DeleteCD(); 00035 } 00036 00037 00038 // Create collision detection process 00039 template <typename T> 00040 void ModelSurgicalSutureWithHeadNeedle_CD<T>::CreateCD ( 00041 RigidBodyDynamics<T> * pHeadNeedle, 00042 InteractionPoint<T> * pNeedleSharpPt, 00043 InteractionPoint<T> * pNeedleSutureConnectingPt 00044 ) 00045 { 00046 m_pHeadNeedle = pHeadNeedle; 00047 m_pNeedleSharpPt = pNeedleSharpPt; 00048 m_pNeedleSutureConnectingPt = pNeedleSutureConnectingPt; 00049 00050 m_pHeadNeedleTranslation = const_cast< Vector3<T>* >( &(pHeadNeedle->GetOriginPoint()) ); 00051 m_pHeadNeedleRotation = const_cast< Quaternion<T>* >( &(pHeadNeedle->GetOrientation()) ); 00052 00053 BuildBVHTree(); 00054 } 00055 00056 // Delete collision detection process 00057 template <typename T> 00058 void ModelSurgicalSutureWithHeadNeedle_CD<T>::DeleteCD () 00059 { 00060 if ( m_BVHTree ) { 00061 delete m_BVHTree; 00062 m_BVHTree = NULL; 00063 } 00064 } 00065 00066 // Build the BVH tree for the elastic rod 00067 template <typename T> 00068 void ModelSurgicalSutureWithHeadNeedle_CD<T>::BuildBVHTree () 00069 { 00070 //---------------------------------------------------------------- 00071 Vector3<T> center; 00072 // / ------------------- 00073 // sphere radius = ( link's radius + link's half length 00074 // \ ------------------- 00075 //T radius = m_pParameters->Radius + m_pParameters->LinkLength/2.0; 00076 //---------------------------------------------------------------- 00077 // Create Leaf Nodes 00078 int numOfLinks = m_pHeadNeedle->RefToInteractionPointGroup().GetTheSetOfInteractionPoints().size() - 1; 00079 BVHNode<T> **nodeList = new BVHNode<T> *[ numOfLinks ]; 00080 std::vector< InteractionPoint<T> >::iterator nextNode = m_pHeadNeedle->RefToInteractionPointGroup().GetTheSetOfInteractionPoints().begin(); 00081 std::vector< InteractionPoint<T> >::iterator currNode = nextNode++; 00082 00083 //* 00084 int numOfNodes = -1; 00085 for ( int i = 0; i < numOfLinks; ++i, ++currNode, ++nextNode ) { 00086 BVHNodeLeafALinkFormedByTwoPointMasses<T> * pBVNode = new BVHNodeLeafALinkFormedByTwoPointMasses<T>( 00087 //TAPs::Enum::BVH_NODE_LEAF_SPHERE_UNSPECIFIED_PRIMS, 00088 TAPs::Enum::BVH_NODE_LEAF_SPHERE_TWO_POINT_MASSES, 00089 ++numOfNodes, // node id 00090 NULL // parent node 00091 ); 00092 pBVNode->SetPtrToPrimitive_1( currNode->PtrToPointMass() ); 00093 pBVNode->SetPtrToPrimitive_2( nextNode->PtrToPointMass() ); 00094 pBVNode->Update(); 00095 nodeList[i] = pBVNode; 00096 00097 //std::cout << "NODE: " << i << ":\t" << nodeList[i]->GetRadius() << "\n"; 00098 //std::cout << "\t" << nodeList[i]->GetCenter() << "\n"; 00099 } 00100 00101 //---------------------------------------------------------------- 00102 // Create Hierarchy Nodes 00103 m_BVHTree = BuildBVHTreeRecursively( numOfNodes+1, nodeList, numOfLinks ); 00104 UpdateBVHTree(); 00105 //m_BVHTree->Update(); 00106 00107 //std::cout << "TREE1\n"; 00108 //std::cout << *m_BVHTree << "\n"; 00109 //m_BVHTree->Update(); 00110 //std::cout << "TREE2\n"; 00111 //std::cout << *m_BVHTree << "\n"; 00112 } 00113 00114 00115 // Build the BVH tree recursively (called by BuildBVHTree function) 00116 template <typename T> 00117 BVHTree<T> * ModelSurgicalSutureWithHeadNeedle_CD<T>::BuildBVHTreeRecursively ( 00118 int startID, 00119 BVHNode<T> ** childNodeList, 00120 int numOfChildNodes 00121 ) 00122 { 00123 //std::cout << "numOfChildNodes: " << numOfChildNodes << "\n"; 00124 BVHNode<T> ** parentNodeList; 00125 if ( numOfChildNodes > 1 ) { 00126 int numOfParentNodes; 00127 if ( numOfChildNodes % 2 == 0 ) { 00128 numOfParentNodes = numOfChildNodes/2; 00129 //std::cout << "numOfParentNodes (even): " << numOfParentNodes << "\n"; 00130 parentNodeList = new BVHNode<T> *[ numOfParentNodes ]; 00131 for ( int i = 0, p = 0; i < numOfChildNodes; i+=2, ++p, ++startID ) { 00132 parentNodeList[p] = new BVHNode<T>( 00133 TAPs::Enum::BVH_NODE_BINARY_SPHERE, 00134 startID, NULL, NULL ); 00135 parentNodeList[p]->Child( 0, childNodeList[i] ); 00136 parentNodeList[p]->Child( 1, childNodeList[i+1] ); 00137 } 00138 } 00139 else { 00140 numOfParentNodes = numOfChildNodes/2 + 1; 00141 //std::cout << "numOfParentNodes (odd): " << numOfParentNodes << "\n"; 00142 parentNodeList = new BVHNode<T> *[ numOfParentNodes ]; 00143 for ( int i = 0, p = 0; i < numOfChildNodes-1; i+=2, ++p, ++startID ) { 00144 parentNodeList[p] = new BVHNode<T>( 00145 TAPs::Enum::BVH_NODE_BINARY_SPHERE, 00146 startID, NULL, NULL ); 00147 parentNodeList[p]->Child( 0, childNodeList[i] ); 00148 parentNodeList[p]->Child( 1, childNodeList[i+1] ); 00149 } 00150 parentNodeList[numOfParentNodes-1] = childNodeList[numOfChildNodes-1]; 00151 } 00152 delete [] childNodeList; 00153 return BuildBVHTreeRecursively( startID, parentNodeList, numOfParentNodes ); 00154 } 00155 else { 00156 BVHTree<T> * tree = new BVHTree_BinarySphere<T>( m_DummyTransform, 00157 /*TAPs::Enum::BVH_TREE_BINARY_SPHERE,*/ startID, childNodeList[0] ); 00158 delete [] childNodeList; 00159 return tree; 00160 } 00161 } 00162 00163 00165 template <typename T> 00166 void ModelSurgicalSutureWithHeadNeedle_CD<T>::UpdateBVHTree () 00167 { 00168 if ( m_BVHTree->Root() ) { 00169 UpdateBVHNodeRecursively( m_BVHTree->Root() ); 00170 } 00171 } 00172 00173 00175 template <typename T> 00176 void ModelSurgicalSutureWithHeadNeedle_CD<T>::UpdateBVHNodeRecursively ( BVHNode<T> * node ) 00177 { 00178 if ( node->Child(0) ) { 00179 UpdateBVHNodeRecursively( node->Child(0) ); 00180 } 00181 if ( node->Child(1) ) { 00182 UpdateBVHNodeRecursively( node->Child(1) ); 00183 } 00184 //---------------------------------------------------------------- 00185 if ( node->Child(0) == NULL && node->Child(1) == NULL ) { 00186 int id = node->GetID(); 00187 //node->SetRadius( (m_prVertex[id] - m_prVertex[id+1]).Length()/2.0 + m_tRadius ); 00188 //node->SetCenter( (m_prVertex[id] + m_prVertex[id+1]) / 2.0 ); 00189 } 00190 else { 00191 node->Update(); 00192 } 00193 } 00194 00195 00196 /* 00197 // Collision Detection and Response with an MBV (Multi-Bounding Volume) object 00198 template <typename T> 00199 bool ModelSurgicalSutureWithHeadNeedle_CD<T>::CDRwith ( 00200 MultiBoundingVolume<T> * const pMBVObj, //!< a multi bounding volume object 00201 TransformationSupport<T> * const pTransform //!< an extra transformation for the MBV object 00202 ) 00203 { 00204 bool bResult = false; 00205 00206 SetOfElasticRodNodes::iterator ERNodes = m_pNodeList->begin(); 00207 00208 //--------------------------------------------------------------- 00209 TransformationSupport<T> transform; 00210 //--------------------------------------------------------------- 00211 if ( pTransform ) { 00212 transform.RefToMatrixTransform() *= pTransform->GetMatrixTransform(); 00213 } 00214 transform.RefToMatrixTransform() *= pMBVObj->GetTransform().GetMatrixTransform(); 00215 00216 // Check collision 00217 TransformationSupport<T> oldTrx( pMBVObj->GetTransform() ); // store the old transformation 00218 pMBVObj->GetTransform() = transform; // set to the new transformation 00219 bResult = this->GetBVHTree()->TestOverlapWithTillLeafNodes( pMBVObj ); // collision detection automatically uses the new transformation 00220 pMBVObj->GetTransform() = oldTrx; // restore the old transformation 00221 if ( !bResult ) return bResult; 00222 00223 // Collision response constants are scaled by the number of core simutation iterations. 00224 T timestep_sqrt = m_pParameters->TimeStep * m_pParameters->TimeStep; 00225 T Ksphere = m_pParameters->K_CDRwBV_Sphere / timestep_sqrt; 00226 T Kcylinder = m_pParameters->K_CDRwBV_Cylinder / timestep_sqrt; 00227 00228 TransformationSupport<T> savedTransform( transform ); 00229 00230 // Get the collided node lists and the collided BVs 00231 std::vector< BVsAndNodesList<T> > & cdDat = this->GetBVHTree()->GetListOfCollidedBoundingVolumesAndNodes(); 00232 00233 // Iterate all of the collided BVs 00234 std::vector< BVsAndNodesList<T> >::iterator it = cdDat.begin(); 00235 while ( it != cdDat.end() ) { 00236 BoundingVolume<T> * pBV = it->BV; 00237 assert( pBV != NULL ); 00238 transform = savedTransform; 00239 00240 //------------------------------------------------- 00241 transform.RefToMatrixTransform() *= pBV->GetTransform().GetMatrixTransform(); 00242 //------------------------------------------------- 00243 // Transform each vertex of the strand to the bounding volume coordinate 00244 //int iDeepestPoint = -1; 00245 //T tDeepestDistance = Math<T>::MAX; 00246 Vector3<T> vDirection; 00247 Vector3<T> translation( transform.GetTranslation() ); 00248 Matrix3x3<T> inversedRotMatrix( transform.GetMatrixRotation().GetInverse() ); 00249 //T distance; 00250 Vector3<T> U; // displacement vector 00251 std::vector< BVHNode<T> * >::iterator node = it->NodeList.begin(); 00252 00253 //T epsilon = m_pParameters->Radius * 0.05; // for collision response 00254 00255 switch ( pBV->GetType() ) { 00256 //--------------------------------------------- 00257 case TAPs::Enum::BOUNDING_CYLINDER: 00258 //--------------------------------------------- 00259 { 00260 // Test only points against the cylinder BV, NOT cylinders againt the BV. 00261 00262 T combinedRadius = m_pParameters->Radius + pBV->GetRadius() + m_pParameters->Offset_CD_BV_Cylinder; 00263 while ( node != it->NodeList.end() ) { 00264 BVHNodeLeafElasticRodNode<T> * Node = dynamic_cast<BVHNodeLeafElasticRodNode<T> *>( *node ); 00265 00266 // In the local coordinate of the bounding cylinder, 00267 // the cylinder axis is parallel to z-axis 00268 // where it is shifted by the cylinder center. 00269 // The cylinder has radius, height and center. 00270 // Its height is measured from -z and +z axis 00271 // where its center is situated between height/2 in -z and +z axis. 00272 Vector3<T> P1( Node->GetPtrToPrimitive_1()->Centerline[*m_pIdxCurr].GetPosition() ); 00273 Vector3<T> P2( Node->GetPtrToPrimitive_2()->Centerline[*m_pIdxCurr].GetPosition() ); 00274 P1 -= translation; 00275 P1 = inversedRotMatrix * P1; 00276 P2 -= translation; 00277 P2 = inversedRotMatrix * P2; 00278 // Shift the location of point by the cylinder center 00279 // i.e. shift the cylinder to the origin (0,0,0) 00280 P1 -= pBV->GetCenter(); 00281 P2 -= pBV->GetCenter(); 00282 00283 // Now the cylinder is centered at the origin with its axis on the z-axis 00284 // where its height is from -height/2 to +height/2. 00285 // And the input point has been transformed into the cylinder coordinate. 00286 // The test can be performed. 00287 00288 // The 1st point 00289 if ( CGMath<T>::CD_CylinderAtOrigin_vs_Point( combinedRadius, pBV->GetHeight(), P1, U ) ) { 00290 bResult = true; 00291 // Now rotate it back by the rotation matrix (from the transform matrix). 00292 // REMARK: Translation (from the transform matrix) is NOT applied back, 00293 // because U represents a displacement vector from 00294 // the input point to the cylinder surface. 00295 // I.e., the strand point is always in the world coordinates. 00296 U = transform.GetMatrixRotation() * U; 00297 00298 U *= Kcylinder * Node->GetPtrToPrimitive_1()->Centerline[*m_pIdxCurr].GetMass(); 00299 Node->GetPtrToPrimitive_1()->ExternalForce += U; 00300 00301 //U *= 1.0; 00302 //Node->GetPtrToPrimitive_1()->Centerline[*m_pIdxCurr].SetPosition( Node->GetPtrToPrimitive_1()->Centerline[*m_pIdxCurr].GetPosition() + U ); 00303 00304 } 00305 00306 // The 2nd point 00307 // SKIPPED to avoid duplicating the replusive force 00308 //if ( CGMath<T>::CD_CylinderAtOrigin_vs_Sphere( pBV->GetRadius(), pBV->GetHeight(), P2, m_pParameters->Radius, U ) ) { 00309 // bResult = true; 00310 // // Now rotate it back by the rotation matrix (from the transform matrix). 00311 // // REMARK: Translation (from the transform matrix) is NOT applied back, 00312 // // because U represents a displacement vector from 00313 // // the input point to the cylinder surface. 00314 // // I.e., the strand point is always in the world coordinates. 00315 // U = transform.GetMatrixRotation() * U; 00316 // U *= Kcylinder; 00317 // Node->GetPtrToPrimitive_2()->ExternalForce += U; 00318 //} 00319 00320 ++node; 00321 } 00322 } 00323 break; 00324 // END: BOUNDING_CYLINDER 00325 00326 //--------------------------------------------- 00327 case TAPs::Enum::BOUNDING_SPHERE: 00328 //--------------------------------------------- 00329 { 00330 // Each sphere bounding volume has its own center location and transformation. 00331 // To get the world coordinate location of the sphere, the sphere center point 00332 // is transformed by the transformation. 00333 Vector3<T> Cs = ( (transform.RefToMatrixTransform() * Vector4<T>( pBV->GetCenter() )).GetVector3() ); 00334 T Rs = ( ( transform.RefToMatrixTransform() * Vector4<T>(Cs + Vector3<T>(0,0,pBV->GetRadius())) ).GetVector3() - Cs ).Length(); 00335 00336 T combinedRadius = m_pParameters->Radius + pBV->GetRadius() + m_pParameters->Offset_CD_BV_Sphere; 00337 while ( node != it->NodeList.end() ) { 00338 00339 BVHNodeLeafElasticRodNode<T> * Node = dynamic_cast<BVHNodeLeafElasticRodNode<T> *>( *node ); 00340 00341 T ratio; 00342 Vector3<T> projPt; 00343 CGMath<T>::FindProjectedPointOnALine( 00344 Cs, // sphere BV's center 00345 Node->GetPtrToPrimitive_1()->Centerline[*m_pIdxCurr].GetPosition(), 00346 Node->GetPtrToPrimitive_2()->Centerline[*m_pIdxCurr].GetPosition(), 00347 ratio, 00348 projPt 00349 ); 00350 if ( 0 <= ratio && ratio <= 1 ) { 00351 U = projPt - Cs; 00352 if ( U.Length() < combinedRadius ) { 00353 bResult = true; 00354 // By force 00355 U *= Ksphere * Node->GetPtrToPrimitive_1()->Centerline[*m_pIdxCurr].GetMass(); 00356 Node->GetPtrToPrimitive_1()->ExternalForce += U; 00357 // The 2nd point is skipped to avoid duplicating the repulsive force 00358 //Node->GetPtrToPrimitive_2()->ExternalForce += U; 00359 } 00360 } 00361 ++node; 00362 } 00363 } 00364 break; 00365 // END: BOUNDING_SPHERE 00366 00367 }//END: switch ( pBV->GetType() ) {...} 00368 ++it; // Next Bounding Volume 00369 } 00370 return bResult; 00371 } 00372 //*/ 00373 00374 00375 /* 00376 // Collision Detection and Response with a HETriMeshOneModelMultiParts object 00377 template <typename T> 00378 bool ModelSurgicalSutureWithHeadNeedle_CD<T>::CDRwith ( 00379 TAPs::OpenGL::HETriMeshOneModelMultiParts<T> * pObj, //!< a HETriMeshOneModelMultiParts object 00380 TransformationSupport<T> * const pTransform //!< an extra transformation for the HETriMeshOneModelMultiParts object 00381 ) 00382 { 00383 bool bResult = false; 00384 00385 // IsCollide is for DEBUG 00386 SetOfElasticRodNodes::iterator it = m_pNodeList->begin(); 00387 while ( it != m_pNodeList->end() ) { 00388 it->IsCollide = false; 00389 ++it; 00390 } 00391 00392 TransformationSupport<T> transform; 00393 if ( pTransform ) { 00394 transform.RefToMatrixTransform() *= pTransform->RefToMatrixTransform(); 00395 } 00396 transform.RefToMatrixTransform() *= pObj->GetTransform().RefToMatrixTransform(); 00397 00398 // Collision Detection 00399 TransformationSupport<T> oldTrx( pObj->GetTransform() ); // store the old transformation 00400 pObj->GetTransform() = transform; // set to the new transformation 00401 bResult = GetBVHTree()->TestOverlapWithTillLeafNodes( pObj->GetBVHTree() ); // collision detection automatically uses the new transformation 00402 pObj->GetTransform() = oldTrx; // restore the old transformation 00403 if ( !bResult ) return bResult; 00404 00405 // Collision Response 00406 bResult = false; 00407 T Kc = m_pParameters->K_CDRwTriangle; 00408 00409 // The list of collided BV leaf nodes 00410 std::vector< BVHNode<T> * > & ER_BVNodes = GetBVHTree()->GetListOfCollidedNodes(); 00411 std::vector< BVHNode<T> * > & Obj_BVNodes = GetBVHTree()->GetListOfCollidedNodesThat(); 00412 std::vector< HEVertex<T> * const > vertexList; 00413 int noOfVertices; 00414 Matrix4x4<T> & TrxMat = transform.RefToMatrixTransform(); 00415 00416 for ( int i = 0; i < static_cast<int>( ER_BVNodes.size() ); ++i ) { 00417 BVHNodeLeafElasticRodNode<T> * NodeER = dynamic_cast< BVHNodeLeafElasticRodNode<T> * >( ER_BVNodes[i] ); 00418 HEFace<T> * Triangle = Obj_BVNodes[i]->GetAPrimitiveHalfEdgeFace(); 00419 vertexList = Triangle->GetPtrsToVerticesAndNumberOfVertices( noOfVertices ); 00420 Vector3<T> cylA( NodeER->GetPtrToPrimitive_1()->Centerline[*m_pIdxCurr].GetPosition() ); 00421 Vector3<T> cylB( NodeER->GetPtrToPrimitive_2()->Centerline[*m_pIdxCurr].GetPosition() ); 00422 Vector3<T> posA( (TrxMat * Vector4<T>(vertexList[0]->GetPosition())).GetVector3() ); 00423 Vector3<T> posB( (TrxMat * Vector4<T>(vertexList[1]->GetPosition())).GetVector3() ); 00424 Vector3<T> posC( (TrxMat * Vector4<T>(vertexList[2]->GetPosition())).GetVector3() ); 00425 if ( TAPs::CGMath<T>::FindIntersectionCylinderTriangle( 00426 cylA, cylB, 00427 m_pParameters->Radius + m_pParameters->Offset_CD_Triangle, 00428 posA, posB, posC 00429 ) ) { 00430 Vector3<T> triCentroid( ( posA + posB + posC ) / 3.0 ); 00431 Vector3<T> N( Triangle->GetNormal() ); 00432 N.Normalized(); 00433 Vector3<T> projPt1, projPt2; 00434 TAPs::CGMath<T>::FindProjectedPointOnAPlane( cylA, posB, N, projPt1 ); 00435 TAPs::CGMath<T>::FindProjectedPointOnAPlane( cylB, posB, N, projPt2 ); 00436 Vector3<T> V1( cylA - projPt1 ); 00437 Vector3<T> V2( cylB - projPt2 ); 00438 //Vector3<T> V1( cylA - triCentroid ); 00439 //Vector3<T> V2( cylB - triCentroid ); 00440 T value = V1 * N; 00441 if ( value < 0.0 ) { 00442 if ( NodeER->GetPtrToPrimitive_1()->SimFlags.CheckSimulationConstraints( Enum::AddOn::IGNORE_CD_FORCE ) == false ) { 00443 NodeER->GetPtrToPrimitive_1()->ExternalForce -= value*Kc * N; // adjusted by force 00444 //NodeER->GetPtrToPrimitive_1()->Centerline[*m_pIdxCurr].SetPosition( cylA - value * N ); // adjusted by position 00445 } 00446 } 00447 value = V2 * N; 00448 if ( value < 0.0 ) { 00449 if ( NodeER->GetPtrToPrimitive_2()->SimFlags.CheckSimulationConstraints( Enum::AddOn::IGNORE_CD_FORCE ) == false ) { 00450 NodeER->GetPtrToPrimitive_2()->ExternalForce -= value*Kc * N; // adjusted by force 00451 //NodeER->GetPtrToPrimitive_2()->Centerline[*m_pIdxCurr].SetPosition( cylB - value * N ); // adjusted by position 00452 } 00453 } 00454 bResult = true; 00455 00456 // DEBUG 00457 NodeER->GetPtrToPrimitive_1()->IsCollide = true; 00458 NodeER->GetPtrToPrimitive_2()->IsCollide = true; 00459 00460 } 00461 } 00462 return bResult; 00463 } 00464 //*/ 00465 //----------------------------------------------------------------------------- 00466 00467 00468 00469 00470 #if defined(__gl_h_) || defined(__GL_H__) 00471 //============================================================================= 00472 template <typename T> 00473 void ModelSurgicalSutureWithHeadNeedle_CD<T>::Draw () const 00474 { 00475 if ( m_BVHTree ) { 00476 glPushMatrix(); 00477 glPushAttrib( GL_ALL_ATTRIB_BITS ); 00478 00479 glTranslatef( m_pHeadNeedleTranslation->GetX(), m_pHeadNeedleTranslation->GetY(), m_pHeadNeedleTranslation->GetZ() ); 00480 Matrix4x4<T> orientation = m_pHeadNeedleRotation->GetRotationMatrix4x4(); 00481 GLfloat m[16] = { 00482 static_cast<GLfloat>(orientation[ 0]), static_cast<GLfloat>(orientation[ 4]), static_cast<GLfloat>(orientation[ 8]), static_cast<GLfloat>(orientation[ 12]), 00483 static_cast<GLfloat>(orientation[ 1]), static_cast<GLfloat>(orientation[ 5]), static_cast<GLfloat>(orientation[ 9]), static_cast<GLfloat>(orientation[ 13]), 00484 static_cast<GLfloat>(orientation[ 2]), static_cast<GLfloat>(orientation[ 6]), static_cast<GLfloat>(orientation[10]), static_cast<GLfloat>(orientation[ 14]), 00485 static_cast<GLfloat>(orientation[ 3]), static_cast<GLfloat>(orientation[ 7]), static_cast<GLfloat>(orientation[11]), static_cast<GLfloat>(orientation[ 15]) 00486 }; 00487 glMultMatrixf( m ); 00488 glPopAttrib(); 00489 glPopMatrix(); 00490 00491 m_BVHTree->Draw(); 00492 } 00493 } 00494 //============================================================================= 00495 #endif // #if defined(__gl_h_) || defined(__GL_H__) 00496 00497 //============================================================================= 00498 END_NAMESPACE_TAPs 00499 //----------------------------------------------------------------------------- 00500 //34567890123456789012345678901234567890123456789012345678901234567890123456789 00501 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----