TAPs 0.7.7.3
TAPsColDetFns.cpp
Go to the documentation of this file.
00001 /******************************************************************************
00002 TAPsColDetFns.cpp
00003 
00004 ColDetFns (cpp file).
00005 
00006 SUKITTI PUNAK   (07/09/2009)
00007 UPDATE          (12/29/2010)
00008 ******************************************************************************/
00009 #include "TAPsColDetFns.hpp"
00010 // Using Inclusion Model (i.e. definitions are included in declarations)
00011 //                       (this name.cpp is included in name.hpp)
00012 // Each friend is defined directly inside its declaration.
00013 
00014 BEGIN_NAMESPACE_TAPs__CD__Fn
00015 //=============================================================================
00016 //-----------------------------------------------------------------------------
00017 
00018 
00019 #if ( defined TAPs_STRAND_MODEL_HPP && defined TAPs_MULTI_BOUNDING_VOLUME_HPP )
00020 //=============================================================================
00021 //-----------------------------------------------------------------------------
00022 template <typename T>
00023 bool CDR_Strand_vs_MBV ( 
00024     TAPs::OpenGL::ModelStrand<T> *  pStrandObj,             
00025     TAPs::MultiBoundingVolume<T> const * const  pMBVObj,    
00026     TAPs::TransformationSupport<T> const * const pTransform 
00027 )
00028 {
00029     bool bResult = false;
00030     //---------------------------------------------------------------
00031     //bool isThePointInsideTheBV;   // the pt is inside or outside the bv
00032     Vector3<T> vDistance;           // displacement vector
00033     TransformationSupport<T> transform;
00034     //---------------------------------------------------------------
00035     if ( pTransform ) {
00036         transform.ReturnMatrixTransform() *= pTransform->GetMatrixTransform();
00037     }
00038     //---------------------------------------------------------------
00039     transform.ReturnMatrixTransform() *= pMBVObj->GetTransform().GetMatrixTransform();
00040     TransformationSupport<T> savedTransform( transform );
00041     //---------------------------------------------------------------
00042     std::vector< BoundingVolume<T> * >::const_iterator pos = pMBVObj->GetBoundingVolumeList().begin();
00043     //---------------------------------------------------------------
00044     while ( pos != pMBVObj->GetBoundingVolumeList().end() ) {
00045         assert( *pos != NULL );
00046         vDistance.SetXYZ( 0, 0, 0 );
00047         transform = savedTransform;
00048         //-------------------------------------------------
00049         transform.ReturnMatrixTransform() *= (*pos)->GetTransform().GetMatrixTransform();
00050         //-------------------------------------------------
00051         // Transform each vertex of the strand to the bounding volume coordinate
00052         int iDeepestPoint       = -1;
00053         T   tDeepestDistance    = 9E60;
00054         Vector3<T>      vDirection;
00055         Vector3<T>      translation( transform.GetTranslation() );
00056         Matrix3x3<T>    inversedRotMatrix( transform.GetMatrixRotation().GetInverse() );
00057 
00058         switch ( (*pos)->GetType() ) {
00059 
00060             //---------------------------------------------
00061             case TAPs::Enum::BOUNDING_CYLINDER:
00062             //---------------------------------------------
00063             #ifdef  TAPs_STRAND_LOCK_SEGMENTS
00064                 for ( unsigned int s = 0; s < pStrandObj->GetNumSegments(); ++s ) {
00065                     // Skip locked or invisible segments
00066                     if ( pStrandObj->GetSegmentLockStatus(s) || !pStrandObj->GetSegmentVisibleStatus(s) ) {}
00067                     else {
00068                         for ( int i = pStrandObj->GetStartPtOfSegment(s); i <= pStrandObj->GetEndPtOfSegment(s); ++i )
00069             #else //TAPs_STRAND_LOCK_SEGMENTS
00070                 {
00071                     {
00072                         for ( unsigned int i = 0; i <= pStrandObj->GetNumberOfLinks(); ++i )
00073             #endif//TAPs_STRAND_LOCK_SEGMENTS
00074                         {
00075                             // If the point is fixed, do not move it.
00076                             if ( pStrandObj->GetFixStatusOfPtNo(i) )    continue;
00077 
00078                             //------------------------------------------------------
00079                             // In the local coordinate of the bounding cylinder, 
00080                             // the cylinder axis is parallel to z-axis 
00081                             // where it is shifted by the cylinder center.
00082                             // The cylinder has radius, height and center.
00083                             // Its height is measured from -z and +z axis
00084                             // where its center is situated between height/2 in -z and +z axis.
00085                             Vector3<T> location = pStrandObj->GetPointPosition(i);
00086                             location -= translation;
00087                             location = inversedRotMatrix * location;
00088                             // Shift the location of point by the cylinder center
00089                             // i.e. shift the cylinder to the origin (0,0,0)
00090                             location -= (*pos)->GetCenter();
00091                             //------------------------------------------------------
00092                             // Now the cylinder is centered at the origin with its axis on the z-axis
00093                             // where its height is from -height/2 to +height/2.
00094                             // And the input point has been transformed into the cylinder coordinate.
00095                             // The test can be performed.
00096                             if ( TAPs::CGMath<T>::CD_CylinderAtOrigin_vs_Point( (*pos)->GetRadius(), (*pos)->GetHeight(), location, vDistance ) )
00097                             {
00098                                 bResult = true;
00099                                 //-------------------------
00100                                 // Now rotate it back by the rotation matrix (from the transform matrix).
00101                                 // REMARK: Translation (from the transform matrix) is NOT applied back, 
00102                                 //         because vDistance represents a displacement vector from 
00103                                 //         the input point to the cylinder surface.
00104                                 //         I.e., the strand point is always in the world coordinates.
00105                                 vDistance = transform.GetMatrixRotation() * vDistance;
00106                                 //-------------------------
00107                                 // This statement just ask the strand to move its collided points away
00108                                 pStrandObj->ChangeOnlyPointPositionByAddedWithThisVector( i, vDistance );
00109                                 T tDistance = vDistance.Length();
00110                                 if ( tDeepestDistance > tDistance ) {
00111                                     tDeepestDistance = tDistance;
00112                                     iDeepestPoint = i;
00113                                     vDirection = vDistance;
00114                                 }
00115                                 //-------------------------
00116                             }
00117                         }// Back to Next Strand Point
00118                     }
00119                 }
00120                 break;
00121                 // END: BOUNDING_CYLINDER
00122 
00123             //---------------------------------------------
00124             case TAPs::Enum::BOUNDING_SPHERE:
00125             //---------------------------------------------
00126             #ifdef  TAPs_STRAND_LOCK_SEGMENTS
00127                 for ( unsigned int s = 0; s < pStrandObj->GetNumSegments(); ++s ) {
00128                     // Skip locked or invisible segments
00129                     if ( pStrandObj->GetSegmentLockStatus(s) || !pStrandObj->GetSegmentVisibleStatus(s) ) {}
00130                     else {
00131                         for ( int i = pStrandObj->GetStartPtOfSegment(s); i <= pStrandObj->GetEndPtOfSegment(s); ++i )
00132             #else //TAPs_STRAND_LOCK_SEGMENTS
00133                 {
00134                     {
00135                         for ( unsigned int i = 0; i <= pStrandObj->GetNumberOfLinks(); ++i )
00136             #endif//TAPs_STRAND_LOCK_SEGMENTS
00137                         {
00138                             // If the point is fixed, do not move it.
00139                             if ( pStrandObj->GetFixStatusOfPtNo(i) )    continue;
00140 
00141                             //------------------------------------------------------
00142                             // In the local coordinate of the bounding sphere centered at the origin 
00143                             Vector3<T> location = pStrandObj->GetPointPosition(i);
00144                             location -= translation;
00145                             location = inversedRotMatrix * location;
00146                             // Shift the location of point by the sphere center
00147                             // i.e. shift the sphere to the origin (0,0,0)
00148                             location -= (*pos)->GetCenter();
00149                             //------------------------------------------------------
00150                             // Now the sphere is centered at the origin
00151                             // And the input point has been transformed into the sphere coordinate.
00152                             // The test can be performed.
00153                             if ( TAPs::CGMath<T>::CD_SphereAtOrigin_vs_Point( (*pos)->GetRadius(), location, vDistance ) )
00154                             {
00155                                 bResult = true;
00156                                 //-------------------------
00157                                 // Now rotate it back by the rotation matrix (from the transform matrix).
00158                                 // REMARK: Translation (from the transform matrix) is NOT applied back, 
00159                                 //         because vDistance represents a displacement vector from 
00160                                 //         the input point to the sphere surface.
00161                                 //         I.e., the strand point is always in the world coordinates.
00162                                 vDistance = transform.GetMatrixRotation() * vDistance;
00163                                 //-------------------------
00164                                 // This statement just ask the strand to move its collided points away
00165                                 pStrandObj->ChangeOnlyPointPositionByAddedWithThisVector( i, vDistance );
00166                                 T tDistance = vDistance.Length();
00167                                 if ( tDeepestDistance > tDistance ) {
00168                                     tDeepestDistance = tDistance;
00169                                     iDeepestPoint = i;
00170                                     vDirection = vDistance;
00171                                 }
00172                                 //-------------------------
00173                             }
00174                         }// Back to Next Strand Point
00175                     }
00176                 }
00177                 break;
00178                 // END: BOUNDING_SPHERE
00179 
00180         }//END: switch ( (*pos)->GetType() ) {...}
00181         ++pos;  // Next Bounding Volume
00182     }
00183     return bResult;
00184 }
00185 // END: CDR_Strand_vs_MBV(...)
00186 
00187 
00188 //-----------------------------------------------------------------------------
00189 // START: namespace Private
00190 namespace Private {
00191 
00193 template <typename T>
00194 bool CD ( 
00195     TAPs::OpenGL::ModelStrand<T> *  pStrandObj,                 
00196     TAPs::BVHTree<T> const * const  pObjBVH,                    
00197     TAPs::TransformationSupport<T> const * const pTransform,    
00198     std::vector< BVHNode< T > * > * listOfSutureCollidedNodes,  
00199     std::vector< BVHNode< T > * > * listOfObjectCollidedNodes   
00200 )
00201 {
00202     //--------------------------------------------------------------------
00203     BVHTree<T> * strandBVH = pStrandObj->GetBVHTree();
00204     bool result = strandBVH->TestOverlapWithTillLeafNodes( pObjBVH );
00205     if ( !result )  return result;
00206     //--------------------------------------------------------------------
00207     BVHNode<T> * cylinder;
00208     BVHNode<T> * triangle;
00209     //--------------------------------------------------------------------
00210 
00211     // HAVE TO CORPORATE pTransform for collision detection !!!
00212 
00213     int size = static_cast<int>( pStrandObj->GetBVHTree()->GetListOfCollidedNodes().size() );
00214     int linkNo;
00215     for ( int i = 0; i < size; ++i ) {
00216         cylinder = strandBVH->GetListOfCollidedNodes()[i];
00217         triangle = strandBVH->GetListOfCollidedNodesThat()[i];
00218         linkNo = cylinder->GetID();
00219         HEFace<T> * heFace = triangle->GetAPrimitiveHalfEdgeFace();
00220         std::vector< HEVertex<T> * const > vertices = heFace->GetPtrsToVertices();
00221         result = CGMath<T>::FindIntersectionCylinderTriangle(
00222                     pStrandObj->GetPointPosition( linkNo ), 
00223                     pStrandObj->GetPointPosition( linkNo+1 ), 
00224                     pStrandObj->GetRadius(), 
00225                     vertices[0]->GetPosition(), 
00226                     vertices[1]->GetPosition(), 
00227                     vertices[2]->GetPosition() );
00228         
00229         if ( result ) {
00230             listOfSutureCollidedNodes->push_back( strandBVH->GetListOfCollidedNodes()[i] );
00231             listOfObjectCollidedNodes->push_back( strandBVH->GetListOfCollidedNodesThat()[i] );
00232         }
00233     }
00234     //--------------------------------------------------------------------
00235     if ( static_cast<int>( listOfSutureCollidedNodes->size() ) > 0 )    return true;
00236     else                                                                return false;
00237 }
00238 
00239 //-----------------------------------------------------------------------------
00241 template <typename T>
00242 bool CR ( 
00243     TAPs::OpenGL::ModelStrand<T> *  pStrandObj,                 
00244     TAPs::BVHTree<T> const * const  pObjBVH,                    
00245     TAPs::TransformationSupport<T> const * const pTransform,    
00246     std::vector< BVHNode< T > * > * listOfSutureCollidedNodes,  
00247     std::vector< BVHNode< T > * > * listOfObjectCollidedNodes   
00248 )
00249 {
00250     // HAVE TO CORPORATE pTransform for collision detection !!!
00251 
00252     std::set< BVHNode<T> * > strandNodeSet;
00253     std::set< BVHNode<T> * > objectNodeSet;
00254     //--------------------------------------------------------------------
00255     Vector3<T> N, V1, V2;
00256     T value;
00257     //T offset = pStrandObj->GetRadius() * 2;
00258     //T offset = pStrandObj->GetRadius();
00259     T offset = 0;
00260     HEFace<T> * primB;
00261     std::vector< HEVertex<T> * const > vertexList;
00262     int noOfVertices;
00263     //--------------------------------------------------------------------
00264     // Deform Object away from Strand Object
00265     for ( int i = 0; i < static_cast<int>( listOfObjectCollidedNodes->size() ); ++i ) {
00266 
00267         assert( (*listOfObjectCollidedNodes)[i]->GetAPrimitiveHalfEdgeFace() != NULL );
00268 
00269         N = (*listOfObjectCollidedNodes)[i]->GetAPrimitiveHalfEdgeFace()->GetNormal();
00270 
00271         assert( N.Length() > 0.5 );
00272 
00273         // This is an ad hoc algorithm
00274         if ( true ) {
00275         //if ( separateDistance > Math<T>::ZERO ) {
00276             primB = (*listOfObjectCollidedNodes)[i]->GetAPrimitiveHalfEdgeFace();
00277             vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices );
00278 
00279             //-------------------------------------------------------
00280             // Set Positions of the stand link away from the triangle
00281             int linkNo = (*listOfSutureCollidedNodes)[i]->GetID();
00282 
00283             #ifdef  TAPs_ADVANCED_SIMULATION
00284             if ( 
00285                    pStrandObj->RetSimulationFlagsOfVertexNo( linkNo ).AreSimulationFlagsCleared() 
00286                 && 
00287                    pStrandObj->RetSimulationFlagsOfVertexNo( linkNo+1 ).AreSimulationFlagsCleared() 
00288             ) 
00289             #endif//TAPs_ADVANCED_SIMULATION
00290             {
00291                 // Limit the link length, to prevent the non-stop move of point(s).
00292                 // Here the length is limited to not be over 8 * pStrandObj->GetLength().
00293                 //Real length = ( pStrandObj->GetPointPosition( linkNo ) - pStrandObj->GetPointPosition( linkNo+1 ) ).Length();
00294                 //if ( length > 4 * pStrandObj->GetLength() )   return;
00295 
00296                 // Use triangle centroid to determine the depth of the intersection
00297                 Vector3<T> triCentroid( ( vertexList[0]->GetPosition() + vertexList[1]->GetPosition() + vertexList[2]->GetPosition() ) / 3.0 );
00298                 V1 = pStrandObj->GetPointPosition( linkNo   ) - triCentroid;
00299                 V2 = pStrandObj->GetPointPosition( linkNo+1 ) - triCentroid;
00300 
00301                 N.Normalized();
00302                 value = V1 * N;
00303                 if ( value < 0.0 ) {
00304                     pStrandObj->ChangeOnlyPointPositionByAddedWithThisVector( linkNo  , N * (offset - value) );
00305                 }
00306                 value = V2 * N;
00307                 if ( value < 0.0 ) {
00308                     pStrandObj->ChangeOnlyPointPositionByAddedWithThisVector( linkNo+1, N * (offset - value) );
00309                 }
00310                 //-------------------------------------------------------
00311                 // Set Positions of the stand link away from the triangle
00312                 //N.Normalized();
00313                 //N *= pStrandObj->GetRadius() * 2;
00314                 //int linkNo = (*listOfSutureCollidedNodes)[i]->GetID();
00315                 //pStrandObj->ChangeOnlyPointPositionByAddedWithThisVector( linkNo  , N );
00316                 //pStrandObj->ChangeOnlyPointPositionByAddedWithThisVector( linkNo+1, N );
00317 
00318             }
00319         }
00320     }
00321     pStrandObj->UpdateBVHTree();
00322 
00323     return false;
00324 }
00325 
00326 } // END: namespace Private
00327 //-----------------------------------------------------------------------------
00328 
00329 //-----------------------------------------------------------------------------
00330 //=============================================================================
00331 #endif//#if ( defined TAPs_STRAND_MODEL_HPP && defined TAPs_MULTI_BOUNDING_VOLUME_HPP )
00332 
00333 
00334 
00335 
00336 #if ( defined TAPs_SUTURE_MODEL_HPP && defined TAPs_MULTI_BOUNDING_VOLUME_HPP )
00337 //=============================================================================
00338 //-----------------------------------------------------------------------------
00339 template <typename T>
00340 bool CDR_Suture_vs_MBV ( 
00341     TAPs::OpenGL::ModelSuture<T> *  pSutureObj,             
00342     TAPs::MultiBoundingVolume<T> const * const  pMBVObj,    
00343     TAPs::TransformationSupport<T> const * const pTransform 
00344 )
00345 {
00346     bool bResult = false;
00347     //---------------------------------------------------------------
00348     //bool isThePointInsideTheBV;   // the pt is inside or outside the bv
00349     Vector3<T> vDistance;           // displacement vector
00350     TransformationSupport<T> transform;
00351     //---------------------------------------------------------------
00352     if ( pTransform ) {
00353         transform.ReturnMatrixTransform() *= pTransform->GetMatrixTransform();
00354     }
00355     //---------------------------------------------------------------
00356     transform.ReturnMatrixTransform() *= pMBVObj->GetTransform().GetMatrixTransform();
00357     TransformationSupport<T> savedTransform( transform );
00358     //---------------------------------------------------------------
00359     std::vector< BoundingVolume<T> * >::const_iterator pos = pMBVObj->GetBoundingVolumeList().begin();
00360     //---------------------------------------------------------------
00361     while ( pos != pMBVObj->GetBoundingVolumeList().end() ) {
00362         assert( *pos != NULL );
00363         vDistance.SetXYZ( 0, 0, 0 );
00364         transform = savedTransform;
00365         //-------------------------------------------------
00366         transform.ReturnMatrixTransform() *= (*pos)->GetTransform().GetMatrixTransform();
00367         //-------------------------------------------------
00368         // Transform each vertex of the strand to the bounding volume coordinate
00369         int iDeepestPoint       = -1;
00370         //T tDeepestDistance    = Math<T>::MAX;
00371         //T tDeepestDistance    = std::numeric_limits<T>::max();
00372         T   tDeepestDistance    = 5E32;
00373         Vector3<T>      vDirection;
00374         Vector3<T>      translation( transform.GetTranslation() );
00375         Matrix3x3<T>    inversedRotMatrix( transform.GetMatrixRotation().GetInverse() );
00376 
00377         switch ( (*pos)->GetType() ) {
00378 
00379             //---------------------------------------------
00380             case TAPs::Enum::BOUNDING_CYLINDER:
00381             //---------------------------------------------
00382             #ifdef  TAPs_STRAND_LOCK_SEGMENTS
00383                 for ( unsigned int s = 0; s < pSutureObj->GetNumSegments(); ++s ) {
00384                     // Skip locked or invisible segments
00385                     if ( pSutureObj->GetSegmentLockStatus(s) || !pSutureObj->GetSegmentVisibleStatus(s) ) {}
00386                     else {
00387                         for ( int i = pSutureObj->GetStartPtOfSegment(s); i <= pSutureObj->GetEndPtOfSegment(s); ++i )
00388             #else //TAPs_STRAND_LOCK_SEGMENTS
00389                 {
00390                     {
00391                         for ( unsigned int i = 0; i <= pSutureObj->GetNumberOfStrandLinksWithoutNeedle(); ++i )
00392             #endif//TAPs_STRAND_LOCK_SEGMENTS
00393                         {
00394                             // If the point is fixed, do not move it.
00395                             if ( pSutureObj->GetFixStatusOfPtNo(i) )    continue;
00396 
00397                             //------------------------------------------------------
00398                             // In the local coordinate of the bounding cylinder, 
00399                             // the cylinder axis is parallel to z-axis 
00400                             // where it is shifted by the cylinder center.
00401                             // The cylinder has radius, height and center.
00402                             // Its height is measured from -z and +z axis
00403                             // where its center is situated between height/2 in -z and +z axis.
00404                             Vector3<T> location = pSutureObj->GetPointPosition(i);
00405                             location -= translation;
00406                             location = inversedRotMatrix * location;
00407                             // Shift the location of point by the cylinder center
00408                             // i.e. shift the cylinder to the origin (0,0,0)
00409                             location -= (*pos)->GetCenter();
00410                             //------------------------------------------------------
00411                             // Now the cylinder is centered at the origin with its axis on the z-axis
00412                             // where its height is from -height/2 to +height/2.
00413                             // And the input point has been transformed into the cylinder coordinate.
00414                             // The test can be performed.
00415                             if ( TAPs::CGMath<T>::CD_CylinderAtOrigin_vs_Point( (*pos)->GetRadius(), (*pos)->GetHeight(), location, vDistance ) )
00416                             {
00417                                 bResult = true;
00418                                 //-------------------------
00419                                 // Now rotate it back by the rotation matrix (from the transform matrix).
00420                                 // REMARK: Translation (from the transform matrix) is NOT applied back, 
00421                                 //         because vDistance represents a displacement vector from 
00422                                 //         the input point to the cylinder surface.
00423                                 //         I.e., the suture point is always in the world coordinates.
00424                                 vDistance = transform.GetMatrixRotation() * vDistance;
00425                                 //-------------------------
00426                                 // This statement just ask the strand to move its collided points away
00427                                 pSutureObj->ChangeOnlyPointPositionByAddedWithThisVector( i, vDistance );
00428                                 T tDistance = vDistance.Length();
00429                                 if ( tDeepestDistance > tDistance ) {
00430                                     tDeepestDistance = tDistance;
00431                                     iDeepestPoint = i;
00432                                     vDirection = vDistance;
00433                                 }
00434                                 //-------------------------
00435                             }
00436                         }// Back to Next Strand Point
00437                     }
00438                 }
00439                 break;
00440                 // END: BOUNDING_CYLINDER
00441 
00442             //---------------------------------------------
00443             case TAPs::Enum::BOUNDING_SPHERE:
00444             //---------------------------------------------
00445             #ifdef  TAPs_STRAND_LOCK_SEGMENTS
00446                 for ( unsigned int s = 0; s < pSutureObj->GetNumSegments(); ++s ) {
00447                     // Skip locked or invisible segments
00448                     if ( pSutureObj->GetSegmentLockStatus(s) || !pSutureObj->GetSegmentVisibleStatus(s) ) {}
00449                     else {
00450                         for ( int i = pSutureObj->GetStartPtOfSegment(s); i <= pSutureObj->GetEndPtOfSegment(s); ++i )
00451             #else //TAPs_STRAND_LOCK_SEGMENTS
00452                 {
00453                     {
00454                         for ( unsigned int i = 0; i <= pSutureObj->GetNumberOfStrandLinksWithoutNeedle(); ++i )
00455             #endif//TAPs_STRAND_LOCK_SEGMENTS
00456                         {
00457                             // If the point is fixed, do not move it.
00458                             if ( pSutureObj->GetFixStatusOfPtNo(i) )    continue;
00459 
00460                             //------------------------------------------------------
00461                             // In the local coordinate of the bounding sphere centered at the origin 
00462                             Vector3<T> location = pSutureObj->GetPointPosition(i);
00463                             location -= translation;
00464                             location = inversedRotMatrix * location;
00465                             // Shift the location of point by the sphere center
00466                             // i.e. shift the sphere to the origin (0,0,0)
00467                             location -= (*pos)->GetCenter();
00468                             //------------------------------------------------------
00469                             // Now the sphere is centered at the origin
00470                             // And the input point has been transformed into the sphere coordinate.
00471                             // The test can be performed.
00472                             if ( TAPs::CGMath<T>::CD_SphereAtOrigin_vs_Point( (*pos)->GetRadius(), location, vDistance ) )
00473                             {
00474                                 bResult = true;
00475                                 //-------------------------
00476                                 // Now rotate it back by the rotation matrix (from the transform matrix).
00477                                 // REMARK: Translation (from the transform matrix) is NOT applied back, 
00478                                 //         because vDistance represents a displacement vector from 
00479                                 //         the input point to the sphere surface.
00480                                 //         I.e., the suture point is always in the world coordinates.
00481                                 vDistance = transform.GetMatrixRotation() * vDistance;
00482                                 //-------------------------
00483                                 // This statement just ask the strand to move its collided points away
00484                                 pSutureObj->ChangeOnlyPointPositionByAddedWithThisVector( i, vDistance );
00485                                 T tDistance = vDistance.Length();
00486                                 if ( tDeepestDistance > tDistance ) {
00487                                     tDeepestDistance = tDistance;
00488                                     iDeepestPoint = i;
00489                                     vDirection = vDistance;
00490                                 }
00491                                 //-------------------------
00492                             }
00493                         }// Back to Next Strand Point
00494                     }
00495                 }
00496                 break;
00497                 // END: BOUNDING_SPHERE
00498 
00499         }//END: switch ( (*pos)->GetType() ) {...}
00500         ++pos;  // Next Bounding Volume
00501     }
00502     return bResult;
00503 }
00504 // END: CDR_Stuture_vs_MBV(...)
00505 //-----------------------------------------------------------------------------
00506 
00507 //-----------------------------------------------------------------------------
00508 //=============================================================================
00509 #endif//#if ( defined TAPs_SUTURE_MODEL_HPP && defined TAPs_MULTI_BOUNDING_VOLUME_HPP )
00510 
00511 
00512 
00513 
00514 #if ( defined TAPs_STRAND_MODEL_HPP && defined TAPs_DEFORM_MESH_HPP )
00515 //=============================================================================
00516 //-----------------------------------------------------------------------------
00517 template <typename T>
00518 bool CDR_Strand_vs_DeformMesh ( 
00519     TAPs::OpenGL::ModelStrand<T> * pStrandObj,          
00520     TAPs::DeformMesh<T> const * const pDeformMeshObj    
00521 )
00522 {
00523     bool bResult = false;
00524     //---------------------------------------------------------------
00525     T distance, length;
00526     int iClosestRow, iClosestCol; 
00527     Vector3<T> strandPos, skinPos;
00528     int iNoRows;
00529     int iNoCols;
00530     pDeformMeshObj->GetNumberOfRowsAndColumns( iNoRows, iNoCols );
00531     for ( int i = 0; i < pStrandObj->GetNumberOfLinks(); ++i ) {
00532         iClosestRow = -1;
00533         iClosestCol = -1;
00534         distance = 0.1;
00535         strandPos = pStrandObj->GetPointPosition( i );
00536         for ( int r = 0; r < iNoRows; ++r ) {
00537             for ( int c = 0; c < iNoCols; ++c ) {
00538                 skinPos = pDeformMeshObj->GetPositionOfPointNumber( r, c );
00539                 length = (strandPos - skinPos).Length();
00540                 if ( length < distance ) {
00541                     iClosestRow = r;
00542                     iClosestCol = c;
00543                     distance = length;
00544                 }
00545             }
00546         }
00547         if ( iClosestRow >= 0 ) {
00548             bResult = true;
00549             pStrandObj->ChangeOnlyPointPositionByAddedWithThisVector( i, Vector3<T>( 0, 0.1, 0 ) );
00550         }
00551     }
00552     //---------------------------------------------------------------
00553     return bResult;
00554 }
00555 // END: CDR_Strand_vs_DeformMesh(...)
00556 //-----------------------------------------------------------------------------
00557 //=============================================================================
00558 #endif//( defined TAPs_STRAND_MODEL_HPP && defined TAPs_DEFORM_MESH_HPP )
00559 
00560 
00561 
00562 
00563 #if ( defined TAPs_SUTURE_MODEL_HPP && defined TAPs_DEFORM_MESH_HPP )
00564 //=============================================================================
00565 //-----------------------------------------------------------------------------
00566 template <typename T>
00567 bool CDR_Suture_vs_DeformMesh ( 
00568     TAPs::OpenGL::ModelSuture<T> * pSutureObj,          
00569     TAPs::DeformMesh<T> const * const pDeformMeshObj    
00570 )
00571 {
00572     bool bResult = false;
00573     //---------------------------------------------------------------
00574     T distance, length;
00575     int iClosestRow, iClosestCol; 
00576     Vector3<T> suturePos, skinPos;
00577     int iNoRows;
00578     int iNoCols;
00579     pDeformMeshObj->GetNumberOfRowsAndColumns( iNoRows, iNoCols );
00580     for ( int i = 0; i < pSutureObj->GetNumberOfStrandLinksWithoutNeedle(); ++i ) {
00581         iClosestRow = -1;
00582         iClosestCol = -1;
00583         distance = 0.1;
00584         suturePos = pSutureObj->GetPointPosition( i );
00585         for ( int r = 0; r < iNoRows; ++r ) {
00586             for ( int c = 0; c < iNoCols; ++c ) {
00587                 skinPos = pDeformMeshObj->GetPositionOfPointNumber( r, c );
00588                 length = (suturePos - skinPos).Length();
00589                 if ( length < distance ) {
00590                     iClosestRow = r;
00591                     iClosestCol = c;
00592                     distance = length;
00593                 }
00594             }
00595         }
00596         if ( iClosestRow >= 0 ) {
00597             bResult = true;
00598             pSutureObj->ChangeOnlyPointPositionByAddedWithThisVector( i, Vector3<T>( 0, 0.1, 0 ) );
00599         }
00600     }
00601     //---------------------------------------------------------------
00602     return bResult;
00603 }
00604 // END: CDR_Stuture_vs_DeformMesh(...)
00605 //-----------------------------------------------------------------------------
00606 //=============================================================================
00607 #endif//( defined TAPs_SUTURE_MODEL_HPP && defined TAPs_DEFORM_MESH_HPP )
00608 
00609 
00610 
00611 
00612 #if ( defined TAPs_DEFORM_MESH_HPP && defined TAPs_MULTI_BOUNDING_VOLUME_HPP )
00613 //=============================================================================
00614 //-----------------------------------------------------------------------------
00615 template <typename T>
00616 bool CDR_DeformMesh_vs_MBV ( 
00617     TAPs::DeformMesh<T> * pDeformMeshObj,                   
00618     TAPs::MultiBoundingVolume<T> const * const  pMBVObj,    
00619     TAPs::TransformationSupport<T> const * const pTransform 
00620 )
00621 {
00622     bool bResult = false;
00623     //---------------------------------------------------------------
00624     int iNoRows;
00625     int iNoCols;
00626     pDeformMeshObj->GetNumberOfRowsAndColumns( iNoRows, iNoCols );
00627     //---------------------------------------------------------------
00628     Vector3<T> vDistance;           // displacement vector
00629     TransformationSupport<T> transform;
00630     //---------------------------------------------------------------
00631     if ( pTransform ) {
00632         transform.ReturnMatrixTransform() *= pTransform->GetMatrixTransform();
00633     }
00634     //---------------------------------------------------------------
00635     transform.ReturnMatrixTransform() *= pMBVObj->GetTransform().GetMatrixTransform();
00636     TransformationSupport<T> savedTransform( transform );
00637     //---------------------------------------------------------------
00638     std::vector< BoundingVolume<T> * >::const_iterator pos = pMBVObj->GetBoundingVolumeList().begin();
00639     //---------------------------------------------------------------
00640     while ( pos != pMBVObj->GetBoundingVolumeList().end() ) {
00641         assert( *pos != NULL );
00642         vDistance.SetXYZ( 0, 0, 0 );
00643         transform = savedTransform;
00644         //-------------------------------------------------
00645         transform.ReturnMatrixTransform() *= (*pos)->GetTransform().GetMatrixTransform();
00646         //-------------------------------------------------
00647         // For transforming each vertex of the deformable mesh to the bounding volume coordinate
00648         Vector3<T>      translation( transform.GetTranslation() );
00649         Matrix3x3<T>    inversedRotMatrix( transform.GetMatrixRotation().GetInverse() );
00650 
00651         switch ( (*pos)->GetType() ) {
00652 
00653             //---------------------------------------------
00654             case TAPs::Enum::BOUNDING_CYLINDER:
00655             //---------------------------------------------
00656                 // Transform each vertex of the flat skin to the bounding volume coordinate
00657                 // Exclude the boundary
00658                 for ( int r = 1; r < iNoRows-1; ++r ) {
00659                     for ( int c = 1; c < iNoCols-1; ++c ) {
00660                         //-------------------------------
00661                         // In the local coordinate of the bounding cylinder, 
00662                         // the cylinder axis is parallel to z-axis 
00663                         // where it is shifted by the cylinder center.
00664                         // The cylinder has radius, height and center.
00665                         // Its height is measured from -z and +z axis
00666                         // where its center is situated between height/2 in -z and +z axis.
00667                         Vector3<T> location = pDeformMeshObj->GetPositionOfPointNumber( r, c );
00668                         location -= translation;
00669                         location = inversedRotMatrix * location;
00670                         // Shift the location of point by the cylinder center
00671                         // i.e. shift the cylinder to the origin (0,0,0)
00672                         location -= (*pos)->GetCenter();
00673                         //-------------------------------
00674                         // Now the cylinder is centered at the origin with its axis on the z-axis
00675                         // where its height is from -height/2 to +height/2.
00676                         // And the input point has been transformed into the cylinder coordinate.
00677                         // The test can be performed.
00678                         if ( TAPs::CGMath<T>::CD_CylinderAtOrigin_vs_Point( (*pos)->GetRadius(), (*pos)->GetHeight(), location, vDistance ) )
00679                         {
00680                             bResult = true;
00681                             //-----------------------------
00682                             // Now rotate it back by the rotation matrix (from the transform matrix).
00683                             // REMARK: Translation (from the transform matrix) is NOT applied back, 
00684                             //         because vDistance represents a displacement vector from 
00685                             //         the input point to the cylinder surface.
00686                             //         I.e., the deformable mesh point is always in the world coordinates.
00687                             vDistance = transform.GetMatrixRotation() * vDistance;
00688                             //-----------------------------
00689                             // This statement just ask the vertex (row,col) of the flat skin to move its collided points away
00690                             //pDeformMeshObj->SetParticleFixStatus( r, c, true );   // DEBUG
00691                             //pDeformMeshObj->MovePositionOfPointNumber( r, c, vDistance );
00692 
00693                             // DEBUG (HACKING)
00694                             pDeformMeshObj->MovePositionOfPointNumber( r, c, Vector3<T>( 0, -1, 0 ) );
00695                             //-----------------------------
00696                         }
00697                     }// Back to the Next Column of the Flat Skin
00698                 }// Back to the Next Row of the Flat Skin
00699                 break;
00700                 // END: BOUNDING_CYLINDER
00701 
00702             //---------------------------------------------
00703             case TAPs::Enum::BOUNDING_SPHERE:
00704             //---------------------------------------------
00705                 // Transform each vertex of the flat skin to the bounding volume coordinate
00706                 // Exclude the boundary
00707                 for ( int r = 1; r < iNoRows-1; ++r ) {
00708                     for ( int c = 1; c < iNoCols-1; ++c ) {
00709                         //-------------------------------
00710                         // In the local coordinate of the bounding cylinder, 
00711                         // the cylinder axis is parallel to z-axis 
00712                         // where it is shifted by the cylinder center.
00713                         // The cylinder has radius, height and center.
00714                         // Its height is measured from -z and +z axis
00715                         // where its center is situated between height/2 in -z and +z axis.
00716                         Vector3<T> location = pDeformMeshObj->GetPositionOfPointNumber( r, c );
00717                         location -= translation;
00718                         location = inversedRotMatrix * location;
00719                         // Shift the location of point by the cylinder center
00720                         // i.e. shift the cylinder to the origin (0,0,0)
00721                         location -= (*pos)->GetCenter();
00722                         //-------------------------------
00723                         // Now the cylinder is centered at the origin with its axis on the z-axis
00724                         // where its height is from -height/2 to +height/2.
00725                         // And the input point has been transformed into the cylinder coordinate.
00726                         // The test can be performed.
00727                         if ( TAPs::CGMath<T>::CD_SphereAtOrigin_vs_Point( (*pos)->GetRadius(), location, vDistance ) )
00728                         {
00729                             bResult = true;
00730                             //-----------------------------
00731                             // Now rotate it back by the rotation matrix (from the transform matrix).
00732                             // REMARK: Translation (from the transform matrix) is NOT applied back, 
00733                             //         because vDistance represents a displacement vector from 
00734                             //         the input point to the cylinder surface.
00735                             //         I.e., the deformable mesh point is always in the world coordinates.
00736                             vDistance = transform.GetMatrixRotation() * vDistance;
00737                             //-----------------------------
00738                             // This statement just ask the vertex (row,col) of the flat skin to move its collided points away
00739                             //pDeformMeshObj->SetParticleFixStatus( r, c, true );   // DEBUG
00740                             //pDeformMeshObj->MovePositionOfPointNumber( r, c, vDistance );
00741 
00742                             // DEBUG (HACKING)
00743                             pDeformMeshObj->MovePositionOfPointNumber( r, c, Vector3<T>( 0, -1, 0 ) );
00744                             //-----------------------------
00745                         }
00746                     }// Back to the Next Column of the Flat Skin
00747                 }// Back to the Next Row of the Flat Skin
00748                 break;
00749                 // END: BOUNDING_SPHERE
00750 
00751         }//END: switch ( (*pos)->GetType() ) {...}
00752         //-------------------------------------------------
00753         ++pos;  // Next Bounding Volume
00754     }
00755     //---------------------------------------------------------------
00756     return bResult;
00757 }
00758 // END: CDR_DeformMesh_vs_MBV(...)
00759 //-----------------------------------------------------------------------------
00760 //=============================================================================
00761 #endif//#if ( defined TAPs_DEFORM_MESH_HPP && defined TAPs_MULTI_BOUNDING_VOLUME_HPP )
00762 
00763 
00764 
00765 
00766 #ifdef  TAPs_BOUNDING_VOLUME_HPP
00767 //=============================================================================
00768 // CDR_PolygonalMesh_vs_BV
00769 //-----------------------------------------------------------------------------
00770 //template <typename T>
00771 //bool CDR_PolygonalMesh_vs_BV ( 
00772 //  TAPs::OpenGL::PolygonalModel<T> * pPolygonalMeshObj,    //!< a PolygonalModel object
00773 //  TAPs::BoundingVolume<T> const * const   pBVObj          //!< a bounding volume object
00774 //)
00775 //{
00776 //  std::cout << "CDR_PolygonalMesh_vs_BV( PolygonalModel<T>, BoundingVolume<T> ) -- NOT IMPLEMENTED YET!" << std::endl;
00777 //  bool bResult = false;
00778 //  //---------------------------------------------------------------
00779 //  //---------------------------------------------------------------
00780 //  return bResult;
00781 //}
00782 // END: CDR_PolygonalMesh_vs_BV(...) for PolygonalModel
00783 //-----------------------------------------------------------------------------
00784 
00785 //-----------------------------------------------------------------------------
00786 //template <typename T>
00787 //bool CDR_PolygonalMesh_vs_BV ( 
00788 //  TAPs::OpenGL::XPolygonalModel<T> * pPolygonalMeshObj,   //!< a PolygonalModel object
00789 //  TAPs::BoundingVolume<T> const * const   pBVObj          //!< a bounding volume object
00790 //)
00791 //{
00792 //  std::cout << "CDR_XPolygonalMesh_vs_BV( XPolygonalModel<T>, BoundingVolume<T> ) -- NOT IMPLEMENTED YET!" << std::endl;
00793 //  bool bResult = false;
00794 //  //---------------------------------------------------------------
00795 //  //---------------------------------------------------------------
00796 //  return bResult;
00797 //}
00798 // END: CDR_PolygonalMesh_vs_BV(...) for XPolygonalModel
00799 //-----------------------------------------------------------------------------
00800 
00801 //-----------------------------------------------------------------------------
00802 template <typename T>
00803 bool CDR_PolygonalMesh_vs_BV ( 
00804     TAPs::OpenGL::HalfEdgeModel<T> * pPolygonalMeshObj,     
00805     TAPs::BoundingVolume<T> const * const   pBVObj          
00806 )
00807 {
00808     #ifdef  TAPs_DEBUG_COLLISION_DETECTION
00809     //pPolygonalMeshObj->GetBVHTree()->ClearFlags();
00810     #endif//TAPs_DEBUG_COLLISION_DETECTION
00811 
00812     #ifdef  TAPs_DEBUG_MODE
00813     std::cout << "CDR_HalfEdgeMesh_vs_BV( HalfEdgeModel<T>, BoundingVolume<T> )\n";
00814     #endif//TAPs_DEBUG_MODE
00815 
00816 
00817     //std::cout << "BVHTree: " << *(pPolygonalMeshObj->GetBVHTree()) << "\n";
00818 
00819     //---------------------------------------------------------------
00820     if ( pPolygonalMeshObj->GetBVHTree()->TestOverlapWithTillLeafNodes( pBVObj ) )
00821     {
00822         //-------------------------------------------------
00823         T separateDistanceConstraint;
00824         Vector3<T> N, centerA;
00825         T separateDistance;
00826         HEFace<T> * primB;
00827         std::vector< HEVertex<T> * const > vertexList;
00828         int noOfVertices;
00829         //-------------------------------------------------
00830         std::vector< BVHNode<T> * > *   listOfCollidedNode_Def   = &pPolygonalMeshObj->GetBVHTree()->GetListOfCollidedNodes();
00831         std::set< BVHNode<T> * > defPolyMesh_NodeSet;
00832 
00833         //std::cout << "listOfCollidedNode_Def SIZE: " << listOfCollidedNode_Def->size() << "\n";
00834 
00835         // Collision Response
00836         //-------------------------------------------------
00837         // Deform the deformable polygonal mesh away from the rigid polygonal mesh
00838         switch ( pBVObj->GetType() ) {
00839             case TAPs::Enum::BOUNDING_SPHERE:
00840                 for ( int i = 0; i < static_cast<int>( listOfCollidedNode_Def->size() ); ++i ) {
00841 
00842                     separateDistanceConstraint = 0.5 * ( (*listOfCollidedNode_Def)[i]->GetRadius() + pBVObj->GetRadius() );
00843                     //centerA = ( pRigidPolyMesh->GetTransform().GetMatrixTransform() * 
00844                     //          Vector4<T>( (*listOfCollidedNode_Rigid)[i]->GetCenter() ) ).GetVector3();
00845                     centerA = pBVObj->GetCenter();
00846                     N = centerA - (*listOfCollidedNode_Def)[i]->GetCenter();
00847                     separateDistance = separateDistanceConstraint - N.Length();
00848                     if ( true ) {
00849                     //if ( separateDistance > Math<T>::ZERO ) {
00850                         N.Normalized();
00851                         N *= separateDistance;
00852                         primB = (*listOfCollidedNode_Def)[i]->GetAPrimitiveHalfEdgeFace();
00853                         vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices );
00854                         //-------------------------------
00855                         // For each vertex in a primitive
00856                         for ( int j = 0; j < noOfVertices; ++j ) {
00857                             //vertexList[j]->SetPosition( vertexList[j]->GetPosition() - N );
00858                             vertexList[j]->SetPosition( vertexList[j]->GetPosition() - Vector3<T>( 0.01, 0.01, 0.01 ) );
00859                             //vertexList[j]->
00860                         }
00861                     }
00862 
00863                     #ifdef  TAPs_DEBUG_COLLISION_DETECTION
00864                     //(*listOfCollidedNode_Def)[i]->flag = true;
00865                     #endif//TAPs_DEBUG_COLLISION_DETECTION
00866 
00867                     // List of BVNodes to be updated
00868                     defPolyMesh_NodeSet.insert( (*listOfCollidedNode_Def)[i] );
00869                 }
00870                 break;
00871 
00872             default:
00873                 std::cout << "CDR_PolygonalMesh_vs_BV of BV Type (" << pBVObj->GetType() << ") doesn't support!\n";
00874                 break;
00875         }
00876         //-------------------------------------------------
00877         // Update Normals of Deformable Polygonal Mesh
00878         pPolygonalMeshObj->CalAndSetNormals();
00879         //-------------------------------------------------
00880         // Update Bounding Volume Hierarchy of Deformable Polygonal Mesh
00881         pPolygonalMeshObj->GetBVHTree()->Update( defPolyMesh_NodeSet );
00882         //-------------------------------------------------
00883         return true;
00884     }
00885     //---------------------------------------------------------------
00886     return false;
00887 }
00888 // END: CDR_PolygonalMesh_vs_BV(...) for HalfEdgeModel
00889 //-----------------------------------------------------------------------------
00890 
00891 
00892 
00893 
00894 //-----------------------------------------------------------------------------
00895 template <typename T>
00896 bool CDR_PolygonalMesh_vs_BV ( 
00897     TAPs::OpenGL::HETriMeshOneModelMultiParts<T> * pPolygonalMeshObj,   
00898     TAPs::BoundingVolume<T> const * const   pBVObj          
00899 )
00900 {
00901     ListOfContactPts.clear();
00902     ListOfForces.clear();
00903 
00904     #ifdef  TAPs_DEBUG_COLLISION_DETECTION
00905     pPolygonalMeshObj->GetBVHTree()->ClearFlags();
00906     #endif//TAPs_DEBUG_COLLISION_DETECTION
00907 
00908     //#ifdef    TAPs_DEBUG_MODE
00909     std::cout << "CDR_PolygonalMesh_vs_BV( HalfEdgeModel<T>, BoundingVolume<T> )\n";
00910     //#endif//TAPs_DEBUG_MODE
00911 
00912     std::cout << "BVHTree: " << *(pPolygonalMeshObj->GetBVHTree()) << "\n";
00913 
00914     bool bResult = false;
00915 
00916     // Collision Detection
00917     bResult = pPolygonalMeshObj->GetBVHTree()->TestOverlapWithTillLeafNodes( pBVObj );
00918 
00919     //---------------------------------------------------------------
00920     // Collision Response
00921     if ( bResult ) {
00922 
00923         // Reset the result for primitive-primitive test, 
00924         // because the previous result is only from bounding volume test.
00925         bResult = false;
00926 
00927         //-------------------------------------------------
00928         T separateDistanceConstraint;
00929         Vector3<T> N, centerA;
00930         T separateDistance;
00931         HEFace<T> * primB;
00932         std::vector< HEVertex<T> * const > vertexList;
00933         int noOfVertices;
00934         //-------------------------------------------------
00935         TransformationSupport<T> trxMBV;    // default constructor is an identity transformation
00936 
00937         //-------------------------------------------------
00938         std::set< BVHNode<T> * > defPolyMesh_NodeSet;
00939 
00940         // Get the list of collided nodes and bounding volumes
00941         std::vector< BVsAndNodesList<T> > * bvList = &pPolygonalMeshObj->GetBVHTree()->GetListOfCollidedBoundingVolumesAndNodes();
00942         //-------------------------------------------------
00943         // Traverse the list of bounding volumes
00944         std::vector< BVsAndNodesList<T> >::const_iterator pos = bvList->begin();
00945         //-------------------------------------------------
00946         //std::cout << "CDR_PolygonalMesh_vs_BV(...) for HETriMeshOneModelMultiParts --> \n";
00947         //std::cout << "\tCASE: the polygonal mesh object's transformation is on. -- NOT IMPLEMENTED YET!\n";
00948 
00949         // Mesh's inverse transformation
00950         Matrix4x4<T> trxInvMesh = pPolygonalMeshObj->GetTransform().GetMatrixTransform();
00951         trxInvMesh.Inversed();
00952         Vector3<T> vOrigin( (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(0,0,0,1)).GetVector3() );
00953 
00954         while ( pos != bvList->end() ) {
00955 
00956             int count = 0;
00957 
00958             // Store the transformation of the bounding volume including the mesh's inverse transformation
00959             TransformationSupport<T> trx = (*pos).BV->GetTransform();
00960             (*pos).BV->GetTransform().SetMatrixTransform( trxInvMesh * trx.GetMatrixTransform() );
00961 
00962             //-----------------------------------------
00963             // Deform the deformable polygonal mesh away from the rigid polygonal mesh
00964             switch ( (*pos).BV->GetType() ) {
00965 
00966                 case TAPs::Enum::BOUNDING_SPHERE:
00967                     {
00968 
00969                         std::cout << "BV: " << (*pos).BV->GetName() << "\n";
00970 
00971                         // For Test against triangle
00972                         //---------------------------------------------
00973                         // Transform the BV due to its transformation, center, and radius
00974                         T radiusOfBV = (*pos).BV->GetRadius();
00975                         Vector3<T> C( (*pos).BV->GetCenter() );
00976                         Matrix4x4<T> translation( 1, 0, 0, C[0], 
00977                                                   0, 1, 0, C[1],
00978                                                   0, 0, 1, C[2],
00979                                                   0, 0, 0, 1 );
00980                         Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV );
00981                         Matrix4x4<T> scale( S[0], 0,    0,    0, 
00982                                             0,    S[1], 0,    0,
00983                                             0,    0,    S[2], 0,
00984                                             0,    0,    0,    1 );
00985                         // The BV's current transformation includes the mesh's inverse transformation (see the code above)
00986                         Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale;
00987 
00988                         // BV Sphere's center and radius after the whole transformation from 
00989                         // BV's transformation to mesh's inverse transformation.
00990                         // I.e., transforming the BV to mesh's coordinate
00991                         Vector3<T> centerOfBV_inMeshCoord = (mat * Vector4<T>(0,0,0,1)).GetVector3();
00992                         T radiusOfBV_inMeshCoord = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV_inMeshCoord ).Length();
00993 
00994                         // Inverse the mesh's transformation to the BV's pure transformation
00995                         mat = pPolygonalMeshObj->GetTransform().GetMatrixTransform() * mat;
00996 
00997                         // BV Sphere's center and radius after the BV's pure transformation
00998                         Vector3<T> centerOfBV( (mat * Vector4<T>(0,0,0,1)).GetVector3() );
00999                         radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length();
01000                         //---------------------------------------------
01001 
01002                         count = 0;
01003                         for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) {
01004 
01005                             bool testResult = false;
01006 
01007                             // Assume triangle is in Sphere Node
01008                             // Test the triangle in sphere node with BVSphere
01009                             primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace();
01010                             vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices );
01011                             Vector3<T> cdrVec[3];
01012 
01013                             //*
01014                             // Test against each vertex in the triangle
01015                             //-----------------------------------
01016                             for ( int j = 0; j < noOfVertices; ++j ) {
01017                                 if( (*pos).BV->TestPointLocation( vertexList[j]->GetPosition(), &(cdrVec[j]) ) )
01018                                 {
01019                                     vertexList[j]->SetPosition( vertexList[j]->GetPosition() + cdrVec[j] );
01020                                     Vector3<T> force( (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(cdrVec[j])).GetVector3() - vOrigin );
01021 
01022                                     //ListOfContactPts.push_back( Vector3<GLfloat>( (*pos).BV->GetCenter()[0], (*pos).BV->GetCenter()[1], (*pos).BV->GetCenter()[2] ) );
01023                                     ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) );
01024                                     ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) );
01025 
01026                                     testResult = true;
01027                                 }
01028                             }
01029                             //-----------------------------------
01030                             //*/
01031 
01032                             //*
01033                             // Test against triangle
01034                             //-----------------------------------
01035                             //Vector3<T> contactPt;
01036                             if ( TAPs::CGMath<T>::FindIntersectionSphereTriangle( 
01037                                     centerOfBV_inMeshCoord, radiusOfBV_inMeshCoord, // BVSphere properties
01038                                     vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices
01039                                     cdrVec[0], cdrVec[1], cdrVec[2]     // out vectors
01040                                     //, &contactPt
01041                             ) ) {
01042                                 Vector3<T> force_1( cdrVec[0] * CDScaleForSphereBVWithTriangle );
01043                                 Vector3<T> force_2( cdrVec[1] * CDScaleForSphereBVWithTriangle );
01044                                 Vector3<T> force_3( cdrVec[2] * CDScaleForSphereBVWithTriangle );
01045 
01046                                 vertexList[0]->SetPosition( vertexList[0]->GetPosition() + force_1 );
01047                                 vertexList[1]->SetPosition( vertexList[1]->GetPosition() + force_2 );
01048                                 vertexList[2]->SetPosition( vertexList[2]->GetPosition() + force_3 );
01049 
01050                                 force_1 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_1)).GetVector3() - vOrigin;
01051                                 force_2 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_2)).GetVector3() - vOrigin;
01052                                 force_3 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_3)).GetVector3() - vOrigin;
01053 
01054                                 //ListOfContactPts.push_back( Vector3<GLfloat>( contactPt[0], contactPt[1], contactPt[2] ) );
01055                                 ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) );
01056                                 Vector3<T> force( ( force_1 + force_2 + force_3 )/3 );
01057                                 ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) );
01058 
01059                                 testResult = true;
01060                             }
01061                             //-----------------------------------
01062                             //*/
01063 
01064 
01065                             std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n";
01066 
01067                             // List of BVNodes to be updated
01068                             if ( testResult ) {
01069                                 defPolyMesh_NodeSet.insert( (*pos).NodeList[i] );
01070                                 bResult = true;
01071                             }
01072                         }
01073                     }
01074                     break;
01075 
01076                 case TAPs::Enum::BOUNDING_CYLINDER:
01077                     {
01078                         std::cout << "BV: " << (*pos).BV->GetName() << "\n";
01079 
01080                         // For Test against triangle
01081                         //---------------------------------------------
01082                         // Transform the BV due to its transformation, center, and radius
01083                         T radiusOfBV = (*pos).BV->GetRadius();
01084                         Vector3<T> C( (*pos).BV->GetCenter() );
01085                         Matrix4x4<T> translation( 1, 0, 0, C[0], 
01086                                                   0, 1, 0, C[1],
01087                                                   0, 0, 1, C[2],
01088                                                   0, 0, 0, 1 );
01089                         Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV );
01090                         Matrix4x4<T> scale( S[0], 0,    0,    0, 
01091                                             0,    S[1], 0,    0,
01092                                             0,    0,    S[2], 0,
01093                                             0,    0,    0,    1 );
01094                         // The BV's current transformation includes the mesh's inverse transformation (see the code above)
01095                         Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale;
01096 
01097                         // BV Sphere's center and radius after the whole transformation from 
01098                         // BV's transformation to mesh's inverse transformation.
01099                         // I.e., transforming the BV to mesh's coordinate
01100                         T halfHeightOfBV = (*pos).BV->GetHeight() / 2.0;
01101                         Vector3<T> centerOfBV_inMeshCoord = (mat * Vector4<T>(0,0,0,1)).GetVector3();
01102                         T radiusOfBV_inMeshCoord = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV_inMeshCoord ).Length();
01103                         Vector3<T> topPtOfBV_inMeshCoord( (mat * Vector4<T>(0,0,halfHeightOfBV,1)).GetVector3() );
01104                         Vector3<T> bottomPtOfBV_inMeshCoord( (mat * Vector4<T>(0,0,-halfHeightOfBV,1)).GetVector3() );
01105 
01106                         // Inverse the mesh's transformation to the BV's pure transformation
01107                         mat = pPolygonalMeshObj->GetTransform().GetMatrixTransform() * mat;
01108 
01109                         // BV Sphere's center and radius after the BV's pure transformation
01110                         Vector3<T> centerOfBV( (mat * Vector4<T>(0,0,0,1)).GetVector3() );
01111                         radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length();
01112                         Vector3<T> topPtOfBV( (mat * Vector4<T>(0,0,halfHeightOfBV,1)).GetVector3() );
01113                         Vector3<T> bottomPtOfBV( (mat * Vector4<T>(0,0,-halfHeightOfBV,1)).GetVector3() );
01114                         //---------------------------------------------
01115 
01116                         count = 0;
01117                         for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) {
01118 
01119                             bool testResult = false;
01120 
01121                             // Assume triangle is in Sphere Node
01122                             // Test the triangle in sphere node with BVCylinder
01123                             primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace();
01124                             vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices );
01125                             Vector3<T> cdrVec[3];
01126 
01127                             //*
01128                             // Test against each vertex in the triangle
01129                             //-----------------------------------
01130                             for ( int j = 0; j < noOfVertices; ++j ) {
01131                                 if( (*pos).BV->TestPointLocation( vertexList[j]->GetPosition(), &(cdrVec[j]) ) )
01132                                 {
01133                                     vertexList[j]->SetPosition( vertexList[j]->GetPosition() + cdrVec[j] );
01134                                     Vector3<T> force( (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(cdrVec[j])).GetVector3() - vOrigin );
01135 
01136                                     //ListOfContactPts.push_back( Vector3<GLfloat>( (*pos).BV->GetCenter()[0], (*pos).BV->GetCenter()[1], (*pos).BV->GetCenter()[2] ) );
01137                                     ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) );
01138                                     ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) );
01139 
01140                                     testResult = true;
01141                                 }
01142                             }
01143                             //-----------------------------------
01144                             //*/
01145 
01146                             //*
01147                             // Test against triangle
01148                             //-----------------------------------
01149                             Vector3<T> contactPt;
01150                             if ( TAPs::CGMath<T>::FindIntersectionCylinderTriangle( 
01151                                     topPtOfBV_inMeshCoord, bottomPtOfBV_inMeshCoord, radiusOfBV_inMeshCoord,    // BVCylinder properties
01152                                     vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices
01153                                     cdrVec[0], cdrVec[1], cdrVec[2]         // out vectors
01154                                     , &contactPt
01155                             ) ) {
01156                                 Vector3<T> force_1( cdrVec[0] * CDScaleForSphereBVWithTriangle );
01157                                 Vector3<T> force_2( cdrVec[1] * CDScaleForSphereBVWithTriangle );
01158                                 Vector3<T> force_3( cdrVec[2] * CDScaleForSphereBVWithTriangle );
01159 
01160                                 vertexList[0]->SetPosition( vertexList[0]->GetPosition() + force_1 );
01161                                 vertexList[1]->SetPosition( vertexList[1]->GetPosition() + force_2 );
01162                                 vertexList[2]->SetPosition( vertexList[2]->GetPosition() + force_3 );
01163 
01164                                 force_1 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_1)).GetVector3() - vOrigin;
01165                                 force_2 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_2)).GetVector3() - vOrigin;
01166                                 force_3 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_3)).GetVector3() - vOrigin;
01167 
01168                                 contactPt = ( (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(contactPt)).GetVector3() );
01169 
01170                                 ListOfContactPts.push_back( Vector3<GLfloat>( contactPt[0], contactPt[1], contactPt[2] ) );
01171                                 Vector3<T> force( ( force_1 + force_2 + force_3 )/3 );
01172                                 ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) );
01173 
01174                                 testResult = true;
01175                             }
01176                             //-----------------------------------
01177                             //*/
01178 
01179                             std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n";
01180 
01181                             // List of BVNodes to be updated
01182                             if ( testResult ) {
01183                                 defPolyMesh_NodeSet.insert( (*pos).NodeList[i] );
01184                                 bResult = true;
01185                             }
01186                         }
01187                     }
01188                     break;
01189 
01190                 default:
01191                     std::cout << "CDR_PolygonalMesh_vs_BV of BV Type (" << (*pos).BV->GetType() << ") doesn't support!\n";
01192                     break;
01193             }
01194 
01195             // Restore the transformation of the bounding volume
01196             //(*pos).BV->GetTransform().SetMatrixTransform( trx.GetMatrixTransform() );
01197             (*pos).BV->SetTransform( trx );
01198             // Next Bounding Volume
01199             ++pos;
01200         }
01201         //-------------------------------------------------
01202 
01203         //-------------------------------------------------
01204         // Update Normals of Deformable Polygonal Mesh
01205         //pPolygonalMeshObj->CalAndSetNormals();        // commented out to rely on AdvanceSimulation to update the normals
01206         //-------------------------------------------------
01207         // Update Bounding Volume Hierarchy of Deformable Polygonal Mesh
01208         pPolygonalMeshObj->GetBVHTree()->Update( defPolyMesh_NodeSet );
01209         // FOR HETriMeshOneModelMultiParts
01210         //-------------------------------------------------
01211         // Update for the model's internal simulation
01212         for ( int i = 0; i < static_cast<int>( pPolygonalMeshObj->GetListOfParts().size() ); ++i ) {
01213             pPolygonalMeshObj->GetPtrToPartNo(i)->UpdateStateToArray();
01214         }
01215     }
01216     //---------------------------------------------------------------
01217     if ( totalForce ) {
01218         totalForce->SetXYZ( 0, 0, 0 );
01219         Vector3<float> force( 0, 0, 0 );
01220         for ( int i = 0; i < ListOfForces.size(); ++i ) {
01221             force += ListOfForces[i];
01222         }
01223         force *= gain;
01224         (*totalForce).SetXYZ( force[0], force[1], force[2] );
01225     }
01226 
01227     return bResult;
01228 }
01229 // END: CDR_PolygonalMesh_vs_BV(...) for HETriMeshOneModelMultiParts
01230 //-----------------------------------------------------------------------------
01231 
01232 
01233 
01234 
01235 //-----------------------------------------------------------------------------
01236 //=============================================================================
01237 #endif//TAPs_BOUNDING_VOLUME_HPP
01238 
01239 
01240 
01241 
01242 //=============================================================================
01243 //-----------------------------------------------------------------------------
01244 //template <typename T>
01245 //bool CD_PolygonalMesh_vs_LineSegment ( 
01246 //  TAPs::OpenGL::PolygonalModel<T> * pPolygonalMeshObj,    //!< a PolygonalModel object
01247 //  TAPs::Vector3<T> const * const  ptA,    //!< the starting point of a line segment
01248 //  TAPs::Vector3<T> const * const  ptB,    //!< the ending point of a line segment
01249 //  std::vector< TAPs::Vector3<T> > * listOfIntersectedPoints,  //!< O/P: list of intersected points
01250 //  std::vector< TAPs::Face<T>* > * listOfIntersectedFaces, //!< O/P: list of intersected faces
01251 //  std::vector< TAPs::Vertex<T>* > * listOfClosestVertices //!< O/P: list of closest vertices
01252 //)
01253 //{
01254 //  std::cout << __FILE__ << " " << __LINE__ << " ";
01255 //  std::cout << "CD_PolygonalMesh_vs_LineSegment( PolygonalModel<T>, ... ) -- NOT IMPLEMENTED YET!" << std::endl;
01256 //  bool bResult = false;
01257 //  //---------------------------------------------------------------
01258 //  //---------------------------------------------------------------
01259 //  return bResult;
01260 //}
01261 // END: CD_PolygonalMesh_vs_LineSegment(...) for PolygonalModel
01262 //-----------------------------------------------------------------------------
01263 
01264 //-----------------------------------------------------------------------------
01265 //template <typename T>
01266 //bool CD_PolygonalMesh_vs_LineSegment ( 
01267 //  TAPs::OpenGL::XPolygonalModel<T> * pPolygonalMeshObj,   //!< a PolygonalModel object
01268 //  TAPs::Vector3<T> const * const  ptA,    //!< the starting point of a line segment
01269 //  TAPs::Vector3<T> const * const  ptB,    //!< the ending point of a line segment
01270 //  std::vector< TAPs::Vector3<T> > * listOfIntersectedPoints,  //!< O/P: list of intersected points
01271 //  std::vector< TAPs::Face<T>* > * listOfIntersectedFaces,     //!< O/P: list of intersected faces
01272 //  std::vector< TAPs::XVertex<T>* > * listOfClosestVertices    //!< O/P: list of closest vertices
01273 //)
01274 //{
01275 //  std::cout << __FILE__ << " " << __LINE__ << " ";
01276 //  std::cout << "CD_PolygonalMesh_vs_LineSegment( XPolygonalModel<T>, ... ) -- NOT IMPLEMENTED YET!" << std::endl;
01277 //  bool bResult = false;
01278 //  //---------------------------------------------------------------
01279 //  //---------------------------------------------------------------
01280 //  return bResult;
01281 //}
01282 // END: CD_PolygonalMesh_vs_LineSegment(...) for XPolygonalModel
01283 //-----------------------------------------------------------------------------
01284 
01285 //-----------------------------------------------------------------------------
01286 template <typename T>
01287 bool CD_PolygonalMesh_vs_LineSegment ( 
01288     TAPs::OpenGL::HalfEdgeModel<T> * pPolygonalMeshObj,     
01289     TAPs::Vector3<T> const * const  ptA,    
01290     TAPs::Vector3<T> const * const  ptB,    
01291     std::vector< TAPs::Vector3<T> > * listOfIntersectedPoints,  
01292     std::vector< TAPs::HEFace<T>* > * listOfIntersectedFaces,   
01293     std::vector< TAPs::HEVertex<T>* > * listOfClosestVertices   
01294 )
01295 {
01296     std::cout << __FILE__ << " " << __LINE__ << " ";
01297     std::cout << "CD_PolygonalMesh_vs_LineSegment( HalfEdgeModel<T>, ... ) -- NOT IMPLEMENTED YET!" << std::endl;
01298 
01299     #ifdef  TAPs_DEBUG_COLLISION_DETECTION
01300     pPolygonalMeshObj->GetBVHTree()->ClearFlags();
01301     #endif//TAPs_DEBUG_COLLISION_DETECTION
01302 
01303     //#ifdef    TAPs_DEBUG_MODE
01304     std::cout << "CD_PolygonalMesh_vs_LineSegment( HalfEdgeModel<T>, ... )\n";
01305     //#endif//TAPs_DEBUG_MODE
01306 
01307     std::cout << "BVHTree: " << *(pPolygonalMeshObj->GetBVHTree()) << "\n";
01308 
01309     bool bResult = false;
01310 
01311     // Collision Detection
01312     bResult = pPolygonalMeshObj->GetBVHTree()->TestIntersectionWithLineSegmentTillLeafNodes( ptA, ptB );
01313     //---------------------------------------------------------------
01314     // Collision Response
01315     //if ( bResult ) {
01316     //}
01317     //---------------------------------------------------------------
01318     return bResult;
01319 }
01320 // END: CD_PolygonalMesh_vs_LineSegment(...) for HalfEdgeModel
01321 //-----------------------------------------------------------------------------
01322 
01323 //-----------------------------------------------------------------------------
01324 template <typename T>
01325 bool CD_PolygonalMesh_vs_LineSegment ( 
01326     TAPs::OpenGL::HalfEdgeModel<T> * pPolygonalMeshObj, 
01327     TAPs::Vector3<T> const * const  ptA,    
01328     TAPs::Vector3<T> const * const  ptB,    
01329     std::vector< TAPs::Vector3<T> > * listOfIntersectedPoints,  
01330     std::vector< TAPs::HEFace<T>* > * listOfIntersectedFaces,   
01331     std::vector< TAPs::HEVertex<T>* > * listOfClosestVertices,  
01332     std::vector< T > * listOfRatios,                            
01333     std::vector< T > * listOfIntersectionAngles                 
01334 )
01335 {
01336     ListOfContactPts.clear();
01337     ListOfForces.clear();
01338 
01339     #ifdef  TAPs_DEBUG_COLLISION_DETECTION
01340     pPolygonalMeshObj->GetBVHTree()->ClearFlags();
01341     #endif//TAPs_DEBUG_COLLISION_DETECTION
01342 
01343     bool bResult = false;
01344 
01345     // Collision Detection
01346     bResult = pPolygonalMeshObj->GetBVHTree()->TestIntersectionWithLineSegmentTillLeafNodes( ptA, ptB );
01347     //---------------------------------------------------------------
01348     if ( bResult ) {
01349 
01350         // Include pPolygonalMeshObj's transformation
01351         TAPs::Matrix4x4<T> invTrx( pPolygonalMeshObj->GetTransform().RefToMatrixTransform().GetInverse() );
01352         TAPs::Vector3<T> A = invTrx * *ptA;
01353         TAPs::Vector3<T> B = invTrx * *ptB;
01354 
01355         std::vector< BVHNode<T> * > & nodeList = pPolygonalMeshObj->GetBVHTree()->GetListOfCollidedNodes();
01356         T ratio, intersectionAngle;
01357         Vector3<T> projPt;
01358         HEFace<T> * triangle;
01359         std::vector< HEVertex<T> * const > vertexList;
01360         int noOfVertices;
01361         for ( int i = 0; i < static_cast<int>( nodeList.size() ); ++i ) {
01362             // Check intersection of the line segment with the primitive triangle in the BV node
01363             triangle = nodeList[i]->GetAPrimitiveHalfEdgeFace();
01364             vertexList = triangle->GetPtrsToVerticesAndNumberOfVertices( noOfVertices );
01365             bool result = CGMath<T>::FindIntersectionLineSegmentTriangle( 
01366                                 A, B,       // I/P: a line segment
01367                                 vertexList[0]->GetPosition(),   // I/P: the triangle
01368                                 vertexList[1]->GetPosition(), 
01369                                 vertexList[2]->GetPosition(), 
01370                                 ratio,              // O/P: the ratio
01371                                 intersectionAngle,  // O/P: the intersection angle (in degrees)
01372                                 projPt              // O/P: the projected point
01373                             );
01374             if ( result ) {
01375                 #ifdef  TAPs_ADVANCED_SIMULATION
01376                     // Sort the elements by ratio -- from low to high
01377                     std::vector< T >::iterator itR = listOfRatios->begin();
01378                     std::vector< T >::iterator itA = listOfIntersectionAngles->begin();
01379                     std::vector< TAPs::Vector3<T> >::iterator itIP = listOfIntersectedPoints->begin();
01380                     std::vector< TAPs::HEFace<T>* >::iterator itIF = listOfIntersectedFaces->begin();
01381                     std::vector< TAPs::HEVertex<T>* >::iterator itCV = listOfClosestVertices->begin();
01382                     while ( itR != listOfRatios->end() ) {
01383                         if ( *itR > ratio ) {
01384                             if ( itR != listOfRatios->begin() ) {
01385                                 --itR;
01386                                 --itA;
01387                                 --itIP;
01388                                 --itIF;
01389                                 --itCV;
01390                             }
01391                             break;
01392                         }
01393                         ++itR;
01394                         ++itA;
01395                         ++itIP;
01396                         ++itIF;
01397                         ++itCV;
01398                     }
01399                     listOfIntersectedPoints->insert( itIP, projPt );
01400                     listOfIntersectedFaces->insert( itIF, triangle );
01401                     listOfRatios->insert( itR, ratio );
01402                     listOfIntersectionAngles->insert( itA, intersectionAngle );
01403 
01404                     //listOfIntersectedPoints->push_back( projPt );
01405                     //listOfIntersectedFaces->push_back( triangle );
01406                     //listOfRatios->push_back( ratio );
01407                     
01408                     // Find the closest point
01409                     T distance0 = ( projPt - vertexList[0]->GetPosition() ).Length();
01410                     T distance1 = ( projPt - vertexList[1]->GetPosition() ).Length();
01411                     T distance2 = ( projPt - vertexList[2]->GetPosition() ).Length();
01412                     if ( distance0 < distance1 ) {
01413                         if ( distance0 < distance2 ) {
01414                             listOfClosestVertices->insert( itCV, vertexList[0] );
01415                             //listOfClosestVertices->push_back( vertexList[0] );
01416                             //vertexList[0]->SimFlags.SetSimulationConstraints( TAPs::Enum::AddOn::PUNCTURED );
01417                         }
01418                         else {
01419                             listOfClosestVertices->insert( itCV, vertexList[2] );
01420                             //listOfClosestVertices->push_back( vertexList[2] );
01421                             //vertexList[2]->SimFlags.SetSimulationConstraints( TAPs::Enum::AddOn::PUNCTURED );
01422                         }
01423                     }
01424                     else {
01425                         if ( distance1 < distance2 ) {
01426                             listOfClosestVertices->insert( itCV, vertexList[1] );
01427                             //listOfClosestVertices->push_back( vertexList[1] );
01428                             //vertexList[1]->SimFlags.SetSimulationConstraints( TAPs::Enum::AddOn::PUNCTURED );
01429                         }
01430                         else {
01431                             listOfClosestVertices->insert( itCV, vertexList[2] );
01432                             //listOfClosestVertices->push_back( vertexList[2] );
01433                             //vertexList[2]->SimFlags.SetSimulationConstraints( TAPs::Enum::AddOn::PUNCTURED );
01434                         }
01435                     }
01436 
01437                 #endif//TAPs_ADVANCED_SIMULATION
01438                 //std::cout << __FILE__ << " " << __LINE__ << " -- ";
01439                 //std::cout << "Line Segment intersected Node " << nodeList[i] << "\n";
01440             }
01441         }
01442     }
01443     return bResult;
01444 }
01445 // END: CD_PolygonalMesh_vs_LineSegment(...) for HETriMeshOneModelMultiParts
01446 //-----------------------------------------------------------------------------
01447 //=============================================================================
01448 
01449 
01450 
01451 
01452 #ifdef  TAPs_MULTI_BOUNDING_VOLUME_HPP
01453 //=============================================================================
01454 //-----------------------------------------------------------------------------
01455 //template <typename T>
01456 //bool CDR_PolygonalMesh_vs_MBV ( 
01457 //  TAPs::OpenGL::PolygonalModel<T> * pPolygonalMeshObj,    //!< a PolygonalModel object
01458 //  TAPs::MultiBoundingVolume<T> const * const pMBVObj      //!< a multi bounding volume object
01459 //)
01460 //{
01461 //  std::cout << "CDR_PolygonalMesh_vs_MBV( PolygonalModel<T>, MultiBoundingVolume<T> ) -- NOT IMPLEMENTED YET!" << std::endl;
01462 //  bool bResult = false;
01463 //  //---------------------------------------------------------------
01464 //  //---------------------------------------------------------------
01465 //  return bResult;
01466 //}
01467 // END: CDR_PolygonalMesh_vs_MBV(...) for PolygonalModel
01468 //-----------------------------------------------------------------------------
01469 
01470 //-----------------------------------------------------------------------------
01471 //template <typename T>
01472 //bool CDR_PolygonalMesh_vs_MBV ( 
01473 //  TAPs::OpenGL::XPolygonalModel<T> * pPolygonalMeshObj,   //!< a PolygonalModel object
01474 //  TAPs::MultiBoundingVolume<T> const * const pMBVObj      //!< a multi bounding volume object
01475 //)
01476 //{
01477 //  std::cout << "CDR_PolygonalMesh_vs_MBV( XPolygonalModel<T>, MultiBoundingVolume<T> ) -- NOT IMPLEMENTED YET!" << std::endl;
01478 //  bool bResult = false;
01479 //  //---------------------------------------------------------------
01480 //  //---------------------------------------------------------------
01481 //  return bResult;
01482 //}
01483 // END: CDR_PolygonalMesh_vs_MBV(...) for XPolygonalModel
01484 //-----------------------------------------------------------------------------
01485 
01486 //-----------------------------------------------------------------------------
01487 template <typename T>
01488 bool CDR_PolygonalMesh_vs_MBV ( 
01489     TAPs::OpenGL::HalfEdgeModel<T> * pPolygonalMeshObj,     
01490     TAPs::MultiBoundingVolume<T> const * const pMBVObj      
01491 )
01492 {
01493     #ifdef  TAPs_DEBUG_COLLISION_DETECTION
01494     pPolygonalMeshObj->GetBVHTree()->ClearFlags();
01495     #endif//TAPs_DEBUG_COLLISION_DETECTION
01496 
01497     //#ifdef    TAPs_DEBUG_MODE
01498     std::cout << "CDR_PolygonalMesh_vs_MBV( HalfEdgeModel<T>, MultiBoundingVolume<T> )\n";
01499     //#endif//TAPs_DEBUG_MODE
01500 
01501     std::cout << "BVHTree: " << *(pPolygonalMeshObj->GetBVHTree()) << "\n";
01502 
01503     bool bResult = false;
01504 
01505     // Collision Detection
01506     bResult = pPolygonalMeshObj->GetBVHTree()->TestOverlapWithTillLeafNodes( pMBVObj );
01507 
01508     //---------------------------------------------------------------
01509     // Collision Response
01510     if ( bResult ) {
01511 
01512         // Reset the result for primitive-primitive test, 
01513         // because the previous result is only from bounding volume test.
01514         bResult = false;
01515 
01516         //-------------------------------------------------
01517         T separateDistanceConstraint;
01518         Vector3<T> N, centerA;
01519         T separateDistance;
01520         HEFace<T> * primB;
01521         std::vector< HEVertex<T> * const > vertexList;
01522         int noOfVertices;
01523         //-------------------------------------------------
01524         TransformationSupport<T> trxMBV;    // default constructor is an identity transformation
01525         trxMBV = pMBVObj->GetTransform();
01526         //-------------------------------------------------
01527         std::set< BVHNode<T> * > defPolyMesh_NodeSet;
01528 
01529         // Get the list of collided nodes and bounding volumes
01530         std::vector< BVsAndNodesList<T> > * bvList = &pPolygonalMeshObj->GetBVHTree()->GetListOfCollidedBoundingVolumesAndNodes();
01531         //-------------------------------------------------
01532         // Traverse the list of bounding volumes
01533         std::vector< BVsAndNodesList<T> >::const_iterator pos = bvList->begin();
01534         //-------------------------------------------------
01535         //std::cout << "CDR_PolygonalMesh_vs_MBV(...) for HalfEdgeModel --> \n";
01536         //std::cout << "\tCASE: the polygonal mesh object's transformation is on. -- NOT IMPLEMENTED YET!\n";
01537 
01538         // Mesh's inverse transformation
01539         Matrix4x4<T> trxInvMesh = pPolygonalMeshObj->GetTransform().GetMatrixTransform();
01540         trxInvMesh.Inversed();
01541 
01542         while ( pos != bvList->end() ) {
01543 
01544             int count = 0;
01545 
01546             // Store the transformation of the bounding volume including the mesh's inverse transformation
01547             TransformationSupport<T> trx = (*pos).BV->GetTransform();
01548             (*pos).BV->GetTransform().SetMatrixTransform( trxInvMesh * trxMBV.GetMatrixTransform() * trx.GetMatrixTransform() );
01549 
01550             //-----------------------------------------
01551             // Deform the deformable polygonal mesh away from the rigid polygonal mesh
01552             switch ( (*pos).BV->GetType() ) {
01553 
01554                 case TAPs::Enum::BOUNDING_SPHERE:
01555                     {
01556 
01557                         std::cout << "BV: " << (*pos).BV->GetName() << "\n";
01558 
01559                         // For Test against triangle
01560                         //---------------------------------------------
01561                         // Transform the BV due to its transformation, center, and radius
01562                         T radiusOfBV = (*pos).BV->GetRadius();
01563                         Vector3<T> C( (*pos).BV->GetCenter() );
01564                         Matrix4x4<T> translation( 1, 0, 0, C[0], 
01565                                                   0, 1, 0, C[1],
01566                                                   0, 0, 1, C[2],
01567                                                   0, 0, 0, 1 );
01568                         Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV );
01569                         Matrix4x4<T> scale( S[0], 0,    0,    0, 
01570                                             0,    S[1], 0,    0,
01571                                             0,    0,    S[2], 0,
01572                                             0,    0,    0,    1 );
01573                         // The BV's current transformation includes the mesh's inverse transformation (see the code above)
01574                         Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale;
01575 
01576                         // BV Sphere's center and radius after the whole transformation from 
01577                         // BV's transformation to mesh's inverse transformation.
01578                         // I.e., transforming the BV to mesh's coordinate
01579                         Vector3<T> centerOfBV_inMeshCoord = (mat * Vector4<T>(0,0,0,1)).GetVector3();
01580                         T radiusOfBV_inMeshCoord = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV_inMeshCoord ).Length();
01581 
01582                         // Inverse the mesh's transformation to the BV's pure transformation
01583                         mat = pPolygonalMeshObj->GetTransform().GetMatrixTransform() * mat;
01584 
01585                         // BV Sphere's center and radius after the BV's pure transformation
01586                         Vector3<T> centerOfBV( (mat * Vector4<T>(0,0,0,1)).GetVector3() );
01587                         radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length();
01588                         //---------------------------------------------
01589 
01590                         count = 0;
01591                         for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) {
01592 
01593                             bool testResult = false;
01594 
01595                             // Assume triangle is in Sphere Node
01596                             // Test the triangle in sphere node with BVSphere
01597                             primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace();
01598                             vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices );
01599                             Vector3<T> cdrVec[3];
01600 
01601                             //*
01602                             // Test against each vertex in the triangle
01603                             //-----------------------------------
01604                             for ( int j = 0; j < noOfVertices; ++j ) {
01605                                 if( (*pos).BV->TestPointLocation( vertexList[j]->GetPosition(), &(cdrVec[j]) ) )
01606                                 {
01607                                     vertexList[j]->SetPosition( vertexList[j]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[j])).GetVector3() );
01608 
01609                                     testResult = true;
01610                                 }
01611                             }
01612                             //-----------------------------------
01613                             //*/
01614 
01615                             //*
01616                             // Test against triangle
01617                             //-----------------------------------
01618                             //Vector3<T> contactPt;
01619                             if ( TAPs::CGMath<T>::FindIntersectionSphereTriangle( 
01620                                     centerOfBV_inMeshCoord, radiusOfBV_inMeshCoord, // BVSphere properties
01621                                     vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices
01622                                     cdrVec[0], cdrVec[1], cdrVec[2]     // out vectors
01623                                     //, &contactPt
01624                             ) ) {
01625                                 vertexList[0]->SetPosition( vertexList[0]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[0])).GetVector3()*CDScaleForSphereBVWithTriangle );
01626                                 vertexList[1]->SetPosition( vertexList[1]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[1])).GetVector3()*CDScaleForSphereBVWithTriangle );
01627                                 vertexList[2]->SetPosition( vertexList[2]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[2])).GetVector3()*CDScaleForSphereBVWithTriangle );
01628 
01629                                 testResult = true;
01630                             }
01631                             //-----------------------------------
01632                             //*/
01633 
01634 
01635                             std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n";
01636 
01637                             // List of BVNodes to be updated
01638                             if ( testResult ) {
01639                                 defPolyMesh_NodeSet.insert( (*pos).NodeList[i] );
01640                                 bResult = true;
01641                             }
01642                         }
01643                     }
01644                     break;
01645 
01646                 case TAPs::Enum::BOUNDING_CYLINDER:
01647                     {
01648                         std::cout << "BV: " << (*pos).BV->GetName() << "\n";
01649 
01650                         // For Test against triangle
01651                         //---------------------------------------------
01652                         // Transform the BV due to its transformation, center, and radius
01653                         T radiusOfBV = (*pos).BV->GetRadius();
01654                         Vector3<T> C( (*pos).BV->GetCenter() );
01655                         Matrix4x4<T> translation( 1, 0, 0, C[0], 
01656                                                   0, 1, 0, C[1],
01657                                                   0, 0, 1, C[2],
01658                                                   0, 0, 0, 1 );
01659                         Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV );
01660                         Matrix4x4<T> scale( S[0], 0,    0,    0, 
01661                                             0,    S[1], 0,    0,
01662                                             0,    0,    S[2], 0,
01663                                             0,    0,    0,    1 );
01664                         // The BV's current transformation includes the mesh's inverse transformation (see the code above)
01665                         Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale;
01666 
01667                         // BV Sphere's center and radius after the whole transformation from 
01668                         // BV's transformation to mesh's inverse transformation.
01669                         // I.e., transforming the BV to mesh's coordinate
01670                         T halfHeightOfBV = (*pos).BV->GetHeight() / 2.0;
01671                         Vector3<T> centerOfBV_inMeshCoord = (mat * Vector4<T>(0,0,0,1)).GetVector3();
01672                         T radiusOfBV_inMeshCoord = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV_inMeshCoord ).Length();
01673                         Vector3<T> topPtOfBV_inMeshCoord( (mat * Vector4<T>(0,0,halfHeightOfBV,1)).GetVector3() );
01674                         Vector3<T> bottomPtOfBV_inMeshCoord( (mat * Vector4<T>(0,0,-halfHeightOfBV,1)).GetVector3() );
01675 
01676                         // Inverse the mesh's transformation to the BV's pure transformation
01677                         mat = pPolygonalMeshObj->GetTransform().GetMatrixTransform() * mat;
01678 
01679                         // BV Sphere's center and radius after the BV's pure transformation
01680                         Vector3<T> centerOfBV( (mat * Vector4<T>(0,0,0,1)).GetVector3() );
01681                         radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length();
01682                         Vector3<T> topPtOfBV( (mat * Vector4<T>(0,0,halfHeightOfBV,1)).GetVector3() );
01683                         Vector3<T> bottomPtOfBV( (mat * Vector4<T>(0,0,-halfHeightOfBV,1)).GetVector3() );
01684                         //---------------------------------------------
01685 
01686                         count = 0;
01687                         for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) {
01688 
01689                             bool testResult = false;
01690 
01691                             // Assume triangle is in Sphere Node
01692                             // Test the triangle in sphere node with BVCylinder
01693                             primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace();
01694                             vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices );
01695                             Vector3<T> cdrVec[3];
01696 
01697                             //*
01698                             // Test against each vertex in the triangle
01699                             //-----------------------------------
01700                             for ( int j = 0; j < noOfVertices; ++j ) {
01701                                 if( (*pos).BV->TestPointLocation( vertexList[j]->GetPosition(), &(cdrVec[j]) ) )
01702                                 {
01703                                     vertexList[j]->SetPosition( vertexList[j]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[j])).GetVector3() );
01704 
01705                                     testResult = true;
01706                                 }
01707                             }
01708                             //-----------------------------------
01709                             //*/
01710 
01711                             //*
01712                             // Test against triangle
01713                             //-----------------------------------
01714                             if ( TAPs::CGMath<T>::FindIntersectionCylinderTriangle( 
01715                                     topPtOfBV_inMeshCoord, bottomPtOfBV_inMeshCoord, radiusOfBV_inMeshCoord,    // BVCylinder properties
01716                                     vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices
01717                                     cdrVec[0], cdrVec[1], cdrVec[2]         // out vectors
01718                             ) ) {
01719                                 vertexList[0]->SetPosition( vertexList[0]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[0])).GetVector3()*CDScaleForCylinderBVWithTriangle );
01720                                 vertexList[1]->SetPosition( vertexList[1]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[1])).GetVector3()*CDScaleForCylinderBVWithTriangle );
01721                                 vertexList[2]->SetPosition( vertexList[2]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[2])).GetVector3()*CDScaleForCylinderBVWithTriangle );
01722 
01723                                 testResult = true;
01724                             }
01725                             //-----------------------------------
01726                             //*/
01727 
01728                             std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n";
01729 
01730                             // List of BVNodes to be updated
01731                             if ( testResult ) {
01732                                 defPolyMesh_NodeSet.insert( (*pos).NodeList[i] );
01733                                 bResult = true;
01734                             }
01735                         }
01736                     }
01737                     break;
01738 
01739                 default:
01740                     std::cout << "CDR_PolygonalMesh_vs_MBV of BV Type (" << (*pos).BV->GetType() << ") doesn't support!\n";
01741                     break;
01742             }
01743 
01744             // Restore the transformation of the bounding volume
01745             (*pos).BV->SetTransform( trx );
01746             // Next Bounding Volume
01747             ++pos;
01748         }
01749         //-------------------------------------------------
01750 
01751         //-------------------------------------------------
01752         // Update Normals of Deformable Polygonal Mesh
01753         pPolygonalMeshObj->CalAndSetNormals();
01754         //-------------------------------------------------
01755         // Update Bounding Volume Hierarchy of Deformable Polygonal Mesh
01756         pPolygonalMeshObj->GetBVHTree()->Update( defPolyMesh_NodeSet );
01757     }
01758     //---------------------------------------------------------------
01759     return bResult;
01760 }
01761 // END: CDR_PolygonalMesh_vs_MBV(...) for HalfEdgeModel
01762 //-----------------------------------------------------------------------------
01763 
01764 
01765 //-----------------------------------------------------------------------------
01766 template <typename T>
01767 bool CDRigid_PolygonalMesh_vs_MBV ( 
01768     TAPs::OpenGL::HalfEdgeModel<T> * pPolygonalMeshObj,     
01769     TAPs::MultiBoundingVolume<T> const * const pMBVObj      
01770 )
01771 {
01772     #ifdef  TAPs_DEBUG_COLLISION_DETECTION
01773     pPolygonalMeshObj->GetBVHTree()->ClearFlags();
01774     #endif//TAPs_DEBUG_COLLISION_DETECTION
01775 
01776     //#ifdef    TAPs_DEBUG_MODE
01777     std::cout << "CDR_PolygonalMesh_vs_MBV( HalfEdgeModel<T>, MultiBoundingVolume<T> )\n";
01778     //#endif//TAPs_DEBUG_MODE
01779 
01780     std::cout << "BVHTree: " << *(pPolygonalMeshObj->GetBVHTree()) << "\n";
01781 
01782     bool bResult = false;
01783 
01784     // Collision Detection
01785     bResult = pPolygonalMeshObj->GetBVHTree()->TestOverlapWithTillLeafNodes( pMBVObj );
01786 
01787     //---------------------------------------------------------------
01788     // Collision Response
01789     if ( bResult ) {
01790 
01791         // Reset the result for primitive-primitive test, 
01792         // because the previous result is only from bounding volume test.
01793         bResult = false;
01794 
01795         //-------------------------------------------------
01796         T separateDistanceConstraint;
01797         Vector3<T> N, centerA;
01798         T separateDistance;
01799         HEFace<T> * primB;
01800         std::vector< HEVertex<T> * const > vertexList;
01801         int noOfVertices;
01802         //-------------------------------------------------
01803         TransformationSupport<T> trxMBV;    // default constructor is an identity transformation
01804         trxMBV = pMBVObj->GetTransform();
01805         //-------------------------------------------------
01806         std::set< BVHNode<T> * > defPolyMesh_NodeSet;
01807 
01808         // Get the list of collided nodes and bounding volumes
01809         std::vector< BVsAndNodesList<T> > * bvList = &pPolygonalMeshObj->GetBVHTree()->GetListOfCollidedBoundingVolumesAndNodes();
01810         //-------------------------------------------------
01811         // Traverse the list of bounding volumes
01812         std::vector< BVsAndNodesList<T> >::const_iterator pos = bvList->begin();
01813         //-------------------------------------------------
01814         //std::cout << "CDR_PolygonalMesh_vs_MBV(...) for HalfEdgeModel --> \n";
01815         //std::cout << "\tCASE: the polygonal mesh object's transformation is on. -- NOT IMPLEMENTED YET!\n";
01816 
01817         // Mesh's inverse transformation
01818         Matrix4x4<T> trxInvMesh = pPolygonalMeshObj->GetTransform().GetMatrixTransform();
01819         trxInvMesh.Inversed();
01820 
01821         while ( pos != bvList->end() ) {
01822 
01823             int count = 0;
01824 
01825             // Store the transformation of the bounding volume including the mesh's inverse transformation
01826             TransformationSupport<T> trx = (*pos).BV->GetTransform();
01827             (*pos).BV->GetTransform().SetMatrixTransform( trxInvMesh * trxMBV.GetMatrixTransform() * trx.GetMatrixTransform() );
01828 
01829             //-----------------------------------------
01830             // Deform the deformable polygonal mesh away from the rigid polygonal mesh
01831             switch ( (*pos).BV->GetType() ) {
01832 
01833                 case TAPs::Enum::BOUNDING_SPHERE:
01834                     {
01835 
01836                         std::cout << "BV: " << (*pos).BV->GetName() << "\n";
01837 
01838                         // For Test against triangle
01839                         //---------------------------------------------
01840                         // Transform the BV due to its transformation, center, and radius
01841                         T radiusOfBV = (*pos).BV->GetRadius();
01842                         Vector3<T> C( (*pos).BV->GetCenter() );
01843                         Matrix4x4<T> translation( 1, 0, 0, C[0], 
01844                                                   0, 1, 0, C[1],
01845                                                   0, 0, 1, C[2],
01846                                                   0, 0, 0, 1 );
01847                         Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV );
01848                         Matrix4x4<T> scale( S[0], 0,    0,    0, 
01849                                             0,    S[1], 0,    0,
01850                                             0,    0,    S[2], 0,
01851                                             0,    0,    0,    1 );
01852                         // The BV's current transformation includes the mesh's inverse transformation (see the code above)
01853                         Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale;
01854 
01855                         // BV Sphere's center and radius after the whole transformation from 
01856                         // BV's transformation to mesh's inverse transformation.
01857                         // I.e., transforming the BV to mesh's coordinate
01858                         Vector3<T> centerOfBV_inMeshCoord = (mat * Vector4<T>(0,0,0,1)).GetVector3();
01859                         T radiusOfBV_inMeshCoord = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV_inMeshCoord ).Length();
01860 
01861                         // Inverse the mesh's transformation to the BV's pure transformation
01862                         mat = pPolygonalMeshObj->GetTransform().GetMatrixTransform() * mat;
01863 
01864                         // BV Sphere's center and radius after the BV's pure transformation
01865                         Vector3<T> centerOfBV( (mat * Vector4<T>(0,0,0,1)).GetVector3() );
01866                         radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length();
01867                         //---------------------------------------------
01868 
01869                         count = 0;
01870                         for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) {
01871 
01872                             bool testResult = false;
01873 
01874                             // Assume triangle is in Sphere Node
01875                             // Test the triangle in sphere node with BVSphere
01876                             primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace();
01877                             vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices );
01878                             Vector3<T> cdrVec[3];
01879 
01880                             //*
01881                             // Test against each vertex in the triangle
01882                             //-----------------------------------
01883                             for ( int j = 0; j < noOfVertices; ++j ) {
01884                                 if( (*pos).BV->TestPointLocation( vertexList[j]->GetPosition(), &(cdrVec[j]) ) )
01885                                 {
01886                                     //vertexList[j]->SetPosition( vertexList[j]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[j])).GetVector3() );
01887 
01888                                     testResult = true;
01889                                 }
01890                             }
01891                             //-----------------------------------
01892                             //*/
01893 
01894                             //*
01895                             // Test against triangle
01896                             //-----------------------------------
01897                             //Vector3<T> contactPt;
01898                             if ( TAPs::CGMath<T>::FindIntersectionSphereTriangle( 
01899                                     centerOfBV_inMeshCoord, radiusOfBV_inMeshCoord, // BVSphere properties
01900                                     vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices
01901                                     cdrVec[0], cdrVec[1], cdrVec[2]     // out vectors
01902                                     //, &contactPt
01903                             ) ) {
01904                                 //vertexList[0]->SetPosition( vertexList[0]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[0])).GetVector3()*CDScaleForSphereBVWithTriangle );
01905                                 //vertexList[1]->SetPosition( vertexList[1]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[1])).GetVector3()*CDScaleForSphereBVWithTriangle );
01906                                 //vertexList[2]->SetPosition( vertexList[2]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[2])).GetVector3()*CDScaleForSphereBVWithTriangle );
01907 
01908                                 testResult = true;
01909                             }
01910                             //-----------------------------------
01911                             //*/
01912 
01913 
01914                             std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n";
01915 
01916                             // List of BVNodes to be updated
01917                             if ( testResult ) {
01918                                 defPolyMesh_NodeSet.insert( (*pos).NodeList[i] );
01919                                 bResult = true;
01920                             }
01921                         }
01922                     }
01923                     break;
01924 
01925                 case TAPs::Enum::BOUNDING_CYLINDER:
01926                     {
01927                         std::cout << "BV: " << (*pos).BV->GetName() << "\n";
01928 
01929                         // For Test against triangle
01930                         //---------------------------------------------
01931                         // Transform the BV due to its transformation, center, and radius
01932                         T radiusOfBV = (*pos).BV->GetRadius();
01933                         Vector3<T> C( (*pos).BV->GetCenter() );
01934                         Matrix4x4<T> translation( 1, 0, 0, C[0], 
01935                                                   0, 1, 0, C[1],
01936                                                   0, 0, 1, C[2],
01937                                                   0, 0, 0, 1 );
01938                         Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV );
01939                         Matrix4x4<T> scale( S[0], 0,    0,    0, 
01940                                             0,    S[1], 0,    0,
01941                                             0,    0,    S[2], 0,
01942                                             0,    0,    0,    1 );
01943                         // The BV's current transformation includes the mesh's inverse transformation (see the code above)
01944                         Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale;
01945 
01946                         // BV Sphere's center and radius after the whole transformation from 
01947                         // BV's transformation to mesh's inverse transformation.
01948                         // I.e., transforming the BV to mesh's coordinate
01949                         T halfHeightOfBV = (*pos).BV->GetHeight() / 2.0;
01950                         Vector3<T> centerOfBV_inMeshCoord = (mat * Vector4<T>(0,0,0,1)).GetVector3();
01951                         T radiusOfBV_inMeshCoord = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV_inMeshCoord ).Length();
01952                         Vector3<T> topPtOfBV_inMeshCoord( (mat * Vector4<T>(0,0,halfHeightOfBV,1)).GetVector3() );
01953                         Vector3<T> bottomPtOfBV_inMeshCoord( (mat * Vector4<T>(0,0,-halfHeightOfBV,1)).GetVector3() );
01954 
01955                         // Inverse the mesh's transformation to the BV's pure transformation
01956                         mat = pPolygonalMeshObj->GetTransform().GetMatrixTransform() * mat;
01957 
01958                         // BV Sphere's center and radius after the BV's pure transformation
01959                         Vector3<T> centerOfBV( (mat * Vector4<T>(0,0,0,1)).GetVector3() );
01960                         radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length();
01961                         Vector3<T> topPtOfBV( (mat * Vector4<T>(0,0,halfHeightOfBV,1)).GetVector3() );
01962                         Vector3<T> bottomPtOfBV( (mat * Vector4<T>(0,0,-halfHeightOfBV,1)).GetVector3() );
01963                         //---------------------------------------------
01964 
01965                         count = 0;
01966                         for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) {
01967 
01968                             bool testResult = false;
01969 
01970                             // Assume triangle is in Sphere Node
01971                             // Test the triangle in sphere node with BVCylinder
01972                             primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace();
01973                             vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices );
01974                             Vector3<T> cdrVec[3];
01975 
01976                             //*
01977                             // Test against each vertex in the triangle
01978                             //-----------------------------------
01979                             for ( int j = 0; j < noOfVertices; ++j ) {
01980                                 if( (*pos).BV->TestPointLocation( vertexList[j]->GetPosition(), &(cdrVec[j]) ) )
01981                                 {
01982                                     //vertexList[j]->SetPosition( vertexList[j]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[j])).GetVector3() );
01983 
01984                                     testResult = true;
01985                                 }
01986                             }
01987                             //-----------------------------------
01988                             //*/
01989 
01990                             //*
01991                             // Test against triangle
01992                             //-----------------------------------
01993                             if ( TAPs::CGMath<T>::FindIntersectionCylinderTriangle( 
01994                                     topPtOfBV_inMeshCoord, bottomPtOfBV_inMeshCoord, radiusOfBV_inMeshCoord,    // BVCylinder properties
01995                                     vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices
01996                                     cdrVec[0], cdrVec[1], cdrVec[2]         // out vectors
01997                             ) ) {
01998                                 //vertexList[0]->SetPosition( vertexList[0]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[0])).GetVector3()*CDScaleForCylinderBVWithTriangle );
01999                                 //vertexList[1]->SetPosition( vertexList[1]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[1])).GetVector3()*CDScaleForCylinderBVWithTriangle );
02000                                 //vertexList[2]->SetPosition( vertexList[2]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[2])).GetVector3()*CDScaleForCylinderBVWithTriangle );
02001 
02002                                 testResult = true;
02003                             }
02004                             //-----------------------------------
02005                             //*/
02006 
02007                             std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n";
02008 
02009                             // List of BVNodes to be updated
02010                             if ( testResult ) {
02011                                 defPolyMesh_NodeSet.insert( (*pos).NodeList[i] );
02012                                 bResult = true;
02013                             }
02014                         }
02015                     }
02016                     break;
02017 
02018                 default:
02019                     std::cout << "CDR_PolygonalMesh_vs_MBV of BV Type (" << (*pos).BV->GetType() << ") doesn't support!\n";
02020                     break;
02021             }
02022 
02023             // Restore the transformation of the bounding volume
02024             (*pos).BV->SetTransform( trx );
02025             // Next Bounding Volume
02026             ++pos;
02027         }
02028         //-------------------------------------------------
02029 
02030         //-------------------------------------------------
02031         // Update Normals of Deformable Polygonal Mesh
02032         //pPolygonalMeshObj->CalAndSetNormals();
02033         //-------------------------------------------------
02034         // Update Bounding Volume Hierarchy of Deformable Polygonal Mesh
02035         //pPolygonalMeshObj->GetBVHTree()->Update( defPolyMesh_NodeSet );
02036     }
02037     //---------------------------------------------------------------
02038     return bResult;
02039 }
02040 // END: CDRigid_PolygonalMesh_vs_MBV(...) for HalfEdgeModel
02041 //-----------------------------------------------------------------------------
02042 
02043 
02044 //-----------------------------------------------------------------------------
02045 template <typename T>
02046 bool CDR_PolygonalMesh_vs_MBV ( 
02047     TAPs::OpenGL::HETriMeshOneModelMultiParts<T> * pPolygonalMeshObj,   
02048     TAPs::MultiBoundingVolume<T> const * const pMBVObj      
02049     , TAPs::Vector3<T> * totalForce     
02050     , T gain                            
02051 )
02052 {
02053     ListOfContactPts.clear();
02054     ListOfForces.clear();
02055 
02056     #ifdef  TAPs_DEBUG_COLLISION_DETECTION
02057     pPolygonalMeshObj->GetBVHTree()->ClearFlags();
02058     #endif//TAPs_DEBUG_COLLISION_DETECTION
02059 
02060     //#ifdef    TAPs_DEBUG_MODE
02061     //std::cout << "CDR_PolygonalMesh_vs_MBV( HalfEdgeModel<T>, MultiBoundingVolume<T> )\n";
02062     //#endif//TAPs_DEBUG_MODE
02063 
02064     //std::cout << "BVHTree: " << *(pPolygonalMeshObj->GetBVHTree()) << "\n";
02065 
02066     bool bResult = false;
02067 
02068     // Collision Detection
02069     bResult = pPolygonalMeshObj->GetBVHTree()->TestOverlapWithTillLeafNodes( pMBVObj );
02070 
02071     //---------------------------------------------------------------
02072     // Collision Response
02073     if ( bResult ) {
02074 
02075         // Reset the result for primitive-primitive test, 
02076         // because the previous result is only from bounding volume test.
02077         bResult = false;
02078 
02079         //-------------------------------------------------
02080         //T separateDistanceConstraint;
02081         Vector3<T> N, centerA;
02082         //T separateDistance;
02083         HEFace<T> * primB;
02084         std::vector< HEVertex<T> * const > vertexList;
02085         int noOfVertices;
02086         //-------------------------------------------------
02087         TransformationSupport<T> trxMBV( pMBVObj->GetTransform() );
02088         //-------------------------------------------------
02089         std::set< BVHNode<T> * > defPolyMesh_NodeSet;
02090 
02091         // Get the list of collided nodes and bounding volumes
02092         std::vector< BVsAndNodesList<T> > * bvList = &pPolygonalMeshObj->GetBVHTree()->GetListOfCollidedBoundingVolumesAndNodes();
02093         //-------------------------------------------------
02094         // Traverse the list of bounding volumes
02095         std::vector< BVsAndNodesList<T> >::const_iterator pos = bvList->begin();
02096         //-------------------------------------------------
02097         //std::cout << "CDR_PolygonalMesh_vs_MBV(...) for HETriMeshOneModelMultiParts --> \n";
02098         //std::cout << "\tCASE: the polygonal mesh object's transformation is on. -- NOT IMPLEMENTED YET!\n";
02099 
02100         // Mesh's inverse transformation
02101         Matrix4x4<T> trxInvMesh = pPolygonalMeshObj->GetTransform().GetMatrixTransform();
02102         trxInvMesh.Inversed();
02103         Vector3<T> vOrigin( (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(0,0,0,1)).GetVector3() );
02104 
02105         while ( pos != bvList->end() ) {
02106 
02107             //int count = 0;
02108 
02109             // Store the transformation of the bounding volume including the mesh's inverse transformation
02110             TransformationSupport<T> trx = (*pos).BV->GetTransform();
02111             (*pos).BV->GetTransform().SetMatrixTransform( trxInvMesh * trxMBV.GetMatrixTransform() * trx.GetMatrixTransform() );
02112 
02113             //-----------------------------------------
02114             // Deform the deformable polygonal mesh away from the rigid polygonal mesh
02115             switch ( (*pos).BV->GetType() ) {
02116 
02117                 case TAPs::Enum::BOUNDING_SPHERE:
02118                     {
02119 
02120                         //std::cout << "BV: " << (*pos).BV->GetName() << "\n";
02121 
02122                         // For Test against triangle
02123                         //---------------------------------------------
02124                         // Transform the BV due to its transformation, center, and radius
02125                         T radiusOfBV = (*pos).BV->GetRadius();
02126                         Vector3<T> C( (*pos).BV->GetCenter() );
02127                         Matrix4x4<T> translation( 1, 0, 0, C[0], 
02128                                                   0, 1, 0, C[1],
02129                                                   0, 0, 1, C[2],
02130                                                   0, 0, 0, 1 );
02131                         Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV );
02132                         Matrix4x4<T> scale( S[0], 0,    0,    0, 
02133                                             0,    S[1], 0,    0,
02134                                             0,    0,    S[2], 0,
02135                                             0,    0,    0,    1 );
02136                         // The BV's current transformation includes the mesh's inverse transformation (see the code above)
02137                         Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale;
02138 
02139                         // BV Sphere's center and radius after the whole transformation from 
02140                         // BV's transformation to mesh's inverse transformation.
02141                         // I.e., transforming the BV to mesh's coordinate
02142                         Vector3<T> centerOfBV_inMeshCoord = (mat * Vector4<T>(0,0,0,1)).GetVector3();
02143                         T radiusOfBV_inMeshCoord = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV_inMeshCoord ).Length();
02144 
02145                         // Inverse the mesh's transformation to the BV's pure transformation
02146                         mat = pPolygonalMeshObj->GetTransform().GetMatrixTransform() * mat;
02147 
02148                         // BV Sphere's center and radius after the BV's pure transformation
02149                         Vector3<T> centerOfBV( (mat * Vector4<T>(0,0,0,1)).GetVector3() );
02150                         radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length();
02151                         //---------------------------------------------
02152 
02153                         //count = 0;
02154                         for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) {
02155 
02156                             bool testResult = false;
02157 
02158                             // Assume triangle is in Sphere Node
02159                             // Test the triangle in sphere node with BVSphere
02160                             primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace();
02161                             vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices );
02162                             Vector3<T> cdrVec[3];
02163 
02164                             //*
02165                             // Test against each vertex in the triangle
02166                             //-----------------------------------
02167                             for ( int j = 0; j < noOfVertices; ++j ) {
02168                                 if( (*pos).BV->TestPointLocation( vertexList[j]->GetPosition(), &(cdrVec[j]) ) )
02169                                 {
02170                                     vertexList[j]->SetPosition( vertexList[j]->GetPosition() + cdrVec[j] );
02171                                     Vector3<T> force( (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(cdrVec[j])).GetVector3() - vOrigin );
02172 
02173                                     //ListOfContactPts.push_back( Vector3<GLfloat>( (*pos).BV->GetCenter()[0], (*pos).BV->GetCenter()[1], (*pos).BV->GetCenter()[2] ) );
02174                                     ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) );
02175                                     ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) );
02176 
02177                                     testResult = true;
02178                                 }
02179                             }
02180                             //-----------------------------------
02181                             //*/
02182 
02183                             //*
02184                             // Test against triangle
02185                             //-----------------------------------
02186                             //Vector3<T> contactPt;
02187                             if ( TAPs::CGMath<T>::FindIntersectionSphereTriangle( 
02188                                     centerOfBV_inMeshCoord, radiusOfBV_inMeshCoord, // BVSphere properties
02189                                     vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices
02190                                     cdrVec[0], cdrVec[1], cdrVec[2]     // out vectors
02191                                     //, &contactPt
02192                             ) ) {
02193                                 Vector3<T> force_1( cdrVec[0] * CDScaleForSphereBVWithTriangle );
02194                                 Vector3<T> force_2( cdrVec[1] * CDScaleForSphereBVWithTriangle );
02195                                 Vector3<T> force_3( cdrVec[2] * CDScaleForSphereBVWithTriangle );
02196 
02197                                 vertexList[0]->SetPosition( vertexList[0]->GetPosition() + force_1 );
02198                                 vertexList[1]->SetPosition( vertexList[1]->GetPosition() + force_2 );
02199                                 vertexList[2]->SetPosition( vertexList[2]->GetPosition() + force_3 );
02200 
02201                                 force_1 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_1)).GetVector3() - vOrigin;
02202                                 force_2 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_2)).GetVector3() - vOrigin;
02203                                 force_3 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_3)).GetVector3() - vOrigin;
02204 
02205                                 //ListOfContactPts.push_back( Vector3<GLfloat>( contactPt[0], contactPt[1], contactPt[2] ) );
02206                                 ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) );
02207                                 Vector3<T> force( ( force_1 + force_2 + force_3 )/3 );
02208                                 ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) );
02209 
02210                                 testResult = true;
02211                             }
02212                             //-----------------------------------
02213                             //*/
02214 
02215 
02216                             //std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n";
02217 
02218                             // List of BVNodes to be updated
02219                             if ( testResult ) {
02220                                 defPolyMesh_NodeSet.insert( (*pos).NodeList[i] );
02221                                 bResult = true;
02222                             }
02223                         }
02224                     }
02225                     break;
02226 
02227                 case TAPs::Enum::BOUNDING_CYLINDER:
02228                     {
02229                         //std::cout << "BV: " << (*pos).BV->GetName() << "\n";
02230 
02231                         // For Test against triangle
02232                         //---------------------------------------------
02233                         // Transform the BV due to its transformation, center, and radius
02234                         T radiusOfBV = (*pos).BV->GetRadius();
02235                         Vector3<T> C( (*pos).BV->GetCenter() );
02236                         Matrix4x4<T> translation( 1, 0, 0, C[0], 
02237                                                   0, 1, 0, C[1],
02238                                                   0, 0, 1, C[2],
02239                                                   0, 0, 0, 1 );
02240                         Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV );
02241                         Matrix4x4<T> scale( S[0], 0,    0,    0, 
02242                                             0,    S[1], 0,    0,
02243                                             0,    0,    S[2], 0,
02244                                             0,    0,    0,    1 );
02245                         // The BV's current transformation includes the mesh's inverse transformation (see the code above)
02246                         Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale;
02247 
02248                         // BV Sphere's center and radius after the whole transformation from 
02249                         // BV's transformation to mesh's inverse transformation.
02250                         // I.e., transforming the BV to mesh's coordinate
02251                         T halfHeightOfBV = (*pos).BV->GetHeight() / 2.0;
02252                         Vector3<T> centerOfBV_inMeshCoord = (mat * Vector4<T>(0,0,0,1)).GetVector3();
02253                         T radiusOfBV_inMeshCoord = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV_inMeshCoord ).Length();
02254                         Vector3<T> topPtOfBV_inMeshCoord( (mat * Vector4<T>(0,0,halfHeightOfBV,1)).GetVector3() );
02255                         Vector3<T> bottomPtOfBV_inMeshCoord( (mat * Vector4<T>(0,0,-halfHeightOfBV,1)).GetVector3() );
02256 
02257                         // Inverse the mesh's transformation to the BV's pure transformation
02258                         mat = pPolygonalMeshObj->GetTransform().GetMatrixTransform() * mat;
02259 
02260                         // BV Sphere's center and radius after the BV's pure transformation
02261                         Vector3<T> centerOfBV( (mat * Vector4<T>(0,0,0,1)).GetVector3() );
02262                         radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length();
02263                         Vector3<T> topPtOfBV( (mat * Vector4<T>(0,0,halfHeightOfBV,1)).GetVector3() );
02264                         Vector3<T> bottomPtOfBV( (mat * Vector4<T>(0,0,-halfHeightOfBV,1)).GetVector3() );
02265                         //---------------------------------------------
02266 
02267                         //count = 0;
02268                         for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) {
02269 
02270                             bool testResult = false;
02271 
02272                             // Assume triangle is in Sphere Node
02273                             // Test the triangle in sphere node with BVCylinder
02274                             primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace();
02275                             vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices );
02276                             Vector3<T> cdrVec[3];
02277 
02278                             //*
02279                             // Test against each vertex in the triangle
02280                             //-----------------------------------
02281                             for ( int j = 0; j < noOfVertices; ++j ) {
02282                                 if( (*pos).BV->TestPointLocation( vertexList[j]->GetPosition(), &(cdrVec[j]) ) )
02283                                 {
02284                                     vertexList[j]->SetPosition( vertexList[j]->GetPosition() + cdrVec[j] );
02285                                     Vector3<T> force( (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(cdrVec[j])).GetVector3() - vOrigin );
02286 
02287                                     //ListOfContactPts.push_back( Vector3<GLfloat>( (*pos).BV->GetCenter()[0], (*pos).BV->GetCenter()[1], (*pos).BV->GetCenter()[2] ) );
02288                                     ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) );
02289                                     ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) );
02290 
02291                                     testResult = true;
02292                                 }
02293                             }
02294                             //-----------------------------------
02295                             //*/
02296 
02297                             //*
02298                             // Test against triangle
02299                             //-----------------------------------
02300                             Vector3<T> contactPt;
02301                             if ( TAPs::CGMath<T>::FindIntersectionCylinderTriangle( 
02302                                     topPtOfBV_inMeshCoord, bottomPtOfBV_inMeshCoord, radiusOfBV_inMeshCoord,    // BVCylinder properties
02303                                     vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices
02304                                     cdrVec[0], cdrVec[1], cdrVec[2]         // out vectors
02305                                     , &contactPt
02306                             ) ) {
02307                                 Vector3<T> force_1( cdrVec[0] * CDScaleForSphereBVWithTriangle );
02308                                 Vector3<T> force_2( cdrVec[1] * CDScaleForSphereBVWithTriangle );
02309                                 Vector3<T> force_3( cdrVec[2] * CDScaleForSphereBVWithTriangle );
02310 
02311                                 vertexList[0]->SetPosition( vertexList[0]->GetPosition() + force_1 );
02312                                 vertexList[1]->SetPosition( vertexList[1]->GetPosition() + force_2 );
02313                                 vertexList[2]->SetPosition( vertexList[2]->GetPosition() + force_3 );
02314 
02315                                 force_1 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_1)).GetVector3() - vOrigin;
02316                                 force_2 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_2)).GetVector3() - vOrigin;
02317                                 force_3 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_3)).GetVector3() - vOrigin;
02318 
02319                                 contactPt = ( (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(contactPt)).GetVector3() );
02320 
02321                                 ListOfContactPts.push_back( Vector3<GLfloat>( contactPt[0], contactPt[1], contactPt[2] ) );
02322                                 Vector3<T> force( ( force_1 + force_2 + force_3 )/3 );
02323                                 ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) );
02324 
02325                                 testResult = true;
02326                             }
02327                             //-----------------------------------
02328                             //*/
02329 
02330                             //std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n";
02331 
02332                             // List of BVNodes to be updated
02333                             if ( testResult ) {
02334                                 defPolyMesh_NodeSet.insert( (*pos).NodeList[i] );
02335                                 bResult = true;
02336                             }
02337                         }
02338                     }
02339                     break;
02340 
02341                 default:
02342                     std::cout << "CDR_PolygonalMesh_vs_MBV of BV Type (" << (*pos).BV->GetType() << ") doesn't support!\n";
02343                     break;
02344             }
02345 
02346             // Restore the transformation of the bounding volume
02347             //(*pos).BV->GetTransform().SetMatrixTransform( trx.GetMatrixTransform() );
02348             (*pos).BV->SetTransform( trx );
02349             // Next Bounding Volume
02350             ++pos;
02351         }
02352         //-------------------------------------------------
02353 
02354         //-------------------------------------------------
02355         // Update Normals of Deformable Polygonal Mesh
02356         //pPolygonalMeshObj->CalAndSetNormals();        // commented out to rely on AdvanceSimulation to update the normals
02357         //-------------------------------------------------
02358         // Update Bounding Volume Hierarchy of Deformable Polygonal Mesh
02359         pPolygonalMeshObj->GetBVHTree()->Update( defPolyMesh_NodeSet );
02360         // FOR HETriMeshOneModelMultiParts
02361         //-------------------------------------------------
02362         // Update for the model's internal simulation
02363         for ( int i = 0; i < static_cast<int>( pPolygonalMeshObj->GetListOfParts().size() ); ++i ) {
02364             pPolygonalMeshObj->GetPtrToPartNo(i)->UpdateStateToArray();
02365         }
02366     }
02367     //---------------------------------------------------------------
02368     if ( totalForce ) {
02369         totalForce->SetXYZ( 0, 0, 0 );
02370         Vector3<float> force( 0, 0, 0 );
02371         for ( int i = 0; i < static_cast<int>( ListOfForces.size() ); ++i ) {
02372             force += ListOfForces[i];
02373         }
02374         force *= gain;
02375         (*totalForce).SetXYZ( force[0], force[1], force[2] );
02376     }
02377 
02378     return bResult;
02379 }
02380 // END: CDR_PolygonalMesh_vs_MBV(...) for HETriMeshOneModelMultiParts
02381 //-----------------------------------------------------------------------------
02382 
02383 
02384 
02385 
02386 
02387 //-----------------------------------------------------------------------------
02388 template <typename T>
02389 bool CDRigid_PolygonalMesh_vs_MBV ( 
02390     TAPs::OpenGL::HETriMeshOneModelMultiParts<T> * pPolygonalMeshObj,   
02391     TAPs::MultiBoundingVolume<T> const * const pMBVObj      
02392     , TAPs::Vector3<T> * totalForce     
02393     , T gain                            
02394 )
02395 {
02396     ListOfContactPts.clear();
02397     ListOfForces.clear();
02398 
02399     #ifdef  TAPs_DEBUG_COLLISION_DETECTION
02400     pPolygonalMeshObj->GetBVHTree()->ClearFlags();
02401     #endif//TAPs_DEBUG_COLLISION_DETECTION
02402 
02403     //#ifdef    TAPs_DEBUG_MODE
02404     //std::cout << "CDR_PolygonalMesh_vs_MBV( HalfEdgeModel<T>, MultiBoundingVolume<T> )\n";
02405     //#endif//TAPs_DEBUG_MODE
02406 
02407     //std::cout << "BVHTree: " << *(pPolygonalMeshObj->GetBVHTree()) << "\n";
02408 
02409     bool bResult = false;
02410 
02411     // Collision Detection
02412     bResult = pPolygonalMeshObj->GetBVHTree()->TestOverlapWithTillLeafNodes( pMBVObj );
02413 
02414     //---------------------------------------------------------------
02415     // Collision Response
02416     if ( bResult ) {
02417 
02418         // Reset the result for primitive-primitive test, 
02419         // because the previous result is only from bounding volume test.
02420         bResult = false;
02421 
02422         //-------------------------------------------------
02423         //T separateDistanceConstraint;
02424         Vector3<T> N, centerA;
02425         //T separateDistance;
02426         HEFace<T> * primB;
02427         std::vector< HEVertex<T> * const > vertexList;
02428         int noOfVertices;
02429         //-------------------------------------------------
02430         TransformationSupport<T> trxMBV( pMBVObj->GetTransform() );
02431         //-------------------------------------------------
02432         std::set< BVHNode<T> * > defPolyMesh_NodeSet;
02433 
02434         // Get the list of collided nodes and bounding volumes
02435         std::vector< BVsAndNodesList<T> > * bvList = &pPolygonalMeshObj->GetBVHTree()->GetListOfCollidedBoundingVolumesAndNodes();
02436         //-------------------------------------------------
02437         // Traverse the list of bounding volumes
02438         std::vector< BVsAndNodesList<T> >::const_iterator pos = bvList->begin();
02439         //-------------------------------------------------
02440         // Mesh's inverse transformation
02441         Matrix4x4<T> trxInvMesh = pPolygonalMeshObj->GetTransform().GetMatrixTransform();
02442         trxInvMesh.Inversed();
02443         Vector3<T> vOrigin( (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(0,0,0,1)).GetVector3() );
02444 
02445         while ( pos != bvList->end() ) {
02446 
02447             //int count = 0;
02448 
02449             // Store the transformation of the bounding volume including the mesh's inverse transformation
02450             TransformationSupport<T> trx = (*pos).BV->GetTransform();
02451             (*pos).BV->GetTransform().SetMatrixTransform( trxInvMesh * trxMBV.GetMatrixTransform() * trx.GetMatrixTransform() );
02452 
02453             //-----------------------------------------
02454             // Deform the deformable polygonal mesh away from the rigid polygonal mesh
02455             switch ( (*pos).BV->GetType() ) {
02456 
02457                 case TAPs::Enum::BOUNDING_SPHERE:
02458                     {
02459 
02460                         //std::cout << "BV: " << (*pos).BV->GetName() << "\n";
02461 
02462                         // For Test against triangle
02463                         //---------------------------------------------
02464                         // Transform the BV due to its transformation, center, and radius
02465                         T radiusOfBV = (*pos).BV->GetRadius();
02466                         Vector3<T> C( (*pos).BV->GetCenter() );
02467                         Matrix4x4<T> translation( 1, 0, 0, C[0], 
02468                                                   0, 1, 0, C[1],
02469                                                   0, 0, 1, C[2],
02470                                                   0, 0, 0, 1 );
02471                         Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV );
02472                         Matrix4x4<T> scale( S[0], 0,    0,    0, 
02473                                             0,    S[1], 0,    0,
02474                                             0,    0,    S[2], 0,
02475                                             0,    0,    0,    1 );
02476                         // The BV's current transformation includes the mesh's inverse transformation (see the code above)
02477                         Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale;
02478 
02479                         // BV Sphere's center and radius after the whole transformation from 
02480                         // BV's transformation to mesh's inverse transformation.
02481                         // I.e., transforming the BV to mesh's coordinate
02482                         Vector3<T> centerOfBV_inMeshCoord = (mat * Vector4<T>(0,0,0,1)).GetVector3();
02483                         T radiusOfBV_inMeshCoord = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV_inMeshCoord ).Length();
02484 
02485                         // Inverse the mesh's transformation to the BV's pure transformation
02486                         mat = pPolygonalMeshObj->GetTransform().GetMatrixTransform() * mat;
02487 
02488                         // BV Sphere's center and radius after the BV's pure transformation
02489                         Vector3<T> centerOfBV( (mat * Vector4<T>(0,0,0,1)).GetVector3() );
02490                         radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length();
02491                         //---------------------------------------------
02492 
02493                         //count = 0;
02494                         for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) {
02495 
02496                             bool testResult = false;
02497 
02498                             // Assume triangle is in Sphere Node
02499                             // Test the triangle in sphere node with BVSphere
02500                             primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace();
02501                             vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices );
02502                             Vector3<T> cdrVec[3];
02503 
02504                             //*
02505                             // Test against each vertex in the triangle
02506                             //-----------------------------------
02507                             for ( int j = 0; j < noOfVertices; ++j ) {
02508                                 if( (*pos).BV->TestPointLocation( vertexList[j]->GetPosition(), &(cdrVec[j]) ) )
02509                                 {
02510                                     //vertexList[j]->SetPosition( vertexList[j]->GetPosition() + cdrVec[j] );
02511                                     Vector3<T> force( (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(cdrVec[j])).GetVector3() - vOrigin );
02512 
02513                                     //ListOfContactPts.push_back( Vector3<GLfloat>( (*pos).BV->GetCenter()[0], (*pos).BV->GetCenter()[1], (*pos).BV->GetCenter()[2] ) );
02514                                     ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) );
02515                                     ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) );
02516 
02517                                     testResult = true;
02518                                 }
02519                             }
02520                             //-----------------------------------
02521                             //*/
02522 
02523                             //*
02524                             // Test against triangle
02525                             //-----------------------------------
02526                             //Vector3<T> contactPt;
02527                             if ( TAPs::CGMath<T>::FindIntersectionSphereTriangle( 
02528                                     centerOfBV_inMeshCoord, radiusOfBV_inMeshCoord, // BVSphere properties
02529                                     vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices
02530                                     cdrVec[0], cdrVec[1], cdrVec[2]     // out vectors
02531                                     //, &contactPt
02532                             ) ) {
02533                                 Vector3<T> force_1( cdrVec[0] * CDScaleForSphereBVWithTriangle );
02534                                 Vector3<T> force_2( cdrVec[1] * CDScaleForSphereBVWithTriangle );
02535                                 Vector3<T> force_3( cdrVec[2] * CDScaleForSphereBVWithTriangle );
02536 
02537                                 //vertexList[0]->SetPosition( vertexList[0]->GetPosition() + force_1 );
02538                                 //vertexList[1]->SetPosition( vertexList[1]->GetPosition() + force_2 );
02539                                 //vertexList[2]->SetPosition( vertexList[2]->GetPosition() + force_3 );
02540 
02541                                 force_1 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_1)).GetVector3() - vOrigin;
02542                                 force_2 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_2)).GetVector3() - vOrigin;
02543                                 force_3 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_3)).GetVector3() - vOrigin;
02544 
02545                                 //ListOfContactPts.push_back( Vector3<GLfloat>( contactPt[0], contactPt[1], contactPt[2] ) );
02546                                 ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) );
02547                                 Vector3<T> force( ( force_1 + force_2 + force_3 )/3 );
02548                                 ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) );
02549 
02550                                 testResult = true;
02551                             }
02552                             //-----------------------------------
02553                             //*/
02554 
02555 
02556                             //std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n";
02557 
02558                             // List of BVNodes to be updated
02559                             if ( testResult ) {
02560                                 defPolyMesh_NodeSet.insert( (*pos).NodeList[i] );
02561                                 bResult = true;
02562                             }
02563                         }
02564                     }
02565                     break;
02566 
02567                 case TAPs::Enum::BOUNDING_CYLINDER:
02568                     {
02569                         //std::cout << "BV: " << (*pos).BV->GetName() << "\n";
02570 
02571                         // For Test against triangle
02572                         //---------------------------------------------
02573                         // Transform the BV due to its transformation, center, and radius
02574                         T radiusOfBV = (*pos).BV->GetRadius();
02575                         Vector3<T> C( (*pos).BV->GetCenter() );
02576                         Matrix4x4<T> translation( 1, 0, 0, C[0], 
02577                                                   0, 1, 0, C[1],
02578                                                   0, 0, 1, C[2],
02579                                                   0, 0, 0, 1 );
02580                         Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV );
02581                         Matrix4x4<T> scale( S[0], 0,    0,    0, 
02582                                             0,    S[1], 0,    0,
02583                                             0,    0,    S[2], 0,
02584                                             0,    0,    0,    1 );
02585                         // The BV's current transformation includes the mesh's inverse transformation (see the code above)
02586                         Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale;
02587 
02588                         // BV Sphere's center and radius after the whole transformation from 
02589                         // BV's transformation to mesh's inverse transformation.
02590                         // I.e., transforming the BV to mesh's coordinate
02591                         T halfHeightOfBV = (*pos).BV->GetHeight() / 2.0;
02592                         Vector3<T> centerOfBV_inMeshCoord = (mat * Vector4<T>(0,0,0,1)).GetVector3();
02593                         T radiusOfBV_inMeshCoord = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV_inMeshCoord ).Length();
02594                         Vector3<T> topPtOfBV_inMeshCoord( (mat * Vector4<T>(0,0,halfHeightOfBV,1)).GetVector3() );
02595                         Vector3<T> bottomPtOfBV_inMeshCoord( (mat * Vector4<T>(0,0,-halfHeightOfBV,1)).GetVector3() );
02596 
02597                         // Inverse the mesh's transformation to the BV's pure transformation
02598                         mat = pPolygonalMeshObj->GetTransform().GetMatrixTransform() * mat;
02599 
02600                         // BV Sphere's center and radius after the BV's pure transformation
02601                         Vector3<T> centerOfBV( (mat * Vector4<T>(0,0,0,1)).GetVector3() );
02602                         radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length();
02603                         Vector3<T> topPtOfBV( (mat * Vector4<T>(0,0,halfHeightOfBV,1)).GetVector3() );
02604                         Vector3<T> bottomPtOfBV( (mat * Vector4<T>(0,0,-halfHeightOfBV,1)).GetVector3() );
02605                         //---------------------------------------------
02606 
02607                         //count = 0;
02608                         for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) {
02609 
02610                             bool testResult = false;
02611 
02612                             // Assume triangle is in Sphere Node
02613                             // Test the triangle in sphere node with BVCylinder
02614                             primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace();
02615                             vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices );
02616                             Vector3<T> cdrVec[3];
02617 
02618                             //*
02619                             // Test against each vertex in the triangle
02620                             //-----------------------------------
02621                             for ( int j = 0; j < noOfVertices; ++j ) {
02622                                 if( (*pos).BV->TestPointLocation( vertexList[j]->GetPosition(), &(cdrVec[j]) ) )
02623                                 {
02624                                     //vertexList[j]->SetPosition( vertexList[j]->GetPosition() + cdrVec[j] );
02625                                     Vector3<T> force( (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(cdrVec[j])).GetVector3() - vOrigin );
02626 
02627                                     //ListOfContactPts.push_back( Vector3<GLfloat>( (*pos).BV->GetCenter()[0], (*pos).BV->GetCenter()[1], (*pos).BV->GetCenter()[2] ) );
02628                                     ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) );
02629                                     ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) );
02630 
02631                                     testResult = true;
02632                                 }
02633                             }
02634                             //-----------------------------------
02635                             //*/
02636 
02637                             //*
02638                             // Test against triangle
02639                             //-----------------------------------
02640                             Vector3<T> contactPt;
02641                             if ( TAPs::CGMath<T>::FindIntersectionCylinderTriangle( 
02642                                     topPtOfBV_inMeshCoord, bottomPtOfBV_inMeshCoord, radiusOfBV_inMeshCoord,    // BVCylinder properties
02643                                     vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices
02644                                     cdrVec[0], cdrVec[1], cdrVec[2]         // out vectors
02645                                     , &contactPt
02646                             ) ) {
02647                                 Vector3<T> force_1( cdrVec[0] * CDScaleForSphereBVWithTriangle );
02648                                 Vector3<T> force_2( cdrVec[1] * CDScaleForSphereBVWithTriangle );
02649                                 Vector3<T> force_3( cdrVec[2] * CDScaleForSphereBVWithTriangle );
02650 
02651                                 //vertexList[0]->SetPosition( vertexList[0]->GetPosition() + force_1 );
02652                                 //vertexList[1]->SetPosition( vertexList[1]->GetPosition() + force_2 );
02653                                 //vertexList[2]->SetPosition( vertexList[2]->GetPosition() + force_3 );
02654 
02655                                 force_1 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_1)).GetVector3() - vOrigin;
02656                                 force_2 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_2)).GetVector3() - vOrigin;
02657                                 force_3 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_3)).GetVector3() - vOrigin;
02658 
02659                                 contactPt = ( (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(contactPt)).GetVector3() );
02660 
02661                                 ListOfContactPts.push_back( Vector3<GLfloat>( contactPt[0], contactPt[1], contactPt[2] ) );
02662                                 Vector3<T> force( ( force_1 + force_2 + force_3 )/3 );
02663                                 ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) );
02664 
02665                                 testResult = true;
02666                             }
02667                             //-----------------------------------
02668                             //*/
02669 
02670                             //std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n";
02671 
02672                             // List of BVNodes to be updated
02673                             if ( testResult ) {
02674                                 defPolyMesh_NodeSet.insert( (*pos).NodeList[i] );
02675                                 bResult = true;
02676                             }
02677                         }
02678                     }
02679                     break;
02680 
02681                 default:
02682                     std::cout << "CDRigid_PolygonalMesh_vs_MBV of BV Type (" << (*pos).BV->GetType() << ") doesn't support!\n";
02683                     break;
02684             }
02685 
02686             // Restore the transformation of the bounding volume
02687             //(*pos).BV->GetTransform().SetMatrixTransform( trx.GetMatrixTransform() );
02688             (*pos).BV->SetTransform( trx );
02689             // Next Bounding Volume
02690             ++pos;
02691         }
02692         //-------------------------------------------------
02693 
02694         //-------------------------------------------------
02695         // Update Normals of Deformable Polygonal Mesh
02696         //pPolygonalMeshObj->CalAndSetNormals();        // commented out to rely on AdvanceSimulation to update the normals
02697         //-------------------------------------------------
02698         // Update Bounding Volume Hierarchy of Deformable Polygonal Mesh
02699         //pPolygonalMeshObj->GetBVHTree()->Update( defPolyMesh_NodeSet );
02700         // FOR HETriMeshOneModelMultiParts
02701         //-------------------------------------------------
02702         // Update for the model's internal simulation
02703         //for ( int i = 0; i < static_cast<int>( pPolygonalMeshObj->GetListOfParts().size() ); ++i ) {
02704         //  pPolygonalMeshObj->GetPtrToPartNo(i)->UpdateStateToArray();
02705         //}
02706     }
02707     //---------------------------------------------------------------
02708     if ( totalForce ) {
02709         totalForce->SetXYZ( 0, 0, 0 );
02710         Vector3<float> force( 0, 0, 0 );
02711         for ( int i = 0; i < static_cast<int>( ListOfForces.size() ); ++i ) {
02712             force += ListOfForces[i];
02713         }
02714         force *= gain;
02715         (*totalForce).SetXYZ( force[0], force[1], force[2] );
02716     }
02717 
02718     return bResult;
02719 }
02720 
02721 
02722 
02723 
02724 //-----------------------------------------------------------------------------
02725 //=============================================================================
02726 #endif//TAPs_MULTI_BOUNDING_VOLUME_HPP
02727 
02728 
02729 
02730 
02731 
02732 //=============================================================================
02733 //-----------------------------------------------------------------------------
02734 template <typename T>
02735 bool CDR_DeformPolygonalMesh_vs_RigidPolygonalMesh ( 
02736     TAPs::OpenGL::HalfEdgeModel<T> *             pDefPolyMesh,      
02737     TAPs::OpenGL::HalfEdgeModel<T> const * const pRigidPolyMesh     
02738 )
02739 {
02740     //---------------------------------------------------------------
02741     if ( pDefPolyMesh->GetBVHTree()->TestOverlapWithTillLeafNodes( pRigidPolyMesh->GetBVHTree() ) )
02742     {
02743         //-------------------------------------------------
02744         T separateDistanceConstraint;
02745         Vector3<T> N, centerA;
02746         T separateDistance;
02747         HEFace<T> * primB;
02748         std::vector< HEVertex<T> * const > vertexList;
02749         int noOfVertices;
02750         //-------------------------------------------------
02751         std::vector< BVHNode<T> * > *   listOfCollidedNode_Def   = &pDefPolyMesh->GetBVHTree()->GetListOfCollidedNodes();
02752         std::vector< BVHNode<T> * > *   listOfCollidedNode_Rigid = &pDefPolyMesh->GetBVHTree()->GetListOfCollidedNodesThat();
02753         std::set< BVHNode<T> * > defPolyMesh_NodeSet;
02754         //-------------------------------------------------
02755         // Deform the deformable polygonal mesh away from the rigid polygonal mesh
02756         for ( int i = 0; i < static_cast<int>( listOfCollidedNode_Def->size() ); ++i ) {
02757 
02758             separateDistanceConstraint = 0.5 * (   (*listOfCollidedNode_Def)[i]->GetRadius() 
02759                                                  + (*listOfCollidedNode_Rigid)[i]->GetRadius() );
02760             centerA = ( pRigidPolyMesh->GetTransform().GetMatrixTransform() * 
02761                         Vector4<T>( (*listOfCollidedNode_Rigid)[i]->GetCenter() ) ).GetVector3();
02762             N = centerA - (*listOfCollidedNode_Def)[i]->GetCenter();
02763             separateDistance = separateDistanceConstraint - N.Length();
02764             if ( separateDistance > Math<T>::ZERO ) {
02765                 N.Normalized();
02766                 N *= separateDistance;
02767                 primB = (*listOfCollidedNode_Def)[i]->GetAPrimitiveHalfEdgeFace();
02768                 vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices );
02769                 //-------------------------------
02770                 // For each vertex in a primitive
02771                 for ( int j = 0; j < noOfVertices; ++j ) {
02772                     vertexList[j]->SetPosition( vertexList[j]->GetPosition() - N );
02773                 }
02774             }
02775             // List of BVNodes to be updated
02776             defPolyMesh_NodeSet.insert( (*listOfCollidedNode_Def)[i] );
02777         }
02778         //-------------------------------------------------
02779         // Update Normals of Deformable Polygonal Mesh
02780         pDefPolyMesh->CalAndSetNormals();
02781         //-------------------------------------------------
02782         // Update Bounding Volume Hierarchy of Deformable Polygonal Mesh
02783         pDefPolyMesh->GetBVHTree()->Update( defPolyMesh_NodeSet );
02784         //-------------------------------------------------
02785         return true;
02786     }
02787     //---------------------------------------------------------------
02788     return false;
02789 }
02790 // END: CDR_DeformPolygonalMesh_vs_RigidPolygonalMesh(...)
02791 //-----------------------------------------------------------------------------
02792 //=============================================================================
02793 
02794 
02795 
02796 
02797 //=============================================================================
02798 //-----------------------------------------------------------------------------
02799 //template <typename T>
02800 //bool CDR_DeformPolygonalMesh_vs_DeformPolygonalMesh ( 
02801 //  TAPs::OpenGL::HalfEdgeModel<T> * const pDefPolyMesh_1,  //!< the 1st deformable polygonal mesh model
02802 //  TAPs::OpenGL::HalfEdgeModel<T> * const pDefPolyMesh_2,  //!< the 2nd deformable polygonal mesh model
02803 //  T deformRatio   //!< deformation ratio (must be between [0-1]) where 0 means the model is 100% deformed while the other model is 0% deformed
02804 //)
02805 //{
02806 //  //---------------------------------------------------------------
02807 //  if ( pDefPolyMesh_1->GetBVHTree()->TestOverlapWithTillLeafNodes( pDefPolyMesh_2->GetBVHTree() ) )
02808 //  {
02809 //      //-------------------------------------------------
02810 //      T separateDistanceConstraint;
02811 //      Vector3<T> N, centerA;
02812 //      T separateDistance;
02813 //      HEFace<T> * primB;
02814 //      std::vector< HEVertex<T> * const > vertexList;
02815 //      int noOfVertices;
02816 //      //-------------------------------------------------
02817 //      std::vector< BVHNode<T> * > *   listOfCollidedNode_Def_1 = &pDefPolyMesh_1->GetBVHTree()->GetListOfCollidedNodes();
02818 //      std::vector< BVHNode<T> * > *   listOfCollidedNode_Def_2 = &pDefPolyMesh_1->GetBVHTree()->GetListOfCollidedNodesThat();
02819 //      std::set< BVHNode<T> * > defPolyMesh_NodeSet;
02820 //      //-------------------------------------------------
02821 //      //// Deform the deformable polygonal mesh away from the rigid polygonal mesh
02822 //      //for ( int i = 0; i < static_cast<int>( listOfCollidedNode_Def->size() ); ++i ) {
02823 //
02824 //      //  separateDistanceConstraint = 0.5 * (   (*listOfCollidedNode_Def_1)[i]->GetRadius() 
02825 //      //                                       + (*listOfCollidedNode_Def_2)[i]->GetRadius() );
02826 //      //  centerA = ( pRigidPolyMesh->GetTransform().GetMatrixTransform() * 
02827 //      //              Vector4<T>( (*listOfCollidedNode_Rigid)[i]->GetCenter() ) ).GetVector3();
02828 //      //  N = centerA - (*listOfCollidedNode_Def)[i]->GetCenter();
02829 //      //  separateDistance = separateDistanceConstraint - N.Length();
02830 //      //  if ( separateDistance > Math<T>::ZERO ) {
02831 //      //      N.Normalized();
02832 //      //      N *= separateDistance;
02833 //      //      primB = (*listOfCollidedNode_Def)[i]->GetAPrimitiveHalfEdgeFace();
02834 //      //      vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices );
02835 //      //      //-------------------------------
02836 //      //      // For each vertex in a primitive
02837 //      //      for ( int j = 0; j < noOfVertices; ++j ) {
02838 //      //          vertexList[j]->SetPosition( vertexList[j]->GetPosition() - N );
02839 //      //      }
02840 //      //  }
02841 //      //  // List of BVNodes to be updated
02842 //      //  defPolyMesh_NodeSet.insert( (*listOfCollidedNode_Def)[i] );
02843 //      //}
02844 //      ////-------------------------------------------------
02845 //      //// Update Normals of Deformable Polygonal Mesh
02846 //      //pDefPolyMesh->CalAndSetNormals();
02847 //      ////-------------------------------------------------
02848 //      //// Update Bounding Volume Hierarchy of Deformable Polygonal Mesh
02849 //      //pDefPolyMesh->GetBVHTree()->Update( defPolyMesh_NodeSet );
02850 //      ////-------------------------------------------------
02851 //      //return true;
02852 //  }
02853 //  //---------------------------------------------------------------
02854 //  return false;
02855 //}
02856 // END: CDR_DeformPolygonalMesh_vs_DeformPolygonalMesh(...)
02857 //-----------------------------------------------------------------------------
02858 //=============================================================================
02859 
02860 
02861 
02862 
02863 //-----------------------------------------------------------------------------
02864 //=============================================================================
02865 END_NAMESPACE_TAPs__CD__Fn
02866 //34567890123456789012345678901234567890123456789012345678901234567890123456789
02867 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines