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