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