TAPs 0.7.7.3
TAPsCDFnsForHalfEdgeModel.cpp
Go to the documentation of this file.
00001 /******************************************************************************
00002 TAPsCDFnsForHalfEdgeModel.cpp
00003 SUKITTI PUNAK   (04/14/2010)
00004 UPDATE          (09/07/2010)
00005 ******************************************************************************/
00006 #include "TAPsCDFnsForHalfEdgeModel.hpp"
00007 // Using Inclusion Model (i.e. definitions are included in declarations)
00008 //                       (this name.cpp is included in name.hpp)
00009 // Each friend is defined directly inside its declaration.
00010 
00011 #ifdef  TAPs_HALF_EDGE_MODEL_HPP
00012 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00013 
00014 BEGIN_NAMESPACE_TAPs__CD__Fn
00015 //=============================================================================
00016 //-----------------------------------------------------------------------------
00017 
00018 
00019 #ifdef  TAPs_BOUNDING_VOLUME_HPP
00020 //=============================================================================
00021 //-----------------------------------------------------------------------------
00022 //template <typename T>
00023 //bool CDR ( 
00024 //  TAPs::OpenGL::HalfEdgeModel<T> * pMeshObj,  //!< a HalfEdgeModel object
00025 //  TAPs::BoundingVolume<T> const * const   pBVObj      //!< a bounding volume object
00026 //  , TAPs::Vector3<T> * totalForce     //!< total force
00027 //  , T gain                            //!< gain
00028 //)
00029 //{...}
00030 //-----------------------------------------------------------------------------
00031 //=============================================================================
00032 #endif//TAPs_BOUNDING_VOLUME_HPP
00033 
00034 
00035 
00036 
00037 #ifdef  TAPs_MULTI_BOUNDING_VOLUME_HPP
00038 //=============================================================================
00039 //-----------------------------------------------------------------------------
00040 template <typename T>
00041 bool CD ( 
00042     TAPs::OpenGL::HalfEdgeModel<T> * pMeshObj,  
00043     TAPs::MultiBoundingVolume<T> const * const pMBVObj  
00044     , TAPs::Vector3<T> * totalForce     
00045     , T gain                            
00046 )
00047 {
00048     ListOfContactPts.clear();
00049     ListOfForces.clear();
00050 
00051     #ifdef  TAPs_DEBUG_COLLISION_DETECTION
00052     pMeshObj->GetBVHTree()->ClearFlags();
00053     #endif//TAPs_DEBUG_COLLISION_DETECTION
00054 
00055     //#ifdef    TAPs_DEBUG_MODE
00056     //std::cout << "CDR_PolygonalMesh_vs_MBV( HalfEdgeModel<T>, MultiBoundingVolume<T> )\n";
00057     //#endif//TAPs_DEBUG_MODE
00058 
00059     //std::cout << "BVHTree: " << *(pMeshObj->GetBVHTree()) << "\n";
00060 
00061     bool bResult = false;
00062 
00063     // Collision Detection
00064     bResult = pMeshObj->GetBVHTree()->TestOverlapWithTillLeafNodes( pMBVObj );
00065 
00066     //return bResult;
00067 
00068     //---------------------------------------------------------------
00069     // Collision Response
00070     if ( bResult ) {
00071 
00072         // Reset the result for primitive-primitive test, 
00073         // because the previous result is only from bounding volume test.
00074         bResult = false;
00075 
00076         //-------------------------------------------------
00077         //T separateDistanceConstraint;
00078         Vector3<T> N, centerA;
00079         //T separateDistance;
00080         HEFace<T> * primB;
00081         std::vector< HEVertex<T> * const > vertexList;
00082         int noOfVertices;
00083         //-------------------------------------------------
00084         TransformationSupport<T> trxMBV;    // default constructor is an identity transformation
00085         trxMBV = pMBVObj->GetTransform();
00086         //-------------------------------------------------
00087         std::set< BVHNode<T> * > defPolyMesh_NodeSet;
00088 
00089         // Get the list of collided nodes and bounding volumes
00090         std::vector< BVsAndNodesList<T> > * bvList = &pMeshObj->GetBVHTree()->GetListOfCollidedBoundingVolumesAndNodes();
00091         //-------------------------------------------------
00092         // Traverse the list of bounding volumes
00093         std::vector< BVsAndNodesList<T> >::const_iterator pos = bvList->begin();
00094         //-------------------------------------------------
00095         // Mesh's inverse transformation
00096         Matrix4x4<T> trxInvMesh = pMeshObj->GetTransform().GetMatrixTransform();
00097         trxInvMesh.Inversed();
00098         Vector3<T> vOrigin( (pMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(0,0,0,1)).GetVector3() );
00099 
00100         while ( pos != bvList->end() ) {
00101 
00102             // Store the transformation of the bounding volume including the mesh's inverse transformation
00103             TransformationSupport<T> trx = (*pos).BV->GetTransform();
00104             (*pos).BV->GetTransform().SetMatrixTransform( trxInvMesh * trxMBV.GetMatrixTransform() * trx.GetMatrixTransform() );
00105 
00106             //-----------------------------------------
00107             // Deform the deformable polygonal mesh away from the rigid polygonal mesh
00108             switch ( (*pos).BV->GetType() ) {
00109 
00110                 case TAPs::Enum::BOUNDING_SPHERE:
00111                     {
00112 
00113                         //std::cout << "BOUNDING_SPHERE: " << (*pos).BV->GetName() << std::endl;
00114 
00115                         // For Test against triangle
00116                         //---------------------------------------------
00117                         // Transform the BV due to its transformation, center, and radius
00118                         T radiusOfBV = (*pos).BV->GetRadius();
00119                         Vector3<T> C( (*pos).BV->GetCenter() );
00120                         Matrix4x4<T> translation( 1, 0, 0, C[0], 
00121                                                   0, 1, 0, C[1],
00122                                                   0, 0, 1, C[2],
00123                                                   0, 0, 0, 1 );
00124                         Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV );
00125                         Matrix4x4<T> scale( S[0], 0,    0,    0, 
00126                                             0,    S[1], 0,    0,
00127                                             0,    0,    S[2], 0,
00128                                             0,    0,    0,    1 );
00129                         // The BV's current transformation includes the mesh's inverse transformation (see the code above)
00130                         Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale;
00131 
00132                         // BV Sphere's center and radius after the whole transformation from 
00133                         // BV's transformation to mesh's inverse transformation.
00134                         // I.e., transforming the BV to mesh's coordinate
00135                         Vector3<T> centerOfBV_inMeshCoord = (mat * Vector4<T>(0,0,0,1)).GetVector3();
00136                         T radiusOfBV_inMeshCoord = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV_inMeshCoord ).Length();
00137 
00138                         // Inverse the mesh's transformation to the BV's pure transformation
00139                         mat = pMeshObj->GetTransform().GetMatrixTransform() * mat;
00140 
00141                         // BV Sphere's center and radius after the BV's pure transformation
00142                         Vector3<T> centerOfBV( (mat * Vector4<T>(0,0,0,1)).GetVector3() );
00143                         radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length();
00144                         //---------------------------------------------
00145 
00146                         //count = 0;
00147                         for ( unsigned int i = 0; i < (*pos).NodeList.size(); ++i ) {
00148 
00149                             bool testResult = false;
00150 
00151                             // Assume triangle is in Sphere Node
00152                             // Test the triangle in sphere node with BVSphere
00153                             primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace();
00154                             vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices );
00155                             Vector3<T> cdrVec[3];
00156 
00157                             //*
00158                             // Test against each vertex in the triangle
00159                             //-----------------------------------
00160                             //for ( int j = 0; j < noOfVertices; ++j ) {
00161                             for ( int j = 0; j < 3; ++j ) {
00162 
00163                                 if( (*pos).BV->TestPointLocation( vertexList[j]->GetPosition(), &(cdrVec[j]) ) )
00164                                 {
00165                                     //vertexList[j]->SetPosition( vertexList[j]->GetPosition() + cdrVec[j] );
00166                                     Vector3<T> force( (pMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(cdrVec[j])).GetVector3() - vOrigin );
00167 
00168                                     //ListOfContactPts.push_back( Vector3<GLfloat>( (*pos).BV->GetCenter()[0], (*pos).BV->GetCenter()[1], (*pos).BV->GetCenter()[2] ) );
00169                                     ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) );
00170                                     ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) );
00171 
00172                                     testResult = true;
00173                                 }
00174                             }
00175                             //-----------------------------------
00176                             //*/
00177 
00178                             //*
00179                             // Test against triangle
00180                             //-----------------------------------
00181                             //Vector3<T> contactPt;
00182                             if ( TAPs::CGMath<T>::FindIntersectionSphereTriangle( 
00183                                     centerOfBV_inMeshCoord, radiusOfBV_inMeshCoord, // BVSphere properties
00184                                     vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices
00185                                     cdrVec[0], cdrVec[1], cdrVec[2]     // out vectors
00186                                     //, &contactPt
00187                             ) ) {
00188                                 Vector3<T> force_1( cdrVec[0] * CDScaleForSphereBVWithTriangle );
00189                                 Vector3<T> force_2( cdrVec[1] * CDScaleForSphereBVWithTriangle );
00190                                 Vector3<T> force_3( cdrVec[2] * CDScaleForSphereBVWithTriangle );
00191 
00192                                 //vertexList[0]->SetPosition( vertexList[0]->GetPosition() + force_1 );
00193                                 //vertexList[1]->SetPosition( vertexList[1]->GetPosition() + force_2 );
00194                                 //vertexList[2]->SetPosition( vertexList[2]->GetPosition() + force_3 );
00195 
00196                                 force_1 = (pMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_1)).GetVector3() - vOrigin;
00197                                 force_2 = (pMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_2)).GetVector3() - vOrigin;
00198                                 force_3 = (pMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_3)).GetVector3() - vOrigin;
00199 
00200                                 //ListOfContactPts.push_back( Vector3<GLfloat>( contactPt[0], contactPt[1], contactPt[2] ) );
00201                                 ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) );
00202                                 Vector3<T> force( ( force_1 + force_2 + force_3 )/3 );
00203                                 ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) );
00204 
00205                                 testResult = true;
00206                             }
00207                             //-----------------------------------
00208                             //*/
00209 
00210 
00211                             //std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n";
00212 
00213                             // List of BVNodes to be updated
00214                             if ( testResult ) {
00215                                 defPolyMesh_NodeSet.insert( (*pos).NodeList[i] );
00216                                 bResult = true;
00217                             }
00218                         }
00219                     }
00220                     break;
00221 
00222                 case TAPs::Enum::BOUNDING_CYLINDER:
00223                     {
00224                         //std::cout << "BOUNDING_CYLINDER: " << (*pos).BV->GetName() << "\n";
00225 
00226                         // For Test against triangle
00227                         //---------------------------------------------
00228                         // Transform the BV due to its transformation, center, and radius
00229                         T radiusOfBV = (*pos).BV->GetRadius();
00230                         Vector3<T> C( (*pos).BV->GetCenter() );
00231                         Matrix4x4<T> translation( 1, 0, 0, C[0], 
00232                                                   0, 1, 0, C[1],
00233                                                   0, 0, 1, C[2],
00234                                                   0, 0, 0, 1 );
00235                         Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV );
00236                         Matrix4x4<T> scale( S[0], 0,    0,    0, 
00237                                             0,    S[1], 0,    0,
00238                                             0,    0,    S[2], 0,
00239                                             0,    0,    0,    1 );
00240                         // The BV's current transformation includes the mesh's inverse transformation (see the code above)
00241                         Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale;
00242 
00243                         // BV Sphere's center and radius after the whole transformation from 
00244                         // BV's transformation to mesh's inverse transformation.
00245                         // I.e., transforming the BV to mesh's coordinate
00246                         T halfHeightOfBV = (*pos).BV->GetHeight() / 2.0;
00247                         Vector3<T> centerOfBV_inMeshCoord = (mat * Vector4<T>(0,0,0,1)).GetVector3();
00248                         T radiusOfBV_inMeshCoord = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV_inMeshCoord ).Length();
00249                         Vector3<T> topPtOfBV_inMeshCoord( (mat * Vector4<T>(0,0,halfHeightOfBV,1)).GetVector3() );
00250                         Vector3<T> bottomPtOfBV_inMeshCoord( (mat * Vector4<T>(0,0,-halfHeightOfBV,1)).GetVector3() );
00251 
00252                         // Inverse the mesh's transformation to the BV's pure transformation
00253                         mat = pMeshObj->GetTransform().GetMatrixTransform() * mat;
00254 
00255                         // BV Sphere's center and radius after the BV's pure transformation
00256                         Vector3<T> centerOfBV( (mat * Vector4<T>(0,0,0,1)).GetVector3() );
00257                         radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length();
00258                         Vector3<T> topPtOfBV( (mat * Vector4<T>(0,0,halfHeightOfBV,1)).GetVector3() );
00259                         Vector3<T> bottomPtOfBV( (mat * Vector4<T>(0,0,-halfHeightOfBV,1)).GetVector3() );
00260                         //---------------------------------------------
00261 
00262                         //count = 0;
00263                         for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) {
00264 
00265                             bool testResult = false;
00266 
00267                             // Assume triangle is in Sphere Node
00268                             // Test the triangle in sphere node with BVCylinder
00269                             primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace();
00270                             vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices );
00271                             Vector3<T> cdrVec[3];
00272 
00273                             //*
00274                             // Test against each vertex in the triangle
00275                             //-----------------------------------
00276                             //for ( int j = 0; j < noOfVertices; ++j ) {
00277                             for ( int j = 0; j < 3; ++j ) {
00278                                 if( (*pos).BV->TestPointLocation( vertexList[j]->GetPosition(), &(cdrVec[j]) ) )
00279                                 {
00280                                     //vertexList[j]->SetPosition( vertexList[j]->GetPosition() + cdrVec[j] );
00281                                     Vector3<T> force( (pMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(cdrVec[j])).GetVector3() - vOrigin );
00282 
00283                                     //ListOfContactPts.push_back( Vector3<GLfloat>( (*pos).BV->GetCenter()[0], (*pos).BV->GetCenter()[1], (*pos).BV->GetCenter()[2] ) );
00284                                     ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) );
00285                                     ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) );
00286 
00287                                     testResult = true;
00288                                 }
00289                             }
00290                             //-----------------------------------
00291                             //*/
00292 
00293                             //*
00294                             // Test against triangle
00295                             //-----------------------------------
00296                             Vector3<T> contactPt;
00297                             if ( TAPs::CGMath<T>::FindIntersectionCylinderTriangle( 
00298                                     topPtOfBV_inMeshCoord, bottomPtOfBV_inMeshCoord, radiusOfBV_inMeshCoord,    // BVCylinder properties
00299                                     vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices
00300                                     cdrVec[0], cdrVec[1], cdrVec[2]         // out vectors
00301                                     , &contactPt
00302                             ) ) {
00303                                 Vector3<T> force_1( cdrVec[0] * CDScaleForSphereBVWithTriangle );
00304                                 Vector3<T> force_2( cdrVec[1] * CDScaleForSphereBVWithTriangle );
00305                                 Vector3<T> force_3( cdrVec[2] * CDScaleForSphereBVWithTriangle );
00306 
00307                                 //vertexList[0]->SetPosition( vertexList[0]->GetPosition() + force_1 );
00308                                 //vertexList[1]->SetPosition( vertexList[1]->GetPosition() + force_2 );
00309                                 //vertexList[2]->SetPosition( vertexList[2]->GetPosition() + force_3 );
00310 
00311                                 force_1 = (pMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_1)).GetVector3() - vOrigin;
00312                                 force_2 = (pMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_2)).GetVector3() - vOrigin;
00313                                 force_3 = (pMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_3)).GetVector3() - vOrigin;
00314 
00315                                 contactPt = ( (pMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(contactPt)).GetVector3() );
00316 
00317                                 ListOfContactPts.push_back( Vector3<GLfloat>( contactPt[0], contactPt[1], contactPt[2] ) );
00318                                 Vector3<T> force( ( force_1 + force_2 + force_3 )/3 );
00319                                 ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) );
00320 
00321                                 testResult = true;
00322                             }
00323                             //-----------------------------------
00324                             //*/
00325 
00326                             //std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n";
00327 
00328                             // List of BVNodes to be updated
00329                             if ( testResult ) {
00330                                 defPolyMesh_NodeSet.insert( (*pos).NodeList[i] );
00331                                 bResult = true;
00332                             }
00333                         }
00334                     }
00335                     break;
00336 
00337                 default:
00338                     std::cout << "CD of BV Type (" << (*pos).BV->GetType() << ") doesn't support!\n";
00339                     break;
00340             }
00341 
00342             // Restore the transformation of the bounding volume
00343             //(*pos).BV->GetTransform().SetMatrixTransform( trx.GetMatrixTransform() );
00344             (*pos).BV->SetTransform( trx );
00345             // Next Bounding Volume
00346             ++pos;
00347         }
00348         //-------------------------------------------------
00349 
00350         //-------------------------------------------------
00351         // Update Normals of Deformable Polygonal Mesh
00352         //pMeshObj->CalAndSetNormals();     // commented out to rely on AdvanceSimulation to update the normals
00353         //-------------------------------------------------
00354         // Update Bounding Volume Hierarchy of Deformable Polygonal Mesh
00355         //pMeshObj->GetBVHTree()->Update( defPolyMesh_NodeSet );
00356         // FOR HETriMeshOneModelMultiParts
00357     }
00358     //---------------------------------------------------------------
00359     if ( totalForce ) {
00360         totalForce->SetXYZ( 0, 0, 0 );
00361         Vector3<float> force( 0, 0, 0 );
00362         for ( int i = 0; i < static_cast<int>( ListOfForces.size() ); ++i ) {
00363             force += ListOfForces[i];
00364         }
00365         force *= gain;
00366         (*totalForce).SetXYZ( force[0], force[1], force[2] );
00367     }
00368 
00369     //std::cout << "END: CD(...) for HalfEdgeModel" << std::endl;
00370 
00371     return bResult;
00372 }
00373 // END: CD (...) for HalfEdgeModel with MultiBoundingVolume
00374 
00375 
00376 
00377 
00378 //-----------------------------------------------------------------------------
00379 template <typename T>
00380 bool CDR ( 
00381     TAPs::OpenGL::HalfEdgeModel<T> * pMeshObj,  
00382     TAPs::MultiBoundingVolume<T> const * const pMBVObj  
00383     , TAPs::Vector3<T> * totalForce     
00384     , T gain                            
00385 )
00386 {
00387     ListOfContactPts.clear();
00388     ListOfForces.clear();
00389 
00390     #ifdef  TAPs_DEBUG_COLLISION_DETECTION
00391     pMeshObj->GetBVHTree()->ClearFlags();
00392     #endif//TAPs_DEBUG_COLLISION_DETECTION
00393 
00394     //#ifdef    TAPs_DEBUG_MODE
00395     //std::cout << "CDR_PolygonalMesh_vs_MBV( HalfEdgeModel<T>, MultiBoundingVolume<T> )\n";
00396     //#endif//TAPs_DEBUG_MODE
00397 
00398     //std::cout << "BVHTree: " << *(pMeshObj->GetBVHTree()) << "\n";
00399 
00400     bool bResult = false;
00401 
00402     // Collision Detection
00403     bResult = pMeshObj->GetBVHTree()->TestOverlapWithTillLeafNodes( pMBVObj );
00404 
00405     //return bResult;
00406 
00407     //---------------------------------------------------------------
00408     // Collision Response
00409     if ( bResult ) {
00410 
00411         // Reset the result for primitive-primitive test, 
00412         // because the previous result is only from bounding volume test.
00413         bResult = false;
00414 
00415         //-------------------------------------------------
00416         //T separateDistanceConstraint;
00417         Vector3<T> N, centerA;
00418         //T separateDistance;
00419         HEFace<T> * primB;
00420         std::vector< HEVertex<T> * const > vertexList;
00421         int noOfVertices;
00422         //-------------------------------------------------
00423         TransformationSupport<T> trxMBV;    // default constructor is an identity transformation
00424         trxMBV = pMBVObj->GetTransform();
00425         //-------------------------------------------------
00426         std::set< BVHNode<T> * > defPolyMesh_NodeSet;
00427 
00428         // Get the list of collided nodes and bounding volumes
00429         std::vector< BVsAndNodesList<T> > * bvList = &pMeshObj->GetBVHTree()->GetListOfCollidedBoundingVolumesAndNodes();
00430         //-------------------------------------------------
00431         // Traverse the list of bounding volumes
00432         std::vector< BVsAndNodesList<T> >::const_iterator pos = bvList->begin();
00433         //-------------------------------------------------
00434         // Mesh's inverse transformation
00435         Matrix4x4<T> trxInvMesh = pMeshObj->GetTransform().GetMatrixTransform();
00436         trxInvMesh.Inversed();
00437         Vector3<T> vOrigin( (pMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(0,0,0,1)).GetVector3() );
00438 
00439         while ( pos != bvList->end() ) {
00440 
00441             // Store the transformation of the bounding volume including the mesh's inverse transformation
00442             TransformationSupport<T> trx = (*pos).BV->GetTransform();
00443             (*pos).BV->GetTransform().SetMatrixTransform( trxInvMesh * trxMBV.GetMatrixTransform() * trx.GetMatrixTransform() );
00444 
00445             //-----------------------------------------
00446             // Deform the deformable polygonal mesh away from the rigid polygonal mesh
00447             switch ( (*pos).BV->GetType() ) {
00448 
00449                 case TAPs::Enum::BOUNDING_SPHERE:
00450                     {
00451 
00452                         //std::cout << "BOUNDING_SPHERE: " << (*pos).BV->GetName() << std::endl;
00453 
00454                         // For Test against triangle
00455                         //---------------------------------------------
00456                         // Transform the BV due to its transformation, center, and radius
00457                         T radiusOfBV = (*pos).BV->GetRadius();
00458                         Vector3<T> C( (*pos).BV->GetCenter() );
00459                         Matrix4x4<T> translation( 1, 0, 0, C[0], 
00460                                                   0, 1, 0, C[1],
00461                                                   0, 0, 1, C[2],
00462                                                   0, 0, 0, 1 );
00463                         Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV );
00464                         Matrix4x4<T> scale( S[0], 0,    0,    0, 
00465                                             0,    S[1], 0,    0,
00466                                             0,    0,    S[2], 0,
00467                                             0,    0,    0,    1 );
00468                         // The BV's current transformation includes the mesh's inverse transformation (see the code above)
00469                         Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale;
00470 
00471                         // BV Sphere's center and radius after the whole transformation from 
00472                         // BV's transformation to mesh's inverse transformation.
00473                         // I.e., transforming the BV to mesh's coordinate
00474                         Vector3<T> centerOfBV_inMeshCoord = (mat * Vector4<T>(0,0,0,1)).GetVector3();
00475                         T radiusOfBV_inMeshCoord = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV_inMeshCoord ).Length();
00476 
00477                         // Inverse the mesh's transformation to the BV's pure transformation
00478                         mat = pMeshObj->GetTransform().GetMatrixTransform() * mat;
00479 
00480                         // BV Sphere's center and radius after the BV's pure transformation
00481                         Vector3<T> centerOfBV( (mat * Vector4<T>(0,0,0,1)).GetVector3() );
00482                         radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length();
00483                         //---------------------------------------------
00484 
00485                         //count = 0;
00486                         for ( unsigned int i = 0; i < (*pos).NodeList.size(); ++i ) {
00487 
00488                             bool testResult = false;
00489 
00490                             // Assume triangle is in Sphere Node
00491                             // Test the triangle in sphere node with BVSphere
00492                             primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace();
00493                             vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices );
00494                             Vector3<T> cdrVec[3];
00495 
00496                             //*
00497                             // Test against each vertex in the triangle
00498                             //-----------------------------------
00499                             //for ( int j = 0; j < noOfVertices; ++j ) {
00500                             for ( int j = 0; j < 3; ++j ) {
00501 
00502                                 if( (*pos).BV->TestPointLocation( vertexList[j]->GetPosition(), &(cdrVec[j]) ) )
00503                                 {
00504                                     vertexList[j]->SetPosition( vertexList[j]->GetPosition() + cdrVec[j] );
00505                                     Vector3<T> force( (pMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(cdrVec[j])).GetVector3() - vOrigin );
00506 
00507                                     //ListOfContactPts.push_back( Vector3<GLfloat>( (*pos).BV->GetCenter()[0], (*pos).BV->GetCenter()[1], (*pos).BV->GetCenter()[2] ) );
00508                                     ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) );
00509                                     ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) );
00510 
00511                                     testResult = true;
00512                                 }
00513                             }
00514                             //-----------------------------------
00515                             //*/
00516 
00517                             //*
00518                             // Test against triangle
00519                             //-----------------------------------
00520                             //Vector3<T> contactPt;
00521                             if ( TAPs::CGMath<T>::FindIntersectionSphereTriangle( 
00522                                     centerOfBV_inMeshCoord, radiusOfBV_inMeshCoord, // BVSphere properties
00523                                     vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices
00524                                     cdrVec[0], cdrVec[1], cdrVec[2]     // out vectors
00525                                     //, &contactPt
00526                             ) ) {
00527                                 Vector3<T> force_1( cdrVec[0] * CDScaleForSphereBVWithTriangle );
00528                                 Vector3<T> force_2( cdrVec[1] * CDScaleForSphereBVWithTriangle );
00529                                 Vector3<T> force_3( cdrVec[2] * CDScaleForSphereBVWithTriangle );
00530 
00531                                 vertexList[0]->SetPosition( vertexList[0]->GetPosition() + force_1 );
00532                                 vertexList[1]->SetPosition( vertexList[1]->GetPosition() + force_2 );
00533                                 vertexList[2]->SetPosition( vertexList[2]->GetPosition() + force_3 );
00534 
00535                                 force_1 = (pMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_1)).GetVector3() - vOrigin;
00536                                 force_2 = (pMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_2)).GetVector3() - vOrigin;
00537                                 force_3 = (pMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_3)).GetVector3() - vOrigin;
00538 
00539                                 //ListOfContactPts.push_back( Vector3<GLfloat>( contactPt[0], contactPt[1], contactPt[2] ) );
00540                                 ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) );
00541                                 Vector3<T> force( ( force_1 + force_2 + force_3 )/3 );
00542                                 ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) );
00543 
00544                                 testResult = true;
00545                             }
00546                             //-----------------------------------
00547                             //*/
00548 
00549 
00550                             //std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n";
00551 
00552                             // List of BVNodes to be updated
00553                             if ( testResult ) {
00554                                 defPolyMesh_NodeSet.insert( (*pos).NodeList[i] );
00555                                 bResult = true;
00556                             }
00557                         }
00558                     }
00559                     break;
00560 
00561                 case TAPs::Enum::BOUNDING_CYLINDER:
00562                     {
00563                         //std::cout << "BOUNDING_CYLINDER: " << (*pos).BV->GetName() << "\n";
00564 
00565                         // For Test against triangle
00566                         //---------------------------------------------
00567                         // Transform the BV due to its transformation, center, and radius
00568                         T radiusOfBV = (*pos).BV->GetRadius();
00569                         Vector3<T> C( (*pos).BV->GetCenter() );
00570                         Matrix4x4<T> translation( 1, 0, 0, C[0], 
00571                                                   0, 1, 0, C[1],
00572                                                   0, 0, 1, C[2],
00573                                                   0, 0, 0, 1 );
00574                         Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV );
00575                         Matrix4x4<T> scale( S[0], 0,    0,    0, 
00576                                             0,    S[1], 0,    0,
00577                                             0,    0,    S[2], 0,
00578                                             0,    0,    0,    1 );
00579                         // The BV's current transformation includes the mesh's inverse transformation (see the code above)
00580                         Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale;
00581 
00582                         // BV Sphere's center and radius after the whole transformation from 
00583                         // BV's transformation to mesh's inverse transformation.
00584                         // I.e., transforming the BV to mesh's coordinate
00585                         T halfHeightOfBV = (*pos).BV->GetHeight() / 2.0;
00586                         Vector3<T> centerOfBV_inMeshCoord = (mat * Vector4<T>(0,0,0,1)).GetVector3();
00587                         T radiusOfBV_inMeshCoord = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV_inMeshCoord ).Length();
00588                         Vector3<T> topPtOfBV_inMeshCoord( (mat * Vector4<T>(0,0,halfHeightOfBV,1)).GetVector3() );
00589                         Vector3<T> bottomPtOfBV_inMeshCoord( (mat * Vector4<T>(0,0,-halfHeightOfBV,1)).GetVector3() );
00590 
00591                         // Inverse the mesh's transformation to the BV's pure transformation
00592                         mat = pMeshObj->GetTransform().GetMatrixTransform() * mat;
00593 
00594                         // BV Sphere's center and radius after the BV's pure transformation
00595                         Vector3<T> centerOfBV( (mat * Vector4<T>(0,0,0,1)).GetVector3() );
00596                         radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length();
00597                         Vector3<T> topPtOfBV( (mat * Vector4<T>(0,0,halfHeightOfBV,1)).GetVector3() );
00598                         Vector3<T> bottomPtOfBV( (mat * Vector4<T>(0,0,-halfHeightOfBV,1)).GetVector3() );
00599                         //---------------------------------------------
00600 
00601                         //count = 0;
00602                         for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) {
00603 
00604                             bool testResult = false;
00605 
00606                             // Assume triangle is in Sphere Node
00607                             // Test the triangle in sphere node with BVCylinder
00608                             primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace();
00609                             vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices );
00610                             Vector3<T> cdrVec[3];
00611 
00612                             //*
00613                             // Test against each vertex in the triangle
00614                             //-----------------------------------
00615                             //for ( int j = 0; j < noOfVertices; ++j ) {
00616                             for ( int j = 0; j < 3; ++j ) {
00617                                 if( (*pos).BV->TestPointLocation( vertexList[j]->GetPosition(), &(cdrVec[j]) ) )
00618                                 {
00619                                     vertexList[j]->SetPosition( vertexList[j]->GetPosition() + cdrVec[j] );
00620                                     Vector3<T> force( (pMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(cdrVec[j])).GetVector3() - vOrigin );
00621 
00622                                     //ListOfContactPts.push_back( Vector3<GLfloat>( (*pos).BV->GetCenter()[0], (*pos).BV->GetCenter()[1], (*pos).BV->GetCenter()[2] ) );
00623                                     ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) );
00624                                     ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) );
00625 
00626                                     testResult = true;
00627                                 }
00628                             }
00629                             //-----------------------------------
00630                             //*/
00631 
00632                             //*
00633                             // Test against triangle
00634                             //-----------------------------------
00635                             Vector3<T> contactPt;
00636                             if ( TAPs::CGMath<T>::FindIntersectionCylinderTriangle( 
00637                                     topPtOfBV_inMeshCoord, bottomPtOfBV_inMeshCoord, radiusOfBV_inMeshCoord,    // BVCylinder properties
00638                                     vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices
00639                                     cdrVec[0], cdrVec[1], cdrVec[2]         // out vectors
00640                                     , &contactPt
00641                             ) ) {
00642                                 Vector3<T> force_1( cdrVec[0] * CDScaleForSphereBVWithTriangle );
00643                                 Vector3<T> force_2( cdrVec[1] * CDScaleForSphereBVWithTriangle );
00644                                 Vector3<T> force_3( cdrVec[2] * CDScaleForSphereBVWithTriangle );
00645 
00646                                 vertexList[0]->SetPosition( vertexList[0]->GetPosition() + force_1 );
00647                                 vertexList[1]->SetPosition( vertexList[1]->GetPosition() + force_2 );
00648                                 vertexList[2]->SetPosition( vertexList[2]->GetPosition() + force_3 );
00649 
00650                                 force_1 = (pMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_1)).GetVector3() - vOrigin;
00651                                 force_2 = (pMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_2)).GetVector3() - vOrigin;
00652                                 force_3 = (pMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_3)).GetVector3() - vOrigin;
00653 
00654                                 contactPt = ( (pMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(contactPt)).GetVector3() );
00655 
00656                                 ListOfContactPts.push_back( Vector3<GLfloat>( contactPt[0], contactPt[1], contactPt[2] ) );
00657                                 Vector3<T> force( ( force_1 + force_2 + force_3 )/3 );
00658                                 ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) );
00659 
00660                                 testResult = true;
00661                             }
00662                             //-----------------------------------
00663                             //*/
00664 
00665                             //std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n";
00666 
00667                             // List of BVNodes to be updated
00668                             if ( testResult ) {
00669                                 defPolyMesh_NodeSet.insert( (*pos).NodeList[i] );
00670                                 bResult = true;
00671                             }
00672                         }
00673                     }
00674                     break;
00675 
00676                 default:
00677                     std::cout << "CDR of BV Type (" << (*pos).BV->GetType() << ") doesn't support!\n";
00678                     break;
00679             }
00680 
00681             // Restore the transformation of the bounding volume
00682             //(*pos).BV->GetTransform().SetMatrixTransform( trx.GetMatrixTransform() );
00683             (*pos).BV->SetTransform( trx );
00684             // Next Bounding Volume
00685             ++pos;
00686         }
00687         //-------------------------------------------------
00688 
00689         //-------------------------------------------------
00690         // Update Normals of Deformable Polygonal Mesh
00691         //pMeshObj->CalAndSetNormals();     // commented out to rely on AdvanceSimulation to update the normals
00692         //-------------------------------------------------
00693         // Update Bounding Volume Hierarchy of Deformable Polygonal Mesh
00694         pMeshObj->GetBVHTree()->Update( defPolyMesh_NodeSet );
00695         // FOR HETriMeshOneModelMultiParts
00696     }
00697     //---------------------------------------------------------------
00698     if ( totalForce ) {
00699         totalForce->SetXYZ( 0, 0, 0 );
00700         Vector3<float> force( 0, 0, 0 );
00701         for ( int i = 0; i < static_cast<int>( ListOfForces.size() ); ++i ) {
00702             force += ListOfForces[i];
00703         }
00704         force *= gain;
00705         (*totalForce).SetXYZ( force[0], force[1], force[2] );
00706     }
00707 
00708     //std::cout << "END: CDR(...) for HalfEdgeModel" << std::endl;
00709 
00710     return bResult;
00711 }
00712 // END: CDR (...) for HalfEdgeModel with MultiBoundingVolume
00713 //-----------------------------------------------------------------------------
00714 //=============================================================================
00715 #endif//TAPs_MULTI_BOUNDING_VOLUME_HPP
00716 
00717 
00718 
00719 
00720 //=============================================================================
00721 //-----------------------------------------------------------------------------
00722 template <typename T>
00723 bool CDR (
00724     TAPs::OpenGL::HalfEdgeModel<T> * pMeshObj_1,    
00725     TAPs::OpenGL::HalfEdgeModel<T> * pMeshObj_2,    
00726     TransformationSupport<T> * pTransform_1,        
00727     TransformationSupport<T> * pTransform_2,        
00728     bool    bIsRigidObj_1,                          
00729     bool    bIsRigidObj_2,                          
00730     T       deformRatio_1,                          
00731     T       deformRatio_2                           
00732 )
00733 {
00734     bool bResult = false;
00735 
00736     // Create the transform for mesh object#1
00737     TransformationSupport<T> transform_1;
00738     if ( pTransform_1 ) {
00739         transform_1.ReturnMatrixTransform() *= pTransform_1->GetMatrixTransform();
00740     }
00741     transform_1.ReturnMatrixTransform() *= pMeshObj_1->GetTransform().GetMatrixTransform();
00742 
00743     // Create the transform for mesh object#1
00744     TransformationSupport<T> transform_2;
00745     if ( pTransform_2 ) {
00746         transform_2.ReturnMatrixTransform() *= pTransform_2->GetMatrixTransform();
00747     }
00748     transform_2.ReturnMatrixTransform() *= pMeshObj_2->GetTransform().GetMatrixTransform();
00749 
00750     // Collision Detection
00751     TransformationSupport<T> oldTrx_1( pMeshObj_1->GetTransform() );    // store the old transformation of object#1
00752     pMeshObj_1->GetTransform() = transform_1;                           // set to the new transformation of object#1
00753     TransformationSupport<T> oldTrx_2( pMeshObj_2->GetTransform() );    // store the old transformation of object#2
00754     pMeshObj_2->GetTransform() = transform_2;                           // set to the new transformation of object#2
00755     bResult = pMeshObj_1->GetBVHTree()->TestOverlapWithTillLeafNodes( pMeshObj_2->GetBVHTree() );   // collision detection automatically uses the new transformations
00756     pMeshObj_1->GetTransform() = oldTrx_1;  // restore the old transformation of object#1
00757     pMeshObj_2->GetTransform() = oldTrx_2;  // restore the old transformation of object#2
00758 
00759     if ( !bResult ) return bResult; // no collision
00760 
00761 
00762     // DO NARROW-PHASE COLLISION CHECK
00763     // ...
00764     // RESOLVE THE COLLISION IF OCCURS
00765     // ...
00766 
00767 
00768     /*
00769     if ( pDefPolyMesh_1->GetBVHTree()->TestOverlapWithTillLeafNodes( pDefPolyMesh_2->GetBVHTree() ) )
00770     {
00771         //-------------------------------------------------
00772         T separateDistanceConstraint;
00773         Vector3<T> N, centerA;
00774         T separateDistance;
00775         HEFace<T> * primB;
00776         std::vector< HEVertex<T> * const > vertexList;
00777         int noOfVertices;
00778         //-------------------------------------------------
00779         std::vector< BVHNode<T> * > *   listOfCollidedNode_Def_1 = &pDefPolyMesh_1->GetBVHTree()->GetListOfCollidedNodes();
00780         std::vector< BVHNode<T> * > *   listOfCollidedNode_Def_2 = &pDefPolyMesh_1->GetBVHTree()->GetListOfCollidedNodesThat();
00781         std::set< BVHNode<T> * > defPolyMesh_NodeSet;
00782         //-------------------------------------------------
00784         //for ( int i = 0; i < static_cast<int>( listOfCollidedNode_Def->size() ); ++i ) {
00785 
00786         //  separateDistanceConstraint = 0.5 * (   (*listOfCollidedNode_Def_1)[i]->GetRadius() 
00787         //                                       + (*listOfCollidedNode_Def_2)[i]->GetRadius() );
00788         //  centerA = ( pRigidPolyMesh->GetTransform().GetMatrixTransform() * 
00789         //              Vector4<T>( (*listOfCollidedNode_Rigid)[i]->GetCenter() ) ).GetVector3();
00790         //  N = centerA - (*listOfCollidedNode_Def)[i]->GetCenter();
00791         //  separateDistance = separateDistanceConstraint - N.Length();
00792         //  if ( separateDistance > Math<T>::ZERO ) {
00793         //      N.Normalized();
00794         //      N *= separateDistance;
00795         //      primB = (*listOfCollidedNode_Def)[i]->GetAPrimitiveHalfEdgeFace();
00796         //      vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices );
00797         //      //-------------------------------
00798         //      // For each vertex in a primitive
00799         //      for ( int j = 0; j < noOfVertices; ++j ) {
00800         //          vertexList[j]->SetPosition( vertexList[j]->GetPosition() - N );
00801         //      }
00802         //  }
00803         //  // List of BVNodes to be updated
00804         //  defPolyMesh_NodeSet.insert( (*listOfCollidedNode_Def)[i] );
00805         //}
00808         //pDefPolyMesh->CalAndSetNormals();
00811         //pDefPolyMesh->GetBVHTree()->Update( defPolyMesh_NodeSet );
00813         //return true;
00814     }
00815     //*/
00816     //---------------------------------------------------------------
00817     return bResult;
00818 }
00819 // END: CDR (...) for HalfEdgeModel with HalfEdgeModel
00820 //-----------------------------------------------------------------------------
00821 //=============================================================================
00822 
00823 
00824 
00825 
00826 //-----------------------------------------------------------------------------
00827 //=============================================================================
00828 END_NAMESPACE_TAPs__CD__Fn
00829 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00830 #endif//TAPs_HALF_EDGE_MODEL_HPP
00831 //34567890123456789012345678901234567890123456789012345678901234567890123456789
00832 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines