#include "TAPsColDetFns.hpp"


Go to the source code of this file.
Namespaces | |
| namespace | Private |
Defines | |
| #define | TAPs_STRAND_MODEL_HPP |
Functions | |
| BEGIN_NAMESPACE_TAPs__CD__Fn void | CalFinalForce () |
| template<typename T> | |
| bool | Private::CD (TAPs::OpenGL::ModelStrand< T > *pStrandObj, TAPs::BVHTree< T > const *const pObjBVH, TAPs::TransformationSupport< T > const *const pTransform, std::vector< BVHNode< T > * > *listOfSutureCollidedNodes, std::vector< BVHNode< T > * > *listOfObjectCollidedNodes) |
| Collision Detection of a strand with another object's bounding volume hierarchy tree. | |
| template<typename T> | |
| bool | CD_PolygonalMesh_vs_LineSegment (TAPs::OpenGL::HETriMeshOneModelMultiParts< T > *pPolygonalMeshObj, TAPs::Vector3< T > const *const ptA, TAPs::Vector3< T > const *const ptB, std::vector< TAPs::Vector3< T > > *listOfIntersectedPoints, std::vector< TAPs::HEFace< T > * > *listOfIntersectedFaces, std::vector< TAPs::HEVertex< T > * > *listOfClosestVertices) |
| template<typename T> | |
| bool | CD_PolygonalMesh_vs_LineSegment (TAPs::OpenGL::HalfEdgeModel< T > *pPolygonalMeshObj, TAPs::Vector3< T > const *const ptA, TAPs::Vector3< T > const *const ptB, std::vector< TAPs::Vector3< T > > *listOfIntersectedPoints, std::vector< TAPs::HEFace< T > * > *listOfIntersectedFaces, std::vector< TAPs::HEVertex< T > * > *listOfClosestVertices) |
| template<typename T> | |
| bool | CD_PolygonalMesh_vs_LineSegment (TAPs::OpenGL::XPolygonalModel< T > *pPolygonalMeshObj, TAPs::Vector3< T > const *const ptA, TAPs::Vector3< T > const *const ptB, std::vector< TAPs::Vector3< T > > *listOfIntersectedPoints, std::vector< TAPs::Face< T > * > *listOfIntersectedFaces, std::vector< TAPs::XVertex< T > * > *listOfClosestVertices) |
| template<typename T> | |
| bool | CD_PolygonalMesh_vs_LineSegment (TAPs::OpenGL::PolygonalModel< T > *pPolygonalMeshObj, TAPs::Vector3< T > const *const ptA, TAPs::Vector3< T > const *const ptB, std::vector< TAPs::Vector3< T > > *listOfIntersectedPoints, std::vector< TAPs::Face< T > * > *listOfIntersectedFaces, std::vector< TAPs::Vertex< T > * > *listOfClosestVertices) |
| Collision detection and response of a polygonal mesh model with a line segment. | |
| template<typename T> | |
| bool | CDR_DeformPolygonalMesh_vs_DeformPolygonalMesh (TAPs::OpenGL::HalfEdgeModel< T > *const pDefPolyMesh_1, TAPs::OpenGL::HalfEdgeModel< T > *const pDefPolyMesh_2, T deformRatio) |
| Collision detection and response of a deformable polygonal mesh model with a rigid polygonal mesh model. | |
| template<typename T> | |
| bool | CDR_DeformPolygonalMesh_vs_RigidPolygonalMesh (TAPs::OpenGL::HalfEdgeModel< T > *pDefPolyMesh, TAPs::OpenGL::HalfEdgeModel< T > const *const pRigidPolyMesh) |
| Collision detection and response of a deformable polygonal mesh model with a rigid polygonal mesh model. | |
| template<typename T> | |
| bool | CDR_PolygonalMesh_vs_BV (TAPs::OpenGL::HETriMeshOneModelMultiParts< T > *pPolygonalMeshObj, TAPs::BoundingVolume< T > const *const pBVObj) |
| template<typename T> | |
| bool | CDR_PolygonalMesh_vs_BV (TAPs::OpenGL::HalfEdgeModel< T > *pPolygonalMeshObj, TAPs::BoundingVolume< T > const *const pBVObj) |
| template<typename T> | |
| bool | CDR_PolygonalMesh_vs_BV (TAPs::OpenGL::XPolygonalModel< T > *pPolygonalMeshObj, TAPs::BoundingVolume< T > const *const pBVObj) |
| template<typename T> | |
| bool | CDR_PolygonalMesh_vs_BV (TAPs::OpenGL::PolygonalModel< T > *pPolygonalMeshObj, TAPs::BoundingVolume< T > const *const pBVObj) |
| Collision detection and response of a strand object with a multi bounding volume object. The function returns true if collision occurs. The function moves the strand to resolve the collision. The multi bouding volume is unaffected. | |
| template<typename T> | |
| bool | CDR_PolygonalMesh_vs_MBV (TAPs::OpenGL::HETriMeshOneModelMultiParts< T > *pPolygonalMeshObj, TAPs::MultiBoundingVolume< T > const *const pMBVObj, TAPs::Vector3< T > *totalForce, T gain) |
| template<typename T> | |
| bool | CDR_PolygonalMesh_vs_MBV (TAPs::OpenGL::HalfEdgeModel< T > *pPolygonalMeshObj, TAPs::MultiBoundingVolume< T > const *const pMBVObj) |
| template<typename T> | |
| bool | CDR_PolygonalMesh_vs_MBV (TAPs::OpenGL::XPolygonalModel< T > *pPolygonalMeshObj, TAPs::MultiBoundingVolume< T > const *const pMBVObj) |
| template<typename T> | |
| bool | CDR_PolygonalMesh_vs_MBV (TAPs::OpenGL::PolygonalModel< T > *pPolygonalMeshObj, TAPs::MultiBoundingVolume< T > const *const pMBVObj) |
| Collision detection and response of a polygonal mesh model with a multi bounding volume object. | |
| template<typename T> | |
| bool | CDR_Strand_vs_MBV (TAPs::OpenGL::ModelStrand< T > *pStrandObj, TAPs::MultiBoundingVolume< T > const *const pMBVObj, TAPs::TransformationSupport< T > const *const pTransform) |
| template<typename T> | |
| bool | Private::CR (TAPs::OpenGL::ModelStrand< T > *pStrandObj, TAPs::BVHTree< T > const *const pObjBVH, TAPs::TransformationSupport< T > const *const pTransform, std::vector< BVHNode< T > * > *listOfSutureCollidedNodes, std::vector< BVHNode< T > * > *listOfObjectCollidedNodes) |
| Collision Detection of a strand with another object's bounding volume hierarchy tree. | |
| #define TAPs_STRAND_MODEL_HPP |
Definition at line 85 of file TAPsColDetFns.cpp.
| BEGIN_NAMESPACE_TAPs__CD__Fn void CalFinalForce | ( | ) |
Definition at line 75 of file TAPsColDetFns.cpp.
00076 { 00077 finalForce.SetXYZ( 0, 0, 0 ); 00078 for ( int i = 0; i < static_cast<int>( ListOfForces.size() ); ++i ) { 00079 finalForce += ListOfForces[i]; 00080 } 00081 }
| bool CD_PolygonalMesh_vs_LineSegment | ( | TAPs::OpenGL::HETriMeshOneModelMultiParts< T > * | pPolygonalMeshObj, | |
| TAPs::Vector3< T > const *const | ptA, | |||
| TAPs::Vector3< T > const *const | ptB, | |||
| std::vector< TAPs::Vector3< T > > * | listOfIntersectedPoints, | |||
| std::vector< TAPs::HEFace< T > * > * | listOfIntersectedFaces, | |||
| std::vector< TAPs::HEVertex< T > * > * | listOfClosestVertices | |||
| ) | [inline] |
| pPolygonalMeshObj | a HETriMeshOneModelMultiParts object |
| ptA | the starting point of a line segment |
| ptB | the ending point of a line segment |
| listOfIntersectedPoints | O/P: list of intersected points |
| listOfIntersectedFaces | O/P: list of intersected faces |
| listOfClosestVertices | O/P: list of closest vertices |
Definition at line 1664 of file TAPsColDetFns.cpp.
01668 : list of intersected points 01669 std::vector< TAPs::HEFace<T>* > * listOfIntersectedFaces, 01670 std::vector< TAPs::HEVertex<T>* > * listOfClosestVertices 01671 ) 01672 { 01673 std::cout << __FILE__ << " " << __LINE__ << " Need to be added to include pPolygonalMeshObj's transformation\n"; 01674 01675 ListOfContactPts.clear(); 01676 ListOfForces.clear(); 01677 01678 #ifdef TAPs_DEBUG_COLLISION_DETECTION 01679 pPolygonalMeshObj->GetBVHTree()->ClearFlags(); 01680 #endif//TAPs_DEBUG_COLLISION_DETECTION 01681 01682 01683 bool bResult = false; 01684 01685 // Collision Detection 01686 bResult = pPolygonalMeshObj->GetBVHTree()->TestIntersectionWithLineSegmentTillLeafNodes( ptA, ptB ); 01687 //--------------------------------------------------------------- 01688 if ( bResult ) { 01689 std::vector< BVHNode<T> * > & nodeList = pPolygonalMeshObj->GetBVHTree()->GetListOfCollidedNodes(); 01690 T ratio; 01691 Vector3<T> projPt; 01692 HEFace<T> * triangle; 01693 std::vector< HEVertex<T> * const > vertexList; 01694 int noOfVertices; 01695 for ( int i = 0; i < static_cast<int>( nodeList.size() ); ++i ) { 01696 // Check intersection of the line segment with the primitive triangle in the BV node 01697 triangle = nodeList[i]->GetAPrimitiveHalfEdgeFace(); 01698 vertexList = triangle->GetPtrsToVerticesAndNumberOfVertices( noOfVertices ); 01699 bool result = CGMath<T>::FindIntersectionLineSegmentTriangle( 01700 *ptA, *ptB, // I/P: a line segment 01701 vertexList[0]->GetPosition(), // I/P: the triangle 01702 vertexList[1]->GetPosition(), 01703 vertexList[2]->GetPosition(), 01704 ratio, // O/P: the ratio 01705 projPt // O/P: the projected point 01706 ); 01707 if ( result ) { 01708 #ifdef TAPs_ADVANCED_SIMULATION 01709 listOfIntersectedPoints->push_back( projPt ); 01710 listOfIntersectedFaces->push_back( triangle ); 01711 // Find the closest point 01712 T distance0 = ( projPt - vertexList[0]->GetPosition() ).Length(); 01713 T distance1 = ( projPt - vertexList[1]->GetPosition() ).Length(); 01714 T distance2 = ( projPt - vertexList[2]->GetPosition() ).Length(); 01715 if ( distance0 > distance1 ) { 01716 if ( distance0 > distance2 ) { 01717 listOfClosestVertices->push_back( vertexList[0] ); 01718 //vertexList[0]->SimFlags.SetSimulationConstraints( TAPs::Enum::AddOn::PUNCTURED ); 01719 } 01720 else { 01721 listOfClosestVertices->push_back( vertexList[2] ); 01722 //vertexList[2]->SimFlags.SetSimulationConstraints( TAPs::Enum::AddOn::PUNCTURED ); 01723 } 01724 } 01725 else { 01726 if ( distance1 > distance2 ) { 01727 listOfClosestVertices->push_back( vertexList[1] ); 01728 //vertexList[1]->SimFlags.SetSimulationConstraints( TAPs::Enum::AddOn::PUNCTURED ); 01729 } 01730 else { 01731 listOfClosestVertices->push_back( vertexList[2] ); 01732 //vertexList[2]->SimFlags.SetSimulationConstraints( TAPs::Enum::AddOn::PUNCTURED ); 01733 } 01734 } 01735 #endif//TAPs_ADVANCED_SIMULATION 01736 std::cout << __FILE__ << " " << __LINE__ << " -- "; 01737 std::cout << "Line Segment intersected Node " << nodeList[i] << "\n"; 01738 } 01739 } 01740 } 01741 return bResult; 01742 }
| bool CD_PolygonalMesh_vs_LineSegment | ( | TAPs::OpenGL::HalfEdgeModel< T > * | pPolygonalMeshObj, | |
| TAPs::Vector3< T > const *const | ptA, | |||
| TAPs::Vector3< T > const *const | ptB, | |||
| std::vector< TAPs::Vector3< T > > * | listOfIntersectedPoints, | |||
| std::vector< TAPs::HEFace< T > * > * | listOfIntersectedFaces, | |||
| std::vector< TAPs::HEVertex< T > * > * | listOfClosestVertices | |||
| ) | [inline] |
| pPolygonalMeshObj | a HalfEdgeModel object |
| ptA | the starting point of a line segment |
| ptB | the ending point of a line segment |
| listOfIntersectedPoints | O/P: list of intersected points |
| listOfIntersectedFaces | O/P: list of intersected faces |
| listOfClosestVertices | O/P: list of closest vertices |
Definition at line 1626 of file TAPsColDetFns.cpp.
01630 : list of intersected points 01631 std::vector< TAPs::HEFace<T>* > * listOfIntersectedFaces, 01632 std::vector< TAPs::HEVertex<T>* > * listOfClosestVertices 01633 ) 01634 { 01635 std::cout << __FILE__ << " " << __LINE__ << " "; 01636 std::cout << "CD_PolygonalMesh_vs_LineSegment( HalfEdgeModel<T>, ... ) -- NOT IMPLEMENTED YET!" << std::endl; 01637 01638 #ifdef TAPs_DEBUG_COLLISION_DETECTION 01639 pPolygonalMeshObj->GetBVHTree()->ClearFlags(); 01640 #endif//TAPs_DEBUG_COLLISION_DETECTION 01641 01642 //#ifdef TAPs_DEBUG_MODE 01643 std::cout << "CD_PolygonalMesh_vs_LineSegment( HalfEdgeModel<T>, ... )\n"; 01644 //#endif//TAPs_DEBUG_MODE 01645 01646 std::cout << "BVHTree: " << *(pPolygonalMeshObj->GetBVHTree()) << "\n"; 01647 01648 bool bResult = false; 01649 01650 // Collision Detection 01651 bResult = pPolygonalMeshObj->GetBVHTree()->TestIntersectionWithLineSegmentTillLeafNodes( ptA, ptB ); 01652 //--------------------------------------------------------------- 01653 // Collision Response 01654 if ( bResult ) { 01655 } 01656 //--------------------------------------------------------------- 01657 return bResult; 01658 }
| bool CD_PolygonalMesh_vs_LineSegment | ( | TAPs::OpenGL::XPolygonalModel< T > * | pPolygonalMeshObj, | |
| TAPs::Vector3< T > const *const | ptA, | |||
| TAPs::Vector3< T > const *const | ptB, | |||
| std::vector< TAPs::Vector3< T > > * | listOfIntersectedPoints, | |||
| std::vector< TAPs::Face< T > * > * | listOfIntersectedFaces, | |||
| std::vector< TAPs::XVertex< T > * > * | listOfClosestVertices | |||
| ) | [inline] |
| pPolygonalMeshObj | a PolygonalModel object |
| ptA | the starting point of a line segment |
| ptB | the ending point of a line segment |
| listOfIntersectedPoints | O/P: list of intersected points |
| listOfIntersectedFaces | O/P: list of intersected faces |
| listOfClosestVertices | O/P: list of closest vertices |
Definition at line 1605 of file TAPsColDetFns.cpp.
01609 : list of intersected points 01610 std::vector< TAPs::Face<T>* > * listOfIntersectedFaces, 01611 std::vector< TAPs::XVertex<T>* > * listOfClosestVertices 01612 ) 01613 { 01614 std::cout << __FILE__ << " " << __LINE__ << " "; 01615 std::cout << "CD_PolygonalMesh_vs_LineSegment( XPolygonalModel<T>, ... ) -- NOT IMPLEMENTED YET!" << std::endl; 01616 bool bResult = false; 01617 //--------------------------------------------------------------- 01618 //--------------------------------------------------------------- 01619 return bResult; 01620 }
| bool CD_PolygonalMesh_vs_LineSegment | ( | TAPs::OpenGL::PolygonalModel< T > * | pPolygonalMeshObj, | |
| TAPs::Vector3< T > const *const | ptA, | |||
| TAPs::Vector3< T > const *const | ptB, | |||
| std::vector< TAPs::Vector3< T > > * | listOfIntersectedPoints, | |||
| std::vector< TAPs::Face< T > * > * | listOfIntersectedFaces, | |||
| std::vector< TAPs::Vertex< T > * > * | listOfClosestVertices | |||
| ) | [inline] |
Collision detection and response of a polygonal mesh model with a line segment.
The polygonal mesh model can be an instance of PolygonalModel, XPolygonalModel, or HalfEdgeModel. The function returns true if collision occurs. The function returns the closest vertex on the triangle intersected by the line segment
| pPolygonalMeshObj | a PolygonalModel object |
| ptA | the starting point of a line segment |
| ptB | the ending point of a line segment |
| listOfIntersectedPoints | O/P: list of intersected points |
| listOfIntersectedFaces | O/P: list of intersected faces |
| listOfClosestVertices | O/P: list of closest vertices |
Definition at line 1584 of file TAPsColDetFns.cpp.
01588 : list of intersected points 01589 std::vector< TAPs::Face<T>* > * listOfIntersectedFaces, 01590 std::vector< TAPs::Vertex<T>* > * listOfClosestVertices 01591 ) 01592 { 01593 std::cout << __FILE__ << " " << __LINE__ << " "; 01594 std::cout << "CD_PolygonalMesh_vs_LineSegment( PolygonalModel<T>, ... ) -- NOT IMPLEMENTED YET!" << std::endl; 01595 bool bResult = false; 01596 //--------------------------------------------------------------- 01597 //--------------------------------------------------------------- 01598 return bResult; 01599 }
| bool CDR_DeformPolygonalMesh_vs_DeformPolygonalMesh | ( | TAPs::OpenGL::HalfEdgeModel< T > *const | pDefPolyMesh_1, | |
| TAPs::OpenGL::HalfEdgeModel< T > *const | pDefPolyMesh_2, | |||
| T | deformRatio = 0.5 | |||
| ) | [inline] |
Collision detection and response of a deformable polygonal mesh model with a rigid polygonal mesh model.
The function returns true if collision occurs. The function deforms both deformable polygonal mesh models to resolve the collision. The deformation is divided by the deformation ratio. The deformation ratio of zero means the first model is 100% deformed, while the second model is 0% deformed.
| pDefPolyMesh_1 | the 1st deformable polygonal mesh model |
| pDefPolyMesh_2 | the 2nd deformable polygonal mesh model |
| deformRatio | deformation ratio (must be between [0-1]) where 0 means the model is 100% deformed while the other model is 0% deformed |
Definition at line 3010 of file TAPsColDetFns.cpp.
03015 { 03016 //--------------------------------------------------------------- 03017 if ( pDefPolyMesh_1->GetBVHTree()->TestOverlapWithTillLeafNodes( pDefPolyMesh_2->GetBVHTree() ) ) 03018 { 03019 //------------------------------------------------- 03020 T separateDistanceConstraint; 03021 Vector3<T> N, centerA; 03022 T separateDistance; 03023 HEFace<T> * primB; 03024 std::vector< HEVertex<T> * const > vertexList; 03025 int noOfVertices; 03026 //------------------------------------------------- 03027 std::vector< BVHNode<T> * > * listOfCollidedNode_Def_1 = &pDefPolyMesh_1->GetBVHTree()->GetListOfCollidedNodes(); 03028 std::vector< BVHNode<T> * > * listOfCollidedNode_Def_2 = &pDefPolyMesh_1->GetBVHTree()->GetListOfCollidedNodesThat(); 03029 std::set< BVHNode<T> * > defPolyMesh_NodeSet; 03030 //------------------------------------------------- 03031 /* 03032 // Deform the deformable polygonal mesh away from the rigid polygonal mesh 03033 for ( int i = 0; i < static_cast<int>( listOfCollidedNode_Def->size() ); ++i ) { 03034 03035 separateDistanceConstraint = 0.5 * ( (*listOfCollidedNode_Def_1)[i]->GetRadius() 03036 + (*listOfCollidedNode_Def_2)[i]->GetRadius() ); 03037 centerA = ( pRigidPolyMesh->GetTransform().GetMatrixTransform() * 03038 Vector4<T>( (*listOfCollidedNode_Rigid)[i]->GetCenter() ) ).GetVector3(); 03039 N = centerA - (*listOfCollidedNode_Def)[i]->GetCenter(); 03040 separateDistance = separateDistanceConstraint - N.Length(); 03041 if ( separateDistance > Math<T>::ZERO ) { 03042 N.Normalized(); 03043 N *= separateDistance; 03044 primB = (*listOfCollidedNode_Def)[i]->GetAPrimitiveHalfEdgeFace(); 03045 vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices ); 03046 //------------------------------- 03047 // For each vertex in a primitive 03048 for ( int j = 0; j < noOfVertices; ++j ) { 03049 vertexList[j]->SetPosition( vertexList[j]->GetPosition() - N ); 03050 } 03051 } 03052 // List of BVNodes to be updated 03053 defPolyMesh_NodeSet.insert( (*listOfCollidedNode_Def)[i] ); 03054 } 03055 //------------------------------------------------- 03056 // Update Normals of Deformable Polygonal Mesh 03057 pDefPolyMesh->CalAndSetNormals(); 03058 //------------------------------------------------- 03059 // Update Bounding Volume Hierarchy of Deformable Polygonal Mesh 03060 pDefPolyMesh->GetBVHTree()->Update( defPolyMesh_NodeSet ); 03061 //------------------------------------------------- 03062 return true; 03063 //*/ 03064 } 03065 //--------------------------------------------------------------- 03066 return false; 03067 }
| bool CDR_DeformPolygonalMesh_vs_RigidPolygonalMesh | ( | TAPs::OpenGL::HalfEdgeModel< T > * | pDefPolyMesh, | |
| TAPs::OpenGL::HalfEdgeModel< T > const *const | pRigidPolyMesh | |||
| ) | [inline] |
Collision detection and response of a deformable polygonal mesh model with a rigid polygonal mesh model.
Each polygonal mesh model can be an instance of PolygonalModel, XPolygonalModel, or HalfEdgeModel. The function returns true if collision occurs. The function deforms the deformable polygonal mesh model to resolve the collision. The rigid polygonal mesh model is unaffected.
| pDefPolyMesh | a deformable polygonal mesh model |
| pRigidPolyMesh | a rigid polygonal mesh model |
Definition at line 2945 of file TAPsColDetFns.cpp.
02949 { 02950 //--------------------------------------------------------------- 02951 if ( pDefPolyMesh->GetBVHTree()->TestOverlapWithTillLeafNodes( pRigidPolyMesh->GetBVHTree() ) ) 02952 { 02953 //------------------------------------------------- 02954 T separateDistanceConstraint; 02955 Vector3<T> N, centerA; 02956 T separateDistance; 02957 HEFace<T> * primB; 02958 std::vector< HEVertex<T> * const > vertexList; 02959 int noOfVertices; 02960 //------------------------------------------------- 02961 std::vector< BVHNode<T> * > * listOfCollidedNode_Def = &pDefPolyMesh->GetBVHTree()->GetListOfCollidedNodes(); 02962 std::vector< BVHNode<T> * > * listOfCollidedNode_Rigid = &pDefPolyMesh->GetBVHTree()->GetListOfCollidedNodesThat(); 02963 std::set< BVHNode<T> * > defPolyMesh_NodeSet; 02964 //------------------------------------------------- 02965 // Deform the deformable polygonal mesh away from the rigid polygonal mesh 02966 for ( int i = 0; i < static_cast<int>( listOfCollidedNode_Def->size() ); ++i ) { 02967 02968 separateDistanceConstraint = 0.5 * ( (*listOfCollidedNode_Def)[i]->GetRadius() 02969 + (*listOfCollidedNode_Rigid)[i]->GetRadius() ); 02970 centerA = ( pRigidPolyMesh->GetTransform().GetMatrixTransform() * 02971 Vector4<T>( (*listOfCollidedNode_Rigid)[i]->GetCenter() ) ).GetVector3(); 02972 N = centerA - (*listOfCollidedNode_Def)[i]->GetCenter(); 02973 separateDistance = separateDistanceConstraint - N.Length(); 02974 if ( separateDistance > Math<T>::ZERO ) { 02975 N.Normalized(); 02976 N *= separateDistance; 02977 primB = (*listOfCollidedNode_Def)[i]->GetAPrimitiveHalfEdgeFace(); 02978 vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices ); 02979 //------------------------------- 02980 // For each vertex in a primitive 02981 for ( int j = 0; j < noOfVertices; ++j ) { 02982 vertexList[j]->SetPosition( vertexList[j]->GetPosition() - N ); 02983 } 02984 } 02985 // List of BVNodes to be updated 02986 defPolyMesh_NodeSet.insert( (*listOfCollidedNode_Def)[i] ); 02987 } 02988 //------------------------------------------------- 02989 // Update Normals of Deformable Polygonal Mesh 02990 pDefPolyMesh->CalAndSetNormals(); 02991 //------------------------------------------------- 02992 // Update Bounding Volume Hierarchy of Deformable Polygonal Mesh 02993 pDefPolyMesh->GetBVHTree()->Update( defPolyMesh_NodeSet ); 02994 //------------------------------------------------- 02995 return true; 02996 } 02997 //--------------------------------------------------------------- 02998 return false; 02999 }
| bool CDR_PolygonalMesh_vs_BV | ( | TAPs::OpenGL::HETriMeshOneModelMultiParts< T > * | pPolygonalMeshObj, | |
| TAPs::BoundingVolume< T > const *const | pBVObj | |||
| ) | [inline] |
| pPolygonalMeshObj | a HETriMeshOneModelMultiParts object |
| pBVObj | a bounding volume object |
Definition at line 1005 of file TAPsColDetFns.cpp.
01009 { 01010 ListOfContactPts.clear(); 01011 ListOfForces.clear(); 01012 01013 #ifdef TAPs_DEBUG_COLLISION_DETECTION 01014 pPolygonalMeshObj->GetBVHTree()->ClearFlags(); 01015 #endif//TAPs_DEBUG_COLLISION_DETECTION 01016 01017 //#ifdef TAPs_DEBUG_MODE 01018 std::cout << "CDR_PolygonalMesh_vs_BV( HalfEdgeModel<T>, BoundingVolume<T> )\n"; 01019 //#endif//TAPs_DEBUG_MODE 01020 01021 std::cout << "BVHTree: " << *(pPolygonalMeshObj->GetBVHTree()) << "\n"; 01022 01023 bool bResult = false; 01024 01025 // Collision Detection 01026 bResult = pPolygonalMeshObj->GetBVHTree()->TestOverlapWithTillLeafNodes( pBVObj ); 01027 01028 //--------------------------------------------------------------- 01029 // Collision Response 01030 if ( bResult ) { 01031 01032 // Reset the result for primitive-primitive test, 01033 // because the previous result is only from bounding volume test. 01034 bResult = false; 01035 01036 //------------------------------------------------- 01037 T separateDistanceConstraint; 01038 Vector3<T> N, centerA; 01039 T separateDistance; 01040 HEFace<T> * primB; 01041 std::vector< HEVertex<T> * const > vertexList; 01042 int noOfVertices; 01043 //------------------------------------------------- 01044 TransformationSupport<T> trxMBV; // default constructor is an identity transformation 01045 01046 //------------------------------------------------- 01047 std::set< BVHNode<T> * > defPolyMesh_NodeSet; 01048 01049 // Get the list of collided nodes and bounding volumes 01050 std::vector< BVsAndNodesList<T> > * bvList = &pPolygonalMeshObj->GetBVHTree()->GetListOfCollidedBoundingVolumesAndNodes(); 01051 //------------------------------------------------- 01052 // Traverse the list of bounding volumes 01053 std::vector< BVsAndNodesList<T> >::const_iterator pos = bvList->begin(); 01054 //------------------------------------------------- 01055 // CASE: the polygonal mesh object's transformation is off. 01056 if ( pPolygonalMeshObj->GetTransform().GetStatusApplyTransformation() == false ) { 01057 while ( pos != bvList->end() ) { 01058 01059 int count = 0; 01060 01061 // Store the transformation of the bounding volume 01062 TransformationSupport<T> trx = (*pos).BV->GetTransform(); 01063 // Case: BV's transformation is on. 01064 if ( (*pos).BV->GetTransform().GetStatusApplyTransformation() ) { 01065 //(*pos).BV->GetTransform().SetMatrixTransform( trx.GetMatrixTransform() ); 01066 } 01067 // Case: BV's transformation is off. 01068 else { 01069 (*pos).BV->GetTransform().EnableStatusApplyTransformation(); 01070 (*pos).BV->GetTransform().SetMatrixTransform( Matrix4x4<T>() ); // set to identity matrix 01071 } 01072 01073 //----------------------------------------- 01074 // Deform the deformable polygonal mesh away from the rigid polygonal mesh 01075 switch ( (*pos).BV->GetType() ) { 01076 01077 case TAPs::Enum::BOUNDING_SPHERE: 01078 { 01079 01080 std::cout << "BV: " << (*pos).BV->GetName() << "\n"; 01081 01082 // For Test against triangle 01083 //--------------------------------------------- 01084 // Transform the BV due to its transformation, center, and radius 01085 01086 Vector3<T> centerOfBV( (*pos).BV->GetCenter() ); 01087 T radiusOfBV = (*pos).BV->GetRadius(); 01088 01089 Vector3<T> C( (*pos).BV->GetCenter() ); 01090 Matrix4x4<T> translation( 1, 0, 0, C[0], 01091 0, 1, 0, C[1], 01092 0, 0, 1, C[2], 01093 0, 0, 0, 1 ); 01094 Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV ); 01095 Matrix4x4<T> scale( S[0], 0, 0, 0, 01096 0, S[1], 0, 0, 01097 0, 0, S[2], 0, 01098 0, 0, 0, 1 ); 01099 Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale; 01100 01101 // BV Sphere's center and radius after the transformation 01102 centerOfBV = (mat * Vector4<T>(0,0,0,1)).GetVector3(); 01103 radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length(); 01104 //--------------------------------------------- 01105 01106 count = 0; 01107 for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) { 01108 01109 bool testResult = false; 01110 01111 // Assume triangle is in Sphere Node 01112 // Test the triangle in sphere node with BVSphere 01113 primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace(); 01114 vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices ); 01115 Vector3<T> cdrVec[3]; 01116 01117 //* 01118 // Test against each vertex in the triangle 01119 //----------------------------------- 01120 for ( int j = 0; j < noOfVertices; ++j ) { 01121 if( (*pos).BV->TestPointLocation( &(vertexList[j]->GetPosition()), &(cdrVec[j]) ) ) 01122 { 01123 vertexList[j]->SetPosition( vertexList[j]->GetPosition() + cdrVec[j] ); 01124 01125 //ListOfContactPts.push_back( Vector3<GLfloat>( (*pos).BV->GetCenter()[0], (*pos).BV->GetCenter()[1], (*pos).BV->GetCenter()[2] ) ); 01126 ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) ); 01127 ListOfForces.push_back( Vector3<GLfloat>( cdrVec[j][0], cdrVec[j][1], cdrVec[j][2] ) ); 01128 01129 testResult = true; 01130 } 01131 } 01132 //----------------------------------- 01133 //*/ 01134 01135 //* 01136 // Test against triangle 01137 //----------------------------------- 01138 Vector3<T> contactPt; 01139 if ( TAPs::CGMath<T>::FindIntersectionSphereTriangle( 01140 centerOfBV, radiusOfBV, // BVSphere properties 01141 vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices 01142 cdrVec[0], cdrVec[1], cdrVec[2] // out vectors 01143 //, &contactPt 01144 ) ) { 01145 vertexList[0]->SetPosition( vertexList[0]->GetPosition() + cdrVec[0]*CDScaleForSphereBVWithTriangle ); 01146 vertexList[1]->SetPosition( vertexList[1]->GetPosition() + cdrVec[1]*CDScaleForSphereBVWithTriangle ); 01147 vertexList[2]->SetPosition( vertexList[2]->GetPosition() + cdrVec[2]*CDScaleForSphereBVWithTriangle ); 01148 01149 //ListOfContactPts.push_back( Vector3<GLfloat>( contactPt[0], contactPt[1], contactPt[2] ) ); 01150 ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) ); 01151 Vector3<T> force( (cdrVec[0] + cdrVec[1] + cdrVec[2] )/3 ); 01152 ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) ); 01153 01154 testResult = true; 01155 } 01156 //----------------------------------- 01157 //*/ 01158 01159 01160 std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n"; 01161 01162 // List of BVNodes to be updated 01163 if ( testResult ) { 01164 defPolyMesh_NodeSet.insert( (*pos).NodeList[i] ); 01165 bResult = true; 01166 } 01167 } 01168 } 01169 break; 01170 01171 case TAPs::Enum::BOUNDING_CYLINDER: 01172 { 01173 std::cout << "BV: " << (*pos).BV->GetName() << "\n"; 01174 01175 // For Test against triangle 01176 //--------------------------------------------- 01177 // Transform the BV due to its transformation, center, and radius 01178 01179 Vector3<T> centerOfBV( (*pos).BV->GetCenter() ); 01180 T halfHeightOfBV = (*pos).BV->GetHeight() / 2.0; 01181 //Vector3<T> topPtOfBV( centerOfBV[0], centerOfBV[1], centerOfBV[2] + halfHeightOfBV ); 01182 //Vector3<T> bottomPtOfBV( centerOfBV[0], centerOfBV[1], centerOfBV[2] - halfHeightOfBV ); 01183 T radiusOfBV = (*pos).BV->GetRadius(); 01184 01185 Vector3<T> C( (*pos).BV->GetCenter() ); 01186 Matrix4x4<T> translation( 1, 0, 0, C[0], 01187 0, 1, 0, C[1], 01188 0, 0, 1, C[2], 01189 0, 0, 0, 1 ); 01190 Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV ); 01191 Matrix4x4<T> scale( S[0], 0, 0, 0, 01192 0, S[1], 0, 0, 01193 0, 0, S[2], 0, 01194 0, 0, 0, 1 ); 01195 Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale; 01196 01197 // BV Sphere's center and radius after the transformation 01198 centerOfBV = (mat * Vector4<T>(0,0,0,1)).GetVector3(); 01199 Vector3<T> topPtOfBV( (mat * Vector4<T>(0,0,halfHeightOfBV,1)).GetVector3() ); 01200 Vector3<T> bottomPtOfBV( (mat * Vector4<T>(0,0,-halfHeightOfBV,1)).GetVector3() ); 01201 radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length(); 01202 //--------------------------------------------- 01203 01204 count = 0; 01205 for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) { 01206 01207 bool testResult = false; 01208 01209 // Assume triangle is in Sphere Node 01210 // Test the triangle in sphere node with BVCylinder 01211 primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace(); 01212 vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices ); 01213 Vector3<T> cdrVec[3]; 01214 01215 //* 01216 // Test against each vertex in the triangle 01217 //----------------------------------- 01218 for ( int j = 0; j < noOfVertices; ++j ) { 01219 if( (*pos).BV->TestPointLocation( &(vertexList[j]->GetPosition()), &(cdrVec[j]) ) ) 01220 { 01221 vertexList[j]->SetPosition( vertexList[j]->GetPosition() + cdrVec[j] ); 01222 01223 //ListOfContactPts.push_back( Vector3<GLfloat>( (*pos).BV->GetCenter()[0], (*pos).BV->GetCenter()[1], (*pos).BV->GetCenter()[2] ) ); 01224 ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) ); 01225 ListOfForces.push_back( Vector3<GLfloat>( cdrVec[j][0], cdrVec[j][1], cdrVec[j][2] ) ); 01226 01227 testResult = true; 01228 } 01229 } 01230 //----------------------------------- 01231 //*/ 01232 01233 //* 01234 // Test against triangle 01235 //----------------------------------- 01236 Vector3<T> contactPt; 01237 if ( TAPs::CGMath<T>::FindIntersectionCylinderTriangle( 01238 topPtOfBV, bottomPtOfBV, radiusOfBV, // BVCylinder properties 01239 vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices 01240 cdrVec[0], cdrVec[1], cdrVec[2] // out vectors 01241 , &contactPt 01242 ) ) { 01243 vertexList[0]->SetPosition( vertexList[0]->GetPosition() + cdrVec[0]*CDScaleForCylinderBVWithTriangle ); 01244 vertexList[1]->SetPosition( vertexList[1]->GetPosition() + cdrVec[1]*CDScaleForCylinderBVWithTriangle ); 01245 vertexList[2]->SetPosition( vertexList[2]->GetPosition() + cdrVec[2]*CDScaleForCylinderBVWithTriangle ); 01246 01247 ListOfContactPts.push_back( Vector3<GLfloat>( contactPt[0], contactPt[1], contactPt[2] ) ); 01248 Vector3<T> force( (cdrVec[0] + cdrVec[1] + cdrVec[2] )/3 ); 01249 ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) ); 01250 01251 testResult = true; 01252 } 01253 //----------------------------------- 01254 //*/ 01255 01256 std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n"; 01257 01258 // List of BVNodes to be updated 01259 if ( testResult ) { 01260 defPolyMesh_NodeSet.insert( (*pos).NodeList[i] ); 01261 bResult = true; 01262 } 01263 } 01264 } 01265 break; 01266 01267 default: 01268 std::cout << "CDR_PolygonalMesh_vs_MBV of BV Type (" << (*pos).BV->GetType() << ") doesn't support!\n"; 01269 break; 01270 } 01271 01272 // Restore the transformation of the bounding volume 01273 //(*pos).BV->GetTransform().SetMatrixTransform( trx.GetMatrixTransform() ); 01274 (*pos).BV->SetTransform( trx ); 01275 // Next Bounding Volume 01276 ++pos; 01277 } 01278 } // END CASE: the polygonal mesh object's transformation is off. 01279 01280 //------------------------------------------------- 01281 // CASE: the polygonal mesh object's transformation is on. 01282 else { 01283 //std::cout << "CDR_PolygonalMesh_vs_MBV(...) for HETriMeshOneModelMultiParts --> \n"; 01284 //std::cout << "\tCASE: the polygonal mesh object's transformation is on. -- NOT IMPLEMENTED YET!\n"; 01285 01286 // Mesh's inverse transformation 01287 Matrix4x4<T> trxInvMesh = pPolygonalMeshObj->GetTransform().GetMatrixTransform(); 01288 trxInvMesh.Inversed(); 01289 Vector3<T> vOrigin( (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(0,0,0,1)).GetVector3() ); 01290 01291 while ( pos != bvList->end() ) { 01292 01293 int count = 0; 01294 01295 // Store the transformation of the bounding volume including the mesh's inverse transformation 01296 TransformationSupport<T> trx = (*pos).BV->GetTransform(); 01297 // Case: BV's transformation is on. 01298 if ( (*pos).BV->GetTransform().GetStatusApplyTransformation() ) { 01299 (*pos).BV->GetTransform().SetMatrixTransform( trxInvMesh * trx.GetMatrixTransform() ); 01300 } 01301 // Case: BV's transformation is off. 01302 else { 01303 (*pos).BV->GetTransform().EnableStatusApplyTransformation(); 01304 (*pos).BV->GetTransform().SetMatrixTransform( trxInvMesh ); 01305 } 01306 01307 //----------------------------------------- 01308 // Deform the deformable polygonal mesh away from the rigid polygonal mesh 01309 switch ( (*pos).BV->GetType() ) { 01310 01311 case TAPs::Enum::BOUNDING_SPHERE: 01312 { 01313 01314 std::cout << "BV: " << (*pos).BV->GetName() << "\n"; 01315 01316 // For Test against triangle 01317 //--------------------------------------------- 01318 // Transform the BV due to its transformation, center, and radius 01319 T radiusOfBV = (*pos).BV->GetRadius(); 01320 Vector3<T> C( (*pos).BV->GetCenter() ); 01321 Matrix4x4<T> translation( 1, 0, 0, C[0], 01322 0, 1, 0, C[1], 01323 0, 0, 1, C[2], 01324 0, 0, 0, 1 ); 01325 Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV ); 01326 Matrix4x4<T> scale( S[0], 0, 0, 0, 01327 0, S[1], 0, 0, 01328 0, 0, S[2], 0, 01329 0, 0, 0, 1 ); 01330 // The BV's current transformation includes the mesh's inverse transformation (see the code above) 01331 Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale; 01332 01333 // BV Sphere's center and radius after the whole transformation from 01334 // BV's transformation to mesh's inverse transformation. 01335 // I.e., transforming the BV to mesh's coordinate 01336 Vector3<T> centerOfBV_inMeshCoord = (mat * Vector4<T>(0,0,0,1)).GetVector3(); 01337 T radiusOfBV_inMeshCoord = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV_inMeshCoord ).Length(); 01338 01339 // Inverse the mesh's transformation to the BV's pure transformation 01340 mat = pPolygonalMeshObj->GetTransform().GetMatrixTransform() * mat; 01341 01342 // BV Sphere's center and radius after the BV's pure transformation 01343 Vector3<T> centerOfBV( (mat * Vector4<T>(0,0,0,1)).GetVector3() ); 01344 radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length(); 01345 //--------------------------------------------- 01346 01347 count = 0; 01348 for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) { 01349 01350 bool testResult = false; 01351 01352 // Assume triangle is in Sphere Node 01353 // Test the triangle in sphere node with BVSphere 01354 primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace(); 01355 vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices ); 01356 Vector3<T> cdrVec[3]; 01357 01358 //* 01359 // Test against each vertex in the triangle 01360 //----------------------------------- 01361 for ( int j = 0; j < noOfVertices; ++j ) { 01362 if( (*pos).BV->TestPointLocation( &(vertexList[j]->GetPosition()), &(cdrVec[j]) ) ) 01363 { 01364 vertexList[j]->SetPosition( vertexList[j]->GetPosition() + cdrVec[j] ); 01365 Vector3<T> force( (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(cdrVec[j])).GetVector3() - vOrigin ); 01366 01367 //ListOfContactPts.push_back( Vector3<GLfloat>( (*pos).BV->GetCenter()[0], (*pos).BV->GetCenter()[1], (*pos).BV->GetCenter()[2] ) ); 01368 ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) ); 01369 ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) ); 01370 01371 testResult = true; 01372 } 01373 } 01374 //----------------------------------- 01375 //*/ 01376 01377 //* 01378 // Test against triangle 01379 //----------------------------------- 01380 //Vector3<T> contactPt; 01381 if ( TAPs::CGMath<T>::FindIntersectionSphereTriangle( 01382 centerOfBV_inMeshCoord, radiusOfBV_inMeshCoord, // BVSphere properties 01383 vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices 01384 cdrVec[0], cdrVec[1], cdrVec[2] // out vectors 01385 //, &contactPt 01386 ) ) { 01387 Vector3<T> force_1( cdrVec[0] * CDScaleForSphereBVWithTriangle ); 01388 Vector3<T> force_2( cdrVec[1] * CDScaleForSphereBVWithTriangle ); 01389 Vector3<T> force_3( cdrVec[2] * CDScaleForSphereBVWithTriangle ); 01390 01391 vertexList[0]->SetPosition( vertexList[0]->GetPosition() + force_1 ); 01392 vertexList[1]->SetPosition( vertexList[1]->GetPosition() + force_2 ); 01393 vertexList[2]->SetPosition( vertexList[2]->GetPosition() + force_3 ); 01394 01395 force_1 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_1)).GetVector3() - vOrigin; 01396 force_2 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_2)).GetVector3() - vOrigin; 01397 force_3 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_3)).GetVector3() - vOrigin; 01398 01399 //ListOfContactPts.push_back( Vector3<GLfloat>( contactPt[0], contactPt[1], contactPt[2] ) ); 01400 ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) ); 01401 Vector3<T> force( ( force_1 + force_2 + force_3 )/3 ); 01402 ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) ); 01403 01404 testResult = true; 01405 } 01406 //----------------------------------- 01407 //*/ 01408 01409 01410 std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n"; 01411 01412 // List of BVNodes to be updated 01413 if ( testResult ) { 01414 defPolyMesh_NodeSet.insert( (*pos).NodeList[i] ); 01415 bResult = true; 01416 } 01417 } 01418 } 01419 break; 01420 01421 case TAPs::Enum::BOUNDING_CYLINDER: 01422 { 01423 std::cout << "BV: " << (*pos).BV->GetName() << "\n"; 01424 01425 // For Test against triangle 01426 //--------------------------------------------- 01427 // Transform the BV due to its transformation, center, and radius 01428 T radiusOfBV = (*pos).BV->GetRadius(); 01429 Vector3<T> C( (*pos).BV->GetCenter() ); 01430 Matrix4x4<T> translation( 1, 0, 0, C[0], 01431 0, 1, 0, C[1], 01432 0, 0, 1, C[2], 01433 0, 0, 0, 1 ); 01434 Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV ); 01435 Matrix4x4<T> scale( S[0], 0, 0, 0, 01436 0, S[1], 0, 0, 01437 0, 0, S[2], 0, 01438 0, 0, 0, 1 ); 01439 // The BV's current transformation includes the mesh's inverse transformation (see the code above) 01440 Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale; 01441 01442 // BV Sphere's center and radius after the whole transformation from 01443 // BV's transformation to mesh's inverse transformation. 01444 // I.e., transforming the BV to mesh's coordinate 01445 T halfHeightOfBV = (*pos).BV->GetHeight() / 2.0; 01446 Vector3<T> centerOfBV_inMeshCoord = (mat * Vector4<T>(0,0,0,1)).GetVector3(); 01447 T radiusOfBV_inMeshCoord = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV_inMeshCoord ).Length(); 01448 Vector3<T> topPtOfBV_inMeshCoord( (mat * Vector4<T>(0,0,halfHeightOfBV,1)).GetVector3() ); 01449 Vector3<T> bottomPtOfBV_inMeshCoord( (mat * Vector4<T>(0,0,-halfHeightOfBV,1)).GetVector3() ); 01450 01451 // Inverse the mesh's transformation to the BV's pure transformation 01452 mat = pPolygonalMeshObj->GetTransform().GetMatrixTransform() * mat; 01453 01454 // BV Sphere's center and radius after the BV's pure transformation 01455 Vector3<T> centerOfBV( (mat * Vector4<T>(0,0,0,1)).GetVector3() ); 01456 radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length(); 01457 Vector3<T> topPtOfBV( (mat * Vector4<T>(0,0,halfHeightOfBV,1)).GetVector3() ); 01458 Vector3<T> bottomPtOfBV( (mat * Vector4<T>(0,0,-halfHeightOfBV,1)).GetVector3() ); 01459 //--------------------------------------------- 01460 01461 count = 0; 01462 for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) { 01463 01464 bool testResult = false; 01465 01466 // Assume triangle is in Sphere Node 01467 // Test the triangle in sphere node with BVCylinder 01468 primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace(); 01469 vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices ); 01470 Vector3<T> cdrVec[3]; 01471 01472 //* 01473 // Test against each vertex in the triangle 01474 //----------------------------------- 01475 for ( int j = 0; j < noOfVertices; ++j ) { 01476 if( (*pos).BV->TestPointLocation( &(vertexList[j]->GetPosition()), &(cdrVec[j]) ) ) 01477 { 01478 vertexList[j]->SetPosition( vertexList[j]->GetPosition() + cdrVec[j] ); 01479 Vector3<T> force( (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(cdrVec[j])).GetVector3() - vOrigin ); 01480 01481 //ListOfContactPts.push_back( Vector3<GLfloat>( (*pos).BV->GetCenter()[0], (*pos).BV->GetCenter()[1], (*pos).BV->GetCenter()[2] ) ); 01482 ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) ); 01483 ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) ); 01484 01485 testResult = true; 01486 } 01487 } 01488 //----------------------------------- 01489 //*/ 01490 01491 //* 01492 // Test against triangle 01493 //----------------------------------- 01494 Vector3<T> contactPt; 01495 if ( TAPs::CGMath<T>::FindIntersectionCylinderTriangle( 01496 topPtOfBV_inMeshCoord, bottomPtOfBV_inMeshCoord, radiusOfBV_inMeshCoord, // BVCylinder properties 01497 vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices 01498 cdrVec[0], cdrVec[1], cdrVec[2] // out vectors 01499 , &contactPt 01500 ) ) { 01501 Vector3<T> force_1( cdrVec[0] * CDScaleForSphereBVWithTriangle ); 01502 Vector3<T> force_2( cdrVec[1] * CDScaleForSphereBVWithTriangle ); 01503 Vector3<T> force_3( cdrVec[2] * CDScaleForSphereBVWithTriangle ); 01504 01505 vertexList[0]->SetPosition( vertexList[0]->GetPosition() + force_1 ); 01506 vertexList[1]->SetPosition( vertexList[1]->GetPosition() + force_2 ); 01507 vertexList[2]->SetPosition( vertexList[2]->GetPosition() + force_3 ); 01508 01509 force_1 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_1)).GetVector3() - vOrigin; 01510 force_2 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_2)).GetVector3() - vOrigin; 01511 force_3 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_3)).GetVector3() - vOrigin; 01512 01513 contactPt = ( (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(contactPt)).GetVector3() ); 01514 01515 ListOfContactPts.push_back( Vector3<GLfloat>( contactPt[0], contactPt[1], contactPt[2] ) ); 01516 Vector3<T> force( ( force_1 + force_2 + force_3 )/3 ); 01517 ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) ); 01518 01519 testResult = true; 01520 } 01521 //----------------------------------- 01522 //*/ 01523 01524 std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n"; 01525 01526 // List of BVNodes to be updated 01527 if ( testResult ) { 01528 defPolyMesh_NodeSet.insert( (*pos).NodeList[i] ); 01529 bResult = true; 01530 } 01531 } 01532 } 01533 break; 01534 01535 default: 01536 std::cout << "CDR_PolygonalMesh_vs_MBV of BV Type (" << (*pos).BV->GetType() << ") doesn't support!\n"; 01537 break; 01538 } 01539 01540 // Restore the transformation of the bounding volume 01541 //(*pos).BV->GetTransform().SetMatrixTransform( trx.GetMatrixTransform() ); 01542 (*pos).BV->SetTransform( trx ); 01543 // Next Bounding Volume 01544 ++pos; 01545 } 01546 } // END CASE: the polygonal mesh object's transformation is on. 01547 //------------------------------------------------- 01548 01549 //------------------------------------------------- 01550 // Update Normals of Deformable Polygonal Mesh 01551 //pPolygonalMeshObj->CalAndSetNormals(); // commented out to rely on AdvanceSimulation to update the normals 01552 //------------------------------------------------- 01553 // Update Bounding Volume Hierarchy of Deformable Polygonal Mesh 01554 pPolygonalMeshObj->GetBVHTree()->Update( defPolyMesh_NodeSet ); 01555 // FOR HETriMeshOneModelMultiParts 01556 //------------------------------------------------- 01557 // Update for the model's internal simulation 01558 for ( int i = 0; i < static_cast<int>( pPolygonalMeshObj->GetListOfParts().size() ); ++i ) { 01559 pPolygonalMeshObj->GetPtrToPartNo(i)->UpdateStateToArray(); 01560 } 01561 } 01562 //--------------------------------------------------------------- 01563 if ( totalForce ) { 01564 totalForce->SetXYZ( 0, 0, 0 ); 01565 Vector3<float> force( 0, 0, 0 ); 01566 for ( int i = 0; i < ListOfForces.size(); ++i ) { 01567 force += ListOfForces[i]; 01568 } 01569 force *= gain; 01570 (*totalForce).SetXYZ( force[0], force[1], force[2] ); 01571 } 01572 01573 return bResult; 01574 }
| bool CDR_PolygonalMesh_vs_BV | ( | TAPs::OpenGL::HalfEdgeModel< T > * | pPolygonalMeshObj, | |
| TAPs::BoundingVolume< T > const *const | pBVObj | |||
| ) | [inline] |
| pPolygonalMeshObj | a HalfEdgeModel object |
| pBVObj | a bounding volume object |
Definition at line 915 of file TAPsColDetFns.cpp.
00919 { 00920 #ifdef TAPs_DEBUG_COLLISION_DETECTION 00921 //pPolygonalMeshObj->GetBVHTree()->ClearFlags(); 00922 #endif//TAPs_DEBUG_COLLISION_DETECTION 00923 00924 #ifdef TAPs_DEBUG_MODE 00925 std::cout << "CDR_HalfEdgeMesh_vs_BV( HalfEdgeModel<T>, BoundingVolume<T> )\n"; 00926 #endif//TAPs_DEBUG_MODE 00927 00928 00929 //std::cout << "BVHTree: " << *(pPolygonalMeshObj->GetBVHTree()) << "\n"; 00930 00931 //--------------------------------------------------------------- 00932 if ( pPolygonalMeshObj->GetBVHTree()->TestOverlapWithTillLeafNodes( pBVObj ) ) 00933 { 00934 //------------------------------------------------- 00935 T separateDistanceConstraint; 00936 Vector3<T> N, centerA; 00937 T separateDistance; 00938 HEFace<T> * primB; 00939 std::vector< HEVertex<T> * const > vertexList; 00940 int noOfVertices; 00941 //------------------------------------------------- 00942 std::vector< BVHNode<T> * > * listOfCollidedNode_Def = &pPolygonalMeshObj->GetBVHTree()->GetListOfCollidedNodes(); 00943 std::set< BVHNode<T> * > defPolyMesh_NodeSet; 00944 00945 //std::cout << "listOfCollidedNode_Def SIZE: " << listOfCollidedNode_Def->size() << "\n"; 00946 00947 // Collision Response 00948 //------------------------------------------------- 00949 // Deform the deformable polygonal mesh away from the rigid polygonal mesh 00950 switch ( pBVObj->GetType() ) { 00951 case TAPs::Enum::BOUNDING_SPHERE: 00952 for ( int i = 0; i < static_cast<int>( listOfCollidedNode_Def->size() ); ++i ) { 00953 00954 separateDistanceConstraint = 0.5 * ( (*listOfCollidedNode_Def)[i]->GetRadius() + pBVObj->GetRadius() ); 00955 //centerA = ( pRigidPolyMesh->GetTransform().GetMatrixTransform() * 00956 // Vector4<T>( (*listOfCollidedNode_Rigid)[i]->GetCenter() ) ).GetVector3(); 00957 centerA = pBVObj->GetCenter(); 00958 N = centerA - (*listOfCollidedNode_Def)[i]->GetCenter(); 00959 separateDistance = separateDistanceConstraint - N.Length(); 00960 if ( true ) { 00961 //if ( separateDistance > Math<T>::ZERO ) { 00962 N.Normalized(); 00963 N *= separateDistance; 00964 primB = (*listOfCollidedNode_Def)[i]->GetAPrimitiveHalfEdgeFace(); 00965 vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices ); 00966 //------------------------------- 00967 // For each vertex in a primitive 00968 for ( int j = 0; j < noOfVertices; ++j ) { 00969 //vertexList[j]->SetPosition( vertexList[j]->GetPosition() - N ); 00970 vertexList[j]->SetPosition( vertexList[j]->GetPosition() - Vector3<T>( 0.01, 0.01, 0.01 ) ); 00971 //vertexList[j]-> 00972 } 00973 } 00974 00975 #ifdef TAPs_DEBUG_COLLISION_DETECTION 00976 //(*listOfCollidedNode_Def)[i]->flag = true; 00977 #endif//TAPs_DEBUG_COLLISION_DETECTION 00978 00979 // List of BVNodes to be updated 00980 defPolyMesh_NodeSet.insert( (*listOfCollidedNode_Def)[i] ); 00981 } 00982 break; 00983 00984 default: 00985 std::cout << "CDR_PolygonalMesh_vs_BV of BV Type (" << pBVObj->GetType() << ") doesn't support!\n"; 00986 break; 00987 } 00988 //------------------------------------------------- 00989 // Update Normals of Deformable Polygonal Mesh 00990 pPolygonalMeshObj->CalAndSetNormals(); 00991 //------------------------------------------------- 00992 // Update Bounding Volume Hierarchy of Deformable Polygonal Mesh 00993 pPolygonalMeshObj->GetBVHTree()->Update( defPolyMesh_NodeSet ); 00994 //------------------------------------------------- 00995 return true; 00996 } 00997 //--------------------------------------------------------------- 00998 return false; 00999 }
| bool CDR_PolygonalMesh_vs_BV | ( | TAPs::OpenGL::XPolygonalModel< T > * | pPolygonalMeshObj, | |
| TAPs::BoundingVolume< T > const *const | pBVObj | |||
| ) | [inline] |
| pPolygonalMeshObj | a PolygonalModel object |
| pBVObj | a bounding volume object |
Definition at line 899 of file TAPsColDetFns.cpp.
00903 { 00904 std::cout << "CDR_XPolygonalMesh_vs_BV( XPolygonalModel<T>, BoundingVolume<T> ) -- NOT IMPLEMENTED YET!" << std::endl; 00905 bool bResult = false; 00906 //--------------------------------------------------------------- 00907 //--------------------------------------------------------------- 00908 return bResult; 00909 }
| bool CDR_PolygonalMesh_vs_BV | ( | TAPs::OpenGL::PolygonalModel< T > * | pPolygonalMeshObj, | |
| TAPs::BoundingVolume< T > const *const | pBVObj | |||
| ) | [inline] |
Collision detection and response of a strand object with a multi bounding volume object. The function returns true if collision occurs. The function moves the strand to resolve the collision. The multi bouding volume is unaffected.
Collision detection and response of a suture object with a multi bounding volume object. The function returns true if collision occurs. The function moves the suture to resolve the collision. The multi bouding volume is unaffected. Collision detection and response of a strand object with a deformable mesh object (TAPsDeformMesh.hpp). The function returns true if collision occurs. The function moves the strand to resolve the collision. The deformable mesh object is unaffected. Collision detection and response of a suture object with a deformable mesh object (TAPsDeformMesh.hpp). The function returns true if collision occurs. The function moves the suture to resolve the collision. The deformable mesh object is unaffected. Collision detection and response of a deformable mesh object (TAPsDeformMesh.hpp) with a multi bounding volume object. The function returns true if collision occurs. The function moves the deformable mesh to resolve the collision. The multi bounding volume object is unaffected. Collision detection and response of a polygonal mesh model with a bounding volume object. The polygonal mesh model can be an instance of PolygonalModel, XPolygonalModel, or HalfEdgeModel. The function returns true if collision occurs. The function deforms the polygonal mesh model to resolve the collision. The bounding volume object is unaffected.
| pPolygonalMeshObj | a PolygonalModel object |
| pBVObj | a bounding volume object |
Definition at line 883 of file TAPsColDetFns.cpp.
00887 { 00888 std::cout << "CDR_PolygonalMesh_vs_BV( PolygonalModel<T>, BoundingVolume<T> ) -- NOT IMPLEMENTED YET!" << std::endl; 00889 bool bResult = false; 00890 //--------------------------------------------------------------- 00891 //--------------------------------------------------------------- 00892 return bResult; 00893 }
| bool CDR_PolygonalMesh_vs_MBV | ( | TAPs::OpenGL::HETriMeshOneModelMultiParts< T > * | pPolygonalMeshObj, | |
| TAPs::MultiBoundingVolume< T > const *const | pMBVObj, | |||
| TAPs::Vector3< T > * | totalForce, | |||
| T | gain | |||
| ) | [inline] |
| pPolygonalMeshObj | a HETriMeshOneModelMultiParts object |
| pMBVObj | a multi bounding volume object |
| totalForce | total force |
| gain | gain |
Definition at line 2321 of file TAPsColDetFns.cpp.
02327 { 02328 ListOfContactPts.clear(); 02329 ListOfForces.clear(); 02330 02331 #ifdef TAPs_DEBUG_COLLISION_DETECTION 02332 pPolygonalMeshObj->GetBVHTree()->ClearFlags(); 02333 #endif//TAPs_DEBUG_COLLISION_DETECTION 02334 02335 //#ifdef TAPs_DEBUG_MODE 02336 //std::cout << "CDR_PolygonalMesh_vs_MBV( HalfEdgeModel<T>, MultiBoundingVolume<T> )\n"; 02337 //#endif//TAPs_DEBUG_MODE 02338 02339 //std::cout << "BVHTree: " << *(pPolygonalMeshObj->GetBVHTree()) << "\n"; 02340 02341 bool bResult = false; 02342 02343 // Collision Detection 02344 bResult = pPolygonalMeshObj->GetBVHTree()->TestOverlapWithTillLeafNodes( pMBVObj ); 02345 // The statement above replaces the code below 02346 /* 02347 //--------------------------------------------------------------- 02348 // Traverse the list of bounding volumes 02349 std::vector< BoundingVolume<T> * >::iterator pos = const_cast< MultiBoundingVolume<T> * >( pMBVObj )->GetBoundingVolumeList().begin(); 02350 if ( pMBVObj->GetTransform().GetStatusApplyTransformation() ) { 02351 // The multi bounding volume's transformation is on. 02352 while ( pos != pMBVObj->GetBoundingVolumeList().end() ) { 02353 assert( *pos != NULL ); 02354 // Store the transformation of the bounding volume 02355 TransformationSupport<T> trx = (*pos)->GetTransform(); 02356 (*pos)->GetTransform().EnableStatusApplyTransformation(); 02357 (*pos)->GetTransform().SetMatrixTransform( pMBVObj->GetTransform().GetMatrixTransform() * trx.GetMatrixTransform() ); 02358 // Collision Detection 02359 bool result = pPolygonalMeshObj->GetBVHTree()->TestOverlapWithTillLeafNodes( *pos ); 02360 if ( result ) bResult = true; 02361 // Restore the transformation of the bounding volume 02362 (*pos)->GetTransform().SetMatrixTransform( trx.GetMatrixTransform() ); 02363 // Next Bounding Volume 02364 ++pos; 02365 } 02366 } 02367 else { 02368 // The multi bounding volume's transformation is off. 02369 while ( pos != pMBVObj->GetBoundingVolumeList().end() ) { 02370 assert( *pos != NULL ); 02371 // Collision Detection 02372 bool result = pPolygonalMeshObj->GetBVHTree()->TestOverlapWithTillLeafNodes( *pos ); 02373 if ( result ) bResult = true; 02374 // Next Bounding Volume 02375 ++pos; 02376 } 02377 } 02378 //*/ 02379 02380 //--------------------------------------------------------------- 02381 // Collision Response 02382 if ( bResult ) { 02383 02384 // Reset the result for primitive-primitive test, 02385 // because the previous result is only from bounding volume test. 02386 bResult = false; 02387 02388 //------------------------------------------------- 02389 //T separateDistanceConstraint; 02390 Vector3<T> N, centerA; 02391 //T separateDistance; 02392 HEFace<T> * primB; 02393 std::vector< HEVertex<T> * const > vertexList; 02394 int noOfVertices; 02395 //------------------------------------------------- 02396 TransformationSupport<T> trxMBV; // default constructor is an identity transformation 02397 02398 // If the multi bounding volume's transformation is on, set trx to it. 02399 if ( pMBVObj->GetTransform().GetStatusApplyTransformation() ) { 02400 trxMBV = pMBVObj->GetTransform(); 02401 } 02402 // Else, trx is an identity transformation. 02403 else { 02404 trxMBV.SetStatusApplyTransformation( true ); 02405 } 02406 //------------------------------------------------- 02407 std::set< BVHNode<T> * > defPolyMesh_NodeSet; 02408 02409 // Get the list of collided nodes and bounding volumes 02410 std::vector< BVsAndNodesList<T> > * bvList = &pPolygonalMeshObj->GetBVHTree()->GetListOfCollidedBoundingVolumesAndNodes(); 02411 //------------------------------------------------- 02412 // Traverse the list of bounding volumes 02413 std::vector< BVsAndNodesList<T> >::const_iterator pos = bvList->begin(); 02414 //------------------------------------------------- 02415 // CASE: the polygonal mesh object's transformation is off. 02416 if ( pPolygonalMeshObj->GetTransform().GetStatusApplyTransformation() == false ) { 02417 while ( pos != bvList->end() ) { 02418 02419 //int count = 0; 02420 02421 // Store the transformation of the bounding volume 02422 TransformationSupport<T> trx = (*pos).BV->GetTransform(); 02423 // Case: BV's transformation is on. 02424 if ( (*pos).BV->GetTransform().GetStatusApplyTransformation() ) { 02425 (*pos).BV->GetTransform().SetMatrixTransform( trxMBV.GetMatrixTransform() * trx.GetMatrixTransform() ); 02426 } 02427 // Case: BV's transformation is off. 02428 else { 02429 (*pos).BV->GetTransform().EnableStatusApplyTransformation(); 02430 (*pos).BV->GetTransform().SetMatrixTransform( trxMBV.GetMatrixTransform() ); 02431 } 02432 02433 //----------------------------------------- 02434 // Deform the deformable polygonal mesh away from the rigid polygonal mesh 02435 switch ( (*pos).BV->GetType() ) { 02436 02437 case TAPs::Enum::BOUNDING_SPHERE: 02438 { 02439 02440 //std::cout << "BV: " << (*pos).BV->GetName() << "\n"; 02441 02442 // For Test against triangle 02443 //--------------------------------------------- 02444 // Transform the BV due to its transformation, center, and radius 02445 02446 Vector3<T> centerOfBV( (*pos).BV->GetCenter() ); 02447 T radiusOfBV = (*pos).BV->GetRadius(); 02448 02449 Vector3<T> C( (*pos).BV->GetCenter() ); 02450 Matrix4x4<T> translation( 1, 0, 0, C[0], 02451 0, 1, 0, C[1], 02452 0, 0, 1, C[2], 02453 0, 0, 0, 1 ); 02454 Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV ); 02455 Matrix4x4<T> scale( S[0], 0, 0, 0, 02456 0, S[1], 0, 0, 02457 0, 0, S[2], 0, 02458 0, 0, 0, 1 ); 02459 Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale; 02460 02461 // BV Sphere's center and radius after the transformation 02462 centerOfBV = (mat * Vector4<T>(0,0,0,1)).GetVector3(); 02463 radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length(); 02464 //--------------------------------------------- 02465 02466 //count = 0; 02467 for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) { 02468 02469 bool testResult = false; 02470 02471 // Assume triangle is in Sphere Node 02472 // Test the triangle in sphere node with BVSphere 02473 primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace(); 02474 vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices ); 02475 Vector3<T> cdrVec[3]; 02476 02477 //* 02478 // Test against each vertex in the triangle 02479 //----------------------------------- 02480 for ( int j = 0; j < noOfVertices; ++j ) { 02481 if( (*pos).BV->TestPointLocation( &(vertexList[j]->GetPosition()), &(cdrVec[j]) ) ) 02482 { 02483 vertexList[j]->SetPosition( vertexList[j]->GetPosition() + cdrVec[j] ); 02484 02485 //ListOfContactPts.push_back( Vector3<GLfloat>( (*pos).BV->GetCenter()[0], (*pos).BV->GetCenter()[1], (*pos).BV->GetCenter()[2] ) ); 02486 ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) ); 02487 ListOfForces.push_back( Vector3<GLfloat>( cdrVec[j][0], cdrVec[j][1], cdrVec[j][2] ) ); 02488 02489 testResult = true; 02490 } 02491 } 02492 //----------------------------------- 02493 //*/ 02494 02495 //* 02496 // Test against triangle 02497 //----------------------------------- 02498 Vector3<T> contactPt; 02499 if ( TAPs::CGMath<T>::FindIntersectionSphereTriangle( 02500 centerOfBV, radiusOfBV, // BVSphere properties 02501 vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices 02502 cdrVec[0], cdrVec[1], cdrVec[2] // out vectors 02503 //, &contactPt 02504 ) ) { 02505 vertexList[0]->SetPosition( vertexList[0]->GetPosition() + cdrVec[0]*CDScaleForSphereBVWithTriangle ); 02506 vertexList[1]->SetPosition( vertexList[1]->GetPosition() + cdrVec[1]*CDScaleForSphereBVWithTriangle ); 02507 vertexList[2]->SetPosition( vertexList[2]->GetPosition() + cdrVec[2]*CDScaleForSphereBVWithTriangle ); 02508 02509 //ListOfContactPts.push_back( Vector3<GLfloat>( contactPt[0], contactPt[1], contactPt[2] ) ); 02510 ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) ); 02511 Vector3<T> force( (cdrVec[0] + cdrVec[1] + cdrVec[2] )/3 ); 02512 ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) ); 02513 02514 testResult = true; 02515 } 02516 //----------------------------------- 02517 //*/ 02518 02519 02520 //std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n"; 02521 02522 // List of BVNodes to be updated 02523 if ( testResult ) { 02524 defPolyMesh_NodeSet.insert( (*pos).NodeList[i] ); 02525 bResult = true; 02526 } 02527 } 02528 } 02529 break; 02530 02531 case TAPs::Enum::BOUNDING_CYLINDER: 02532 { 02533 //std::cout << "BV: " << (*pos).BV->GetName() << "\n"; 02534 02535 // For Test against triangle 02536 //--------------------------------------------- 02537 // Transform the BV due to its transformation, center, and radius 02538 02539 Vector3<T> centerOfBV( (*pos).BV->GetCenter() ); 02540 T halfHeightOfBV = (*pos).BV->GetHeight() / 2.0; 02541 //Vector3<T> topPtOfBV( centerOfBV[0], centerOfBV[1], centerOfBV[2] + halfHeightOfBV ); 02542 //Vector3<T> bottomPtOfBV( centerOfBV[0], centerOfBV[1], centerOfBV[2] - halfHeightOfBV ); 02543 T radiusOfBV = (*pos).BV->GetRadius(); 02544 02545 Vector3<T> C( (*pos).BV->GetCenter() ); 02546 Matrix4x4<T> translation( 1, 0, 0, C[0], 02547 0, 1, 0, C[1], 02548 0, 0, 1, C[2], 02549 0, 0, 0, 1 ); 02550 Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV ); 02551 Matrix4x4<T> scale( S[0], 0, 0, 0, 02552 0, S[1], 0, 0, 02553 0, 0, S[2], 0, 02554 0, 0, 0, 1 ); 02555 Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale; 02556 02557 // BV Sphere's center and radius after the transformation 02558 centerOfBV = (mat * Vector4<T>(0,0,0,1)).GetVector3(); 02559 Vector3<T> topPtOfBV( (mat * Vector4<T>(0,0,halfHeightOfBV,1)).GetVector3() ); 02560 Vector3<T> bottomPtOfBV( (mat * Vector4<T>(0,0,-halfHeightOfBV,1)).GetVector3() ); 02561 radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length(); 02562 //--------------------------------------------- 02563 02564 //count = 0; 02565 for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) { 02566 02567 bool testResult = false; 02568 02569 // Assume triangle is in Sphere Node 02570 // Test the triangle in sphere node with BVCylinder 02571 primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace(); 02572 vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices ); 02573 Vector3<T> cdrVec[3]; 02574 02575 //* 02576 // Test against each vertex in the triangle 02577 //----------------------------------- 02578 for ( int j = 0; j < noOfVertices; ++j ) { 02579 if( (*pos).BV->TestPointLocation( &(vertexList[j]->GetPosition()), &(cdrVec[j]) ) ) 02580 { 02581 vertexList[j]->SetPosition( vertexList[j]->GetPosition() + cdrVec[j] ); 02582 02583 //ListOfContactPts.push_back( Vector3<GLfloat>( (*pos).BV->GetCenter()[0], (*pos).BV->GetCenter()[1], (*pos).BV->GetCenter()[2] ) ); 02584 ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) ); 02585 ListOfForces.push_back( Vector3<GLfloat>( cdrVec[j][0], cdrVec[j][1], cdrVec[j][2] ) ); 02586 02587 testResult = true; 02588 } 02589 } 02590 //----------------------------------- 02591 //*/ 02592 02593 //* 02594 // Test against triangle 02595 //----------------------------------- 02596 Vector3<T> contactPt; 02597 if ( TAPs::CGMath<T>::FindIntersectionCylinderTriangle( 02598 topPtOfBV, bottomPtOfBV, radiusOfBV, // BVCylinder properties 02599 vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices 02600 cdrVec[0], cdrVec[1], cdrVec[2] // out vectors 02601 , &contactPt 02602 ) ) { 02603 vertexList[0]->SetPosition( vertexList[0]->GetPosition() + cdrVec[0]*CDScaleForCylinderBVWithTriangle ); 02604 vertexList[1]->SetPosition( vertexList[1]->GetPosition() + cdrVec[1]*CDScaleForCylinderBVWithTriangle ); 02605 vertexList[2]->SetPosition( vertexList[2]->GetPosition() + cdrVec[2]*CDScaleForCylinderBVWithTriangle ); 02606 02607 ListOfContactPts.push_back( Vector3<GLfloat>( contactPt[0], contactPt[1], contactPt[2] ) ); 02608 Vector3<T> force( (cdrVec[0] + cdrVec[1] + cdrVec[2] )/3 ); 02609 ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) ); 02610 02611 testResult = true; 02612 } 02613 //----------------------------------- 02614 //*/ 02615 02616 //std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n"; 02617 02618 // List of BVNodes to be updated 02619 if ( testResult ) { 02620 defPolyMesh_NodeSet.insert( (*pos).NodeList[i] ); 02621 bResult = true; 02622 } 02623 } 02624 } 02625 break; 02626 02627 default: 02628 std::cout << "CDR_PolygonalMesh_vs_MBV of BV Type (" << (*pos).BV->GetType() << ") doesn't support!\n"; 02629 break; 02630 } 02631 02632 // Restore the transformation of the bounding volume 02633 //(*pos).BV->GetTransform().SetMatrixTransform( trx.GetMatrixTransform() ); 02634 (*pos).BV->SetTransform( trx ); 02635 // Next Bounding Volume 02636 ++pos; 02637 } 02638 } // END CASE: the polygonal mesh object's transformation is off. 02639 02640 //------------------------------------------------- 02641 // CASE: the polygonal mesh object's transformation is on. 02642 else { 02643 //std::cout << "CDR_PolygonalMesh_vs_MBV(...) for HETriMeshOneModelMultiParts --> \n"; 02644 //std::cout << "\tCASE: the polygonal mesh object's transformation is on. -- NOT IMPLEMENTED YET!\n"; 02645 02646 // Mesh's inverse transformation 02647 Matrix4x4<T> trxInvMesh = pPolygonalMeshObj->GetTransform().GetMatrixTransform(); 02648 trxInvMesh.Inversed(); 02649 Vector3<T> vOrigin( (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(0,0,0,1)).GetVector3() ); 02650 02651 while ( pos != bvList->end() ) { 02652 02653 //int count = 0; 02654 02655 // Store the transformation of the bounding volume including the mesh's inverse transformation 02656 TransformationSupport<T> trx = (*pos).BV->GetTransform(); 02657 // Case: BV's transformation is on. 02658 if ( (*pos).BV->GetTransform().GetStatusApplyTransformation() ) { 02659 (*pos).BV->GetTransform().SetMatrixTransform( trxInvMesh * trxMBV.GetMatrixTransform() * trx.GetMatrixTransform() ); 02660 } 02661 // Case: BV's transformation is off. 02662 else { 02663 (*pos).BV->GetTransform().EnableStatusApplyTransformation(); 02664 (*pos).BV->GetTransform().SetMatrixTransform( trxInvMesh * trxMBV.GetMatrixTransform() ); 02665 } 02666 02667 //----------------------------------------- 02668 // Deform the deformable polygonal mesh away from the rigid polygonal mesh 02669 switch ( (*pos).BV->GetType() ) { 02670 02671 case TAPs::Enum::BOUNDING_SPHERE: 02672 { 02673 02674 //std::cout << "BV: " << (*pos).BV->GetName() << "\n"; 02675 02676 // For Test against triangle 02677 //--------------------------------------------- 02678 // Transform the BV due to its transformation, center, and radius 02679 T radiusOfBV = (*pos).BV->GetRadius(); 02680 Vector3<T> C( (*pos).BV->GetCenter() ); 02681 Matrix4x4<T> translation( 1, 0, 0, C[0], 02682 0, 1, 0, C[1], 02683 0, 0, 1, C[2], 02684 0, 0, 0, 1 ); 02685 Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV ); 02686 Matrix4x4<T> scale( S[0], 0, 0, 0, 02687 0, S[1], 0, 0, 02688 0, 0, S[2], 0, 02689 0, 0, 0, 1 ); 02690 // The BV's current transformation includes the mesh's inverse transformation (see the code above) 02691 Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale; 02692 02693 // BV Sphere's center and radius after the whole transformation from 02694 // BV's transformation to mesh's inverse transformation. 02695 // I.e., transforming the BV to mesh's coordinate 02696 Vector3<T> centerOfBV_inMeshCoord = (mat * Vector4<T>(0,0,0,1)).GetVector3(); 02697 T radiusOfBV_inMeshCoord = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV_inMeshCoord ).Length(); 02698 02699 // Inverse the mesh's transformation to the BV's pure transformation 02700 mat = pPolygonalMeshObj->GetTransform().GetMatrixTransform() * mat; 02701 02702 // BV Sphere's center and radius after the BV's pure transformation 02703 Vector3<T> centerOfBV( (mat * Vector4<T>(0,0,0,1)).GetVector3() ); 02704 radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length(); 02705 //--------------------------------------------- 02706 02707 //count = 0; 02708 for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) { 02709 02710 bool testResult = false; 02711 02712 // Assume triangle is in Sphere Node 02713 // Test the triangle in sphere node with BVSphere 02714 primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace(); 02715 vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices ); 02716 Vector3<T> cdrVec[3]; 02717 02718 //* 02719 // Test against each vertex in the triangle 02720 //----------------------------------- 02721 for ( int j = 0; j < noOfVertices; ++j ) { 02722 if( (*pos).BV->TestPointLocation( &(vertexList[j]->GetPosition()), &(cdrVec[j]) ) ) 02723 { 02724 vertexList[j]->SetPosition( vertexList[j]->GetPosition() + cdrVec[j] ); 02725 Vector3<T> force( (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(cdrVec[j])).GetVector3() - vOrigin ); 02726 02727 //ListOfContactPts.push_back( Vector3<GLfloat>( (*pos).BV->GetCenter()[0], (*pos).BV->GetCenter()[1], (*pos).BV->GetCenter()[2] ) ); 02728 ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) ); 02729 ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) ); 02730 02731 testResult = true; 02732 } 02733 } 02734 //----------------------------------- 02735 //*/ 02736 02737 //* 02738 // Test against triangle 02739 //----------------------------------- 02740 //Vector3<T> contactPt; 02741 if ( TAPs::CGMath<T>::FindIntersectionSphereTriangle( 02742 centerOfBV_inMeshCoord, radiusOfBV_inMeshCoord, // BVSphere properties 02743 vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices 02744 cdrVec[0], cdrVec[1], cdrVec[2] // out vectors 02745 //, &contactPt 02746 ) ) { 02747 Vector3<T> force_1( cdrVec[0] * CDScaleForSphereBVWithTriangle ); 02748 Vector3<T> force_2( cdrVec[1] * CDScaleForSphereBVWithTriangle ); 02749 Vector3<T> force_3( cdrVec[2] * CDScaleForSphereBVWithTriangle ); 02750 02751 vertexList[0]->SetPosition( vertexList[0]->GetPosition() + force_1 ); 02752 vertexList[1]->SetPosition( vertexList[1]->GetPosition() + force_2 ); 02753 vertexList[2]->SetPosition( vertexList[2]->GetPosition() + force_3 ); 02754 02755 force_1 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_1)).GetVector3() - vOrigin; 02756 force_2 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_2)).GetVector3() - vOrigin; 02757 force_3 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_3)).GetVector3() - vOrigin; 02758 02759 //ListOfContactPts.push_back( Vector3<GLfloat>( contactPt[0], contactPt[1], contactPt[2] ) ); 02760 ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) ); 02761 Vector3<T> force( ( force_1 + force_2 + force_3 )/3 ); 02762 ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) ); 02763 02764 testResult = true; 02765 } 02766 //----------------------------------- 02767 //*/ 02768 02769 02770 //std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n"; 02771 02772 // List of BVNodes to be updated 02773 if ( testResult ) { 02774 defPolyMesh_NodeSet.insert( (*pos).NodeList[i] ); 02775 bResult = true; 02776 } 02777 } 02778 } 02779 break; 02780 02781 case TAPs::Enum::BOUNDING_CYLINDER: 02782 { 02783 //std::cout << "BV: " << (*pos).BV->GetName() << "\n"; 02784 02785 // For Test against triangle 02786 //--------------------------------------------- 02787 // Transform the BV due to its transformation, center, and radius 02788 T radiusOfBV = (*pos).BV->GetRadius(); 02789 Vector3<T> C( (*pos).BV->GetCenter() ); 02790 Matrix4x4<T> translation( 1, 0, 0, C[0], 02791 0, 1, 0, C[1], 02792 0, 0, 1, C[2], 02793 0, 0, 0, 1 ); 02794 Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV ); 02795 Matrix4x4<T> scale( S[0], 0, 0, 0, 02796 0, S[1], 0, 0, 02797 0, 0, S[2], 0, 02798 0, 0, 0, 1 ); 02799 // The BV's current transformation includes the mesh's inverse transformation (see the code above) 02800 Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale; 02801 02802 // BV Sphere's center and radius after the whole transformation from 02803 // BV's transformation to mesh's inverse transformation. 02804 // I.e., transforming the BV to mesh's coordinate 02805 T halfHeightOfBV = (*pos).BV->GetHeight() / 2.0; 02806 Vector3<T> centerOfBV_inMeshCoord = (mat * Vector4<T>(0,0,0,1)).GetVector3(); 02807 T radiusOfBV_inMeshCoord = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV_inMeshCoord ).Length(); 02808 Vector3<T> topPtOfBV_inMeshCoord( (mat * Vector4<T>(0,0,halfHeightOfBV,1)).GetVector3() ); 02809 Vector3<T> bottomPtOfBV_inMeshCoord( (mat * Vector4<T>(0,0,-halfHeightOfBV,1)).GetVector3() ); 02810 02811 // Inverse the mesh's transformation to the BV's pure transformation 02812 mat = pPolygonalMeshObj->GetTransform().GetMatrixTransform() * mat; 02813 02814 // BV Sphere's center and radius after the BV's pure transformation 02815 Vector3<T> centerOfBV( (mat * Vector4<T>(0,0,0,1)).GetVector3() ); 02816 radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length(); 02817 Vector3<T> topPtOfBV( (mat * Vector4<T>(0,0,halfHeightOfBV,1)).GetVector3() ); 02818 Vector3<T> bottomPtOfBV( (mat * Vector4<T>(0,0,-halfHeightOfBV,1)).GetVector3() ); 02819 //--------------------------------------------- 02820 02821 //count = 0; 02822 for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) { 02823 02824 bool testResult = false; 02825 02826 // Assume triangle is in Sphere Node 02827 // Test the triangle in sphere node with BVCylinder 02828 primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace(); 02829 vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices ); 02830 Vector3<T> cdrVec[3]; 02831 02832 //* 02833 // Test against each vertex in the triangle 02834 //----------------------------------- 02835 for ( int j = 0; j < noOfVertices; ++j ) { 02836 if( (*pos).BV->TestPointLocation( &(vertexList[j]->GetPosition()), &(cdrVec[j]) ) ) 02837 { 02838 vertexList[j]->SetPosition( vertexList[j]->GetPosition() + cdrVec[j] ); 02839 Vector3<T> force( (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(cdrVec[j])).GetVector3() - vOrigin ); 02840 02841 //ListOfContactPts.push_back( Vector3<GLfloat>( (*pos).BV->GetCenter()[0], (*pos).BV->GetCenter()[1], (*pos).BV->GetCenter()[2] ) ); 02842 ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) ); 02843 ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) ); 02844 02845 testResult = true; 02846 } 02847 } 02848 //----------------------------------- 02849 //*/ 02850 02851 //* 02852 // Test against triangle 02853 //----------------------------------- 02854 Vector3<T> contactPt; 02855 if ( TAPs::CGMath<T>::FindIntersectionCylinderTriangle( 02856 topPtOfBV_inMeshCoord, bottomPtOfBV_inMeshCoord, radiusOfBV_inMeshCoord, // BVCylinder properties 02857 vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices 02858 cdrVec[0], cdrVec[1], cdrVec[2] // out vectors 02859 , &contactPt 02860 ) ) { 02861 Vector3<T> force_1( cdrVec[0] * CDScaleForSphereBVWithTriangle ); 02862 Vector3<T> force_2( cdrVec[1] * CDScaleForSphereBVWithTriangle ); 02863 Vector3<T> force_3( cdrVec[2] * CDScaleForSphereBVWithTriangle ); 02864 02865 vertexList[0]->SetPosition( vertexList[0]->GetPosition() + force_1 ); 02866 vertexList[1]->SetPosition( vertexList[1]->GetPosition() + force_2 ); 02867 vertexList[2]->SetPosition( vertexList[2]->GetPosition() + force_3 ); 02868 02869 force_1 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_1)).GetVector3() - vOrigin; 02870 force_2 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_2)).GetVector3() - vOrigin; 02871 force_3 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_3)).GetVector3() - vOrigin; 02872 02873 contactPt = ( (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(contactPt)).GetVector3() ); 02874 02875 ListOfContactPts.push_back( Vector3<GLfloat>( contactPt[0], contactPt[1], contactPt[2] ) ); 02876 Vector3<T> force( ( force_1 + force_2 + force_3 )/3 ); 02877 ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) ); 02878 02879 testResult = true; 02880 } 02881 //----------------------------------- 02882 //*/ 02883 02884 //std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n"; 02885 02886 // List of BVNodes to be updated 02887 if ( testResult ) { 02888 defPolyMesh_NodeSet.insert( (*pos).NodeList[i] ); 02889 bResult = true; 02890 } 02891 } 02892 } 02893 break; 02894 02895 default: 02896 std::cout << "CDR_PolygonalMesh_vs_MBV of BV Type (" << (*pos).BV->GetType() << ") doesn't support!\n"; 02897 break; 02898 } 02899 02900 // Restore the transformation of the bounding volume 02901 //(*pos).BV->GetTransform().SetMatrixTransform( trx.GetMatrixTransform() ); 02902 (*pos).BV->SetTransform( trx ); 02903 // Next Bounding Volume 02904 ++pos; 02905 } 02906 } // END CASE: the polygonal mesh object's transformation is on. 02907 //------------------------------------------------- 02908 02909 //------------------------------------------------- 02910 // Update Normals of Deformable Polygonal Mesh 02911 //pPolygonalMeshObj->CalAndSetNormals(); // commented out to rely on AdvanceSimulation to update the normals 02912 //------------------------------------------------- 02913 // Update Bounding Volume Hierarchy of Deformable Polygonal Mesh 02914 pPolygonalMeshObj->GetBVHTree()->Update( defPolyMesh_NodeSet ); 02915 // FOR HETriMeshOneModelMultiParts 02916 //------------------------------------------------- 02917 // Update for the model's internal simulation 02918 for ( int i = 0; i < static_cast<int>( pPolygonalMeshObj->GetListOfParts().size() ); ++i ) { 02919 pPolygonalMeshObj->GetPtrToPartNo(i)->UpdateStateToArray(); 02920 } 02921 } 02922 //--------------------------------------------------------------- 02923 if ( totalForce ) { 02924 totalForce->SetXYZ( 0, 0, 0 ); 02925 Vector3<float> force( 0, 0, 0 ); 02926 for ( int i = 0; i < static_cast<int>( ListOfForces.size() ); ++i ) { 02927 force += ListOfForces[i]; 02928 } 02929 force *= gain; 02930 (*totalForce).SetXYZ( force[0], force[1], force[2] ); 02931 } 02932 02933 return bResult; 02934 }
| bool CDR_PolygonalMesh_vs_MBV | ( | TAPs::OpenGL::HalfEdgeModel< T > * | pPolygonalMeshObj, | |
| TAPs::MultiBoundingVolume< T > const *const | pMBVObj | |||
| ) | [inline] |
| pPolygonalMeshObj | a HalfEdgeModel object |
| pMBVObj | a multi bounding volume object |
Definition at line 1785 of file TAPsColDetFns.cpp.
01789 { 01790 #ifdef TAPs_DEBUG_COLLISION_DETECTION 01791 pPolygonalMeshObj->GetBVHTree()->ClearFlags(); 01792 #endif//TAPs_DEBUG_COLLISION_DETECTION 01793 01794 //#ifdef TAPs_DEBUG_MODE 01795 std::cout << "CDR_PolygonalMesh_vs_MBV( HalfEdgeModel<T>, MultiBoundingVolume<T> )\n"; 01796 //#endif//TAPs_DEBUG_MODE 01797 01798 std::cout << "BVHTree: " << *(pPolygonalMeshObj->GetBVHTree()) << "\n"; 01799 01800 bool bResult = false; 01801 01802 // Collision Detection 01803 bResult = pPolygonalMeshObj->GetBVHTree()->TestOverlapWithTillLeafNodes( pMBVObj ); 01804 // The statement above replaces the code below 01805 /* 01806 //--------------------------------------------------------------- 01807 // Traverse the list of bounding volumes 01808 std::vector< BoundingVolume<T> * >::iterator pos = const_cast< MultiBoundingVolume<T> * >( pMBVObj )->GetBoundingVolumeList().begin(); 01809 if ( pMBVObj->GetTransform().GetStatusApplyTransformation() ) { 01810 // The multi bounding volume's transformation is on. 01811 while ( pos != pMBVObj->GetBoundingVolumeList().end() ) { 01812 assert( *pos != NULL ); 01813 // Store the transformation of the bounding volume 01814 TransformationSupport<T> trx = (*pos)->GetTransform(); 01815 (*pos)->GetTransform().EnableStatusApplyTransformation(); 01816 (*pos)->GetTransform().SetMatrixTransform( pMBVObj->GetTransform().GetMatrixTransform() * trx.GetMatrixTransform() ); 01817 // Collision Detection 01818 bool result = pPolygonalMeshObj->GetBVHTree()->TestOverlapWithTillLeafNodes( *pos ); 01819 if ( result ) bResult = true; 01820 // Restore the transformation of the bounding volume 01821 (*pos)->GetTransform().SetMatrixTransform( trx.GetMatrixTransform() ); 01822 // Next Bounding Volume 01823 ++pos; 01824 } 01825 } 01826 else { 01827 // The multi bounding volume's transformation is off. 01828 while ( pos != pMBVObj->GetBoundingVolumeList().end() ) { 01829 assert( *pos != NULL ); 01830 // Collision Detection 01831 bool result = pPolygonalMeshObj->GetBVHTree()->TestOverlapWithTillLeafNodes( *pos ); 01832 if ( result ) bResult = true; 01833 // Next Bounding Volume 01834 ++pos; 01835 } 01836 } 01837 //*/ 01838 01839 //--------------------------------------------------------------- 01840 // Collision Response 01841 if ( bResult ) { 01842 01843 // Reset the result for primitive-primitive test, 01844 // because the previous result is only from bounding volume test. 01845 bResult = false; 01846 01847 //------------------------------------------------- 01848 T separateDistanceConstraint; 01849 Vector3<T> N, centerA; 01850 T separateDistance; 01851 HEFace<T> * primB; 01852 std::vector< HEVertex<T> * const > vertexList; 01853 int noOfVertices; 01854 //------------------------------------------------- 01855 TransformationSupport<T> trxMBV; // default constructor is an identity transformation 01856 01857 // If the multi bounding volume's transformation is on, set trx to it. 01858 if ( pMBVObj->GetTransform().GetStatusApplyTransformation() ) { 01859 trxMBV = pMBVObj->GetTransform(); 01860 } 01861 // Else, trx is an identity transformation. 01862 else { 01863 trxMBV.SetStatusApplyTransformation( true ); 01864 } 01865 //------------------------------------------------- 01866 std::set< BVHNode<T> * > defPolyMesh_NodeSet; 01867 01868 // Get the list of collided nodes and bounding volumes 01869 std::vector< BVsAndNodesList<T> > * bvList = &pPolygonalMeshObj->GetBVHTree()->GetListOfCollidedBoundingVolumesAndNodes(); 01870 //------------------------------------------------- 01871 // Traverse the list of bounding volumes 01872 std::vector< BVsAndNodesList<T> >::const_iterator pos = bvList->begin(); 01873 //------------------------------------------------- 01874 // CASE: the polygonal mesh object's transformation is off. 01875 if ( pPolygonalMeshObj->GetTransform().GetStatusApplyTransformation() == false ) { 01876 while ( pos != bvList->end() ) { 01877 01878 int count = 0; 01879 01880 // Store the transformation of the bounding volume 01881 TransformationSupport<T> trx = (*pos).BV->GetTransform(); 01882 // Case: BV's transformation is on. 01883 if ( (*pos).BV->GetTransform().GetStatusApplyTransformation() ) { 01884 (*pos).BV->GetTransform().SetMatrixTransform( trxMBV.GetMatrixTransform() * trx.GetMatrixTransform() ); 01885 } 01886 // Case: BV's transformation is off. 01887 else { 01888 (*pos).BV->GetTransform().EnableStatusApplyTransformation(); 01889 (*pos).BV->GetTransform().SetMatrixTransform( trxMBV.GetMatrixTransform() ); 01890 } 01891 01892 //----------------------------------------- 01893 // Deform the deformable polygonal mesh away from the rigid polygonal mesh 01894 switch ( (*pos).BV->GetType() ) { 01895 01896 case TAPs::Enum::BOUNDING_SPHERE: 01897 { 01898 01899 std::cout << "BV: " << (*pos).BV->GetName() << "\n"; 01900 01901 // For Test against triangle 01902 //--------------------------------------------- 01903 // Transform the BV due to its transformation, center, and radius 01904 01905 Vector3<T> centerOfBV( (*pos).BV->GetCenter() ); 01906 T radiusOfBV = (*pos).BV->GetRadius(); 01907 01908 Vector3<T> C( (*pos).BV->GetCenter() ); 01909 Matrix4x4<T> translation( 1, 0, 0, C[0], 01910 0, 1, 0, C[1], 01911 0, 0, 1, C[2], 01912 0, 0, 0, 1 ); 01913 Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV ); 01914 Matrix4x4<T> scale( S[0], 0, 0, 0, 01915 0, S[1], 0, 0, 01916 0, 0, S[2], 0, 01917 0, 0, 0, 1 ); 01918 Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale; 01919 01920 // BV Sphere's center and radius after the transformation 01921 centerOfBV = (mat * Vector4<T>(0,0,0,1)).GetVector3(); 01922 radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length(); 01923 //--------------------------------------------- 01924 01925 count = 0; 01926 for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) { 01927 01928 bool testResult = false; 01929 01930 // Assume triangle is in Sphere Node 01931 // Test the triangle in sphere node with BVSphere 01932 primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace(); 01933 vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices ); 01934 Vector3<T> cdrVec[3]; 01935 01936 //* 01937 // Test against each vertex in the triangle 01938 //----------------------------------- 01939 for ( int j = 0; j < noOfVertices; ++j ) { 01940 if( (*pos).BV->TestPointLocation( &(vertexList[j]->GetPosition()), &(cdrVec[j]) ) ) 01941 { 01942 vertexList[j]->SetPosition( vertexList[j]->GetPosition() + cdrVec[j] ); 01943 01944 testResult = true; 01945 } 01946 } 01947 //----------------------------------- 01948 //*/ 01949 01950 //* 01951 // Test against triangle 01952 //----------------------------------- 01953 if ( TAPs::CGMath<T>::FindIntersectionSphereTriangle( 01954 centerOfBV, radiusOfBV, // BVSphere properties 01955 vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices 01956 cdrVec[0], cdrVec[1], cdrVec[2] // out vectors 01957 ) ) { 01958 vertexList[0]->SetPosition( vertexList[0]->GetPosition() + cdrVec[0]*CDScaleForSphereBVWithTriangle ); 01959 vertexList[1]->SetPosition( vertexList[1]->GetPosition() + cdrVec[1]*CDScaleForSphereBVWithTriangle ); 01960 vertexList[2]->SetPosition( vertexList[2]->GetPosition() + cdrVec[2]*CDScaleForSphereBVWithTriangle ); 01961 01962 testResult = true; 01963 } 01964 //----------------------------------- 01965 //*/ 01966 01967 01968 std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n"; 01969 01970 // List of BVNodes to be updated 01971 if ( testResult ) { 01972 defPolyMesh_NodeSet.insert( (*pos).NodeList[i] ); 01973 bResult = true; 01974 } 01975 } 01976 } 01977 break; 01978 01979 case TAPs::Enum::BOUNDING_CYLINDER: 01980 { 01981 std::cout << "BV: " << (*pos).BV->GetName() << "\n"; 01982 01983 // For Test against triangle 01984 //--------------------------------------------- 01985 // Transform the BV due to its transformation, center, and radius 01986 01987 Vector3<T> centerOfBV( (*pos).BV->GetCenter() ); 01988 T halfHeightOfBV = (*pos).BV->GetHeight() / 2.0; 01989 //Vector3<T> topPtOfBV( centerOfBV[0], centerOfBV[1], centerOfBV[2] + halfHeightOfBV ); 01990 //Vector3<T> bottomPtOfBV( centerOfBV[0], centerOfBV[1], centerOfBV[2] - halfHeightOfBV ); 01991 T radiusOfBV = (*pos).BV->GetRadius(); 01992 01993 Vector3<T> C( (*pos).BV->GetCenter() ); 01994 Matrix4x4<T> translation( 1, 0, 0, C[0], 01995 0, 1, 0, C[1], 01996 0, 0, 1, C[2], 01997 0, 0, 0, 1 ); 01998 Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV ); 01999 Matrix4x4<T> scale( S[0], 0, 0, 0, 02000 0, S[1], 0, 0, 02001 0, 0, S[2], 0, 02002 0, 0, 0, 1 ); 02003 Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale; 02004 02005 // BV Sphere's center and radius after the transformation 02006 centerOfBV = (mat * Vector4<T>(0,0,0,1)).GetVector3(); 02007 Vector3<T> topPtOfBV( (mat * Vector4<T>(0,0,halfHeightOfBV,1)).GetVector3() ); 02008 Vector3<T> bottomPtOfBV( (mat * Vector4<T>(0,0,-halfHeightOfBV,1)).GetVector3() ); 02009 radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length(); 02010 //--------------------------------------------- 02011 02012 count = 0; 02013 for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) { 02014 02015 bool testResult = false; 02016 02017 // Assume triangle is in Sphere Node 02018 // Test the triangle in sphere node with BVCylinder 02019 primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace(); 02020 vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices ); 02021 Vector3<T> cdrVec[3]; 02022 02023 //* 02024 // Test against each vertex in the triangle 02025 //----------------------------------- 02026 for ( int j = 0; j < noOfVertices; ++j ) { 02027 if( (*pos).BV->TestPointLocation( &(vertexList[j]->GetPosition()), &(cdrVec[j]) ) ) 02028 { 02029 vertexList[j]->SetPosition( vertexList[j]->GetPosition() + cdrVec[j] ); 02030 02031 testResult = true; 02032 } 02033 } 02034 //----------------------------------- 02035 //*/ 02036 02037 //* 02038 // Test against triangle 02039 //----------------------------------- 02040 if ( TAPs::CGMath<T>::FindIntersectionCylinderTriangle( 02041 topPtOfBV, bottomPtOfBV, radiusOfBV, // BVCylinder properties 02042 vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices 02043 cdrVec[0], cdrVec[1], cdrVec[2] // out vectors 02044 ) ) { 02045 vertexList[0]->SetPosition( vertexList[0]->GetPosition() + cdrVec[0]*CDScaleForCylinderBVWithTriangle ); 02046 vertexList[1]->SetPosition( vertexList[1]->GetPosition() + cdrVec[1]*CDScaleForCylinderBVWithTriangle ); 02047 vertexList[2]->SetPosition( vertexList[2]->GetPosition() + cdrVec[2]*CDScaleForCylinderBVWithTriangle ); 02048 02049 testResult = true; 02050 } 02051 //----------------------------------- 02052 //*/ 02053 02054 std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n"; 02055 02056 // List of BVNodes to be updated 02057 if ( testResult ) { 02058 defPolyMesh_NodeSet.insert( (*pos).NodeList[i] ); 02059 bResult = true; 02060 } 02061 } 02062 } 02063 break; 02064 02065 default: 02066 std::cout << "CDR_PolygonalMesh_vs_MBV of BV Type (" << (*pos).BV->GetType() << ") doesn't support!\n"; 02067 break; 02068 } 02069 02070 // Restore the transformation of the bounding volume 02071 //(*pos).BV->GetTransform().SetMatrixTransform( trx.GetMatrixTransform() ); 02072 (*pos).BV->SetTransform( trx ); 02073 // Next Bounding Volume 02074 ++pos; 02075 } 02076 } // END CASE: the polygonal mesh object's transformation is off. 02077 02078 //------------------------------------------------- 02079 // CASE: the polygonal mesh object's transformation is on. 02080 else { 02081 //std::cout << "CDR_PolygonalMesh_vs_MBV(...) for HalfEdgeModel --> \n"; 02082 //std::cout << "\tCASE: the polygonal mesh object's transformation is on. -- NOT IMPLEMENTED YET!\n"; 02083 02084 // Mesh's inverse transformation 02085 Matrix4x4<T> trxInvMesh = pPolygonalMeshObj->GetTransform().GetMatrixTransform(); 02086 trxInvMesh.Inversed(); 02087 02088 while ( pos != bvList->end() ) { 02089 02090 int count = 0; 02091 02092 // Store the transformation of the bounding volume including the mesh's inverse transformation 02093 TransformationSupport<T> trx = (*pos).BV->GetTransform(); 02094 // Case: BV's transformation is on. 02095 if ( (*pos).BV->GetTransform().GetStatusApplyTransformation() ) { 02096 (*pos).BV->GetTransform().SetMatrixTransform( trxInvMesh * trxMBV.GetMatrixTransform() * trx.GetMatrixTransform() ); 02097 } 02098 // Case: BV's transformation is off. 02099 else { 02100 (*pos).BV->GetTransform().EnableStatusApplyTransformation(); 02101 (*pos).BV->GetTransform().SetMatrixTransform( trxInvMesh * trxMBV.GetMatrixTransform() ); 02102 } 02103 02104 //----------------------------------------- 02105 // Deform the deformable polygonal mesh away from the rigid polygonal mesh 02106 switch ( (*pos).BV->GetType() ) { 02107 02108 case TAPs::Enum::BOUNDING_SPHERE: 02109 { 02110 02111 std::cout << "BV: " << (*pos).BV->GetName() << "\n"; 02112 02113 // For Test against triangle 02114 //--------------------------------------------- 02115 // Transform the BV due to its transformation, center, and radius 02116 T radiusOfBV = (*pos).BV->GetRadius(); 02117 Vector3<T> C( (*pos).BV->GetCenter() ); 02118 Matrix4x4<T> translation( 1, 0, 0, C[0], 02119 0, 1, 0, C[1], 02120 0, 0, 1, C[2], 02121 0, 0, 0, 1 ); 02122 Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV ); 02123 Matrix4x4<T> scale( S[0], 0, 0, 0, 02124 0, S[1], 0, 0, 02125 0, 0, S[2], 0, 02126 0, 0, 0, 1 ); 02127 // The BV's current transformation includes the mesh's inverse transformation (see the code above) 02128 Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale; 02129 02130 // BV Sphere's center and radius after the whole transformation from 02131 // BV's transformation to mesh's inverse transformation. 02132 // I.e., transforming the BV to mesh's coordinate 02133 Vector3<T> centerOfBV_inMeshCoord = (mat * Vector4<T>(0,0,0,1)).GetVector3(); 02134 T radiusOfBV_inMeshCoord = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV_inMeshCoord ).Length(); 02135 02136 // Inverse the mesh's transformation to the BV's pure transformation 02137 mat = pPolygonalMeshObj->GetTransform().GetMatrixTransform() * mat; 02138 02139 // BV Sphere's center and radius after the BV's pure transformation 02140 Vector3<T> centerOfBV( (mat * Vector4<T>(0,0,0,1)).GetVector3() ); 02141 radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length(); 02142 //--------------------------------------------- 02143 02144 count = 0; 02145 for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) { 02146 02147 bool testResult = false; 02148 02149 // Assume triangle is in Sphere Node 02150 // Test the triangle in sphere node with BVSphere 02151 primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace(); 02152 vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices ); 02153 Vector3<T> cdrVec[3]; 02154 02155 //* 02156 // Test against each vertex in the triangle 02157 //----------------------------------- 02158 for ( int j = 0; j < noOfVertices; ++j ) { 02159 if( (*pos).BV->TestPointLocation( &(vertexList[j]->GetPosition()), &(cdrVec[j]) ) ) 02160 { 02161 vertexList[j]->SetPosition( vertexList[j]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[j])).GetVector3() ); 02162 02163 testResult = true; 02164 } 02165 } 02166 //----------------------------------- 02167 //*/ 02168 02169 //* 02170 // Test against triangle 02171 //----------------------------------- 02172 //Vector3<T> contactPt; 02173 if ( TAPs::CGMath<T>::FindIntersectionSphereTriangle( 02174 centerOfBV_inMeshCoord, radiusOfBV_inMeshCoord, // BVSphere properties 02175 vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices 02176 cdrVec[0], cdrVec[1], cdrVec[2] // out vectors 02177 //, &contactPt 02178 ) ) { 02179 vertexList[0]->SetPosition( vertexList[0]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[0])).GetVector3()*CDScaleForSphereBVWithTriangle ); 02180 vertexList[1]->SetPosition( vertexList[1]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[1])).GetVector3()*CDScaleForSphereBVWithTriangle ); 02181 vertexList[2]->SetPosition( vertexList[2]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[2])).GetVector3()*CDScaleForSphereBVWithTriangle ); 02182 02183 testResult = true; 02184 } 02185 //----------------------------------- 02186 //*/ 02187 02188 02189 std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n"; 02190 02191 // List of BVNodes to be updated 02192 if ( testResult ) { 02193 defPolyMesh_NodeSet.insert( (*pos).NodeList[i] ); 02194 bResult = true; 02195 } 02196 } 02197 } 02198 break; 02199 02200 case TAPs::Enum::BOUNDING_CYLINDER: 02201 { 02202 std::cout << "BV: " << (*pos).BV->GetName() << "\n"; 02203 02204 // For Test against triangle 02205 //--------------------------------------------- 02206 // Transform the BV due to its transformation, center, and radius 02207 T radiusOfBV = (*pos).BV->GetRadius(); 02208 Vector3<T> C( (*pos).BV->GetCenter() ); 02209 Matrix4x4<T> translation( 1, 0, 0, C[0], 02210 0, 1, 0, C[1], 02211 0, 0, 1, C[2], 02212 0, 0, 0, 1 ); 02213 Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV ); 02214 Matrix4x4<T> scale( S[0], 0, 0, 0, 02215 0, S[1], 0, 0, 02216 0, 0, S[2], 0, 02217 0, 0, 0, 1 ); 02218 // The BV's current transformation includes the mesh's inverse transformation (see the code above) 02219 Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale; 02220 02221 // BV Sphere's center and radius after the whole transformation from 02222 // BV's transformation to mesh's inverse transformation. 02223 // I.e., transforming the BV to mesh's coordinate 02224 T halfHeightOfBV = (*pos).BV->GetHeight() / 2.0; 02225 Vector3<T> centerOfBV_inMeshCoord = (mat * Vector4<T>(0,0,0,1)).GetVector3(); 02226 T radiusOfBV_inMeshCoord = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV_inMeshCoord ).Length(); 02227 Vector3<T> topPtOfBV_inMeshCoord( (mat * Vector4<T>(0,0,halfHeightOfBV,1)).GetVector3() ); 02228 Vector3<T> bottomPtOfBV_inMeshCoord( (mat * Vector4<T>(0,0,-halfHeightOfBV,1)).GetVector3() ); 02229 02230 // Inverse the mesh's transformation to the BV's pure transformation 02231 mat = pPolygonalMeshObj->GetTransform().GetMatrixTransform() * mat; 02232 02233 // BV Sphere's center and radius after the BV's pure transformation 02234 Vector3<T> centerOfBV( (mat * Vector4<T>(0,0,0,1)).GetVector3() ); 02235 radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length(); 02236 Vector3<T> topPtOfBV( (mat * Vector4<T>(0,0,halfHeightOfBV,1)).GetVector3() ); 02237 Vector3<T> bottomPtOfBV( (mat * Vector4<T>(0,0,-halfHeightOfBV,1)).GetVector3() ); 02238 //--------------------------------------------- 02239 02240 count = 0; 02241 for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) { 02242 02243 bool testResult = false; 02244 02245 // Assume triangle is in Sphere Node 02246 // Test the triangle in sphere node with BVCylinder 02247 primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace(); 02248 vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices ); 02249 Vector3<T> cdrVec[3]; 02250 02251 //* 02252 // Test against each vertex in the triangle 02253 //----------------------------------- 02254 for ( int j = 0; j < noOfVertices; ++j ) { 02255 if( (*pos).BV->TestPointLocation( &(vertexList[j]->GetPosition()), &(cdrVec[j]) ) ) 02256 { 02257 vertexList[j]->SetPosition( vertexList[j]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[j])).GetVector3() ); 02258 02259 testResult = true; 02260 } 02261 } 02262 //----------------------------------- 02263 //*/ 02264 02265 //* 02266 // Test against triangle 02267 //----------------------------------- 02268 if ( TAPs::CGMath<T>::FindIntersectionCylinderTriangle( 02269 topPtOfBV_inMeshCoord, bottomPtOfBV_inMeshCoord, radiusOfBV_inMeshCoord, // BVCylinder properties 02270 vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices 02271 cdrVec[0], cdrVec[1], cdrVec[2] // out vectors 02272 ) ) { 02273 vertexList[0]->SetPosition( vertexList[0]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[0])).GetVector3()*CDScaleForCylinderBVWithTriangle ); 02274 vertexList[1]->SetPosition( vertexList[1]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[1])).GetVector3()*CDScaleForCylinderBVWithTriangle ); 02275 vertexList[2]->SetPosition( vertexList[2]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[2])).GetVector3()*CDScaleForCylinderBVWithTriangle ); 02276 02277 testResult = true; 02278 } 02279 //----------------------------------- 02280 //*/ 02281 02282 std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n"; 02283 02284 // List of BVNodes to be updated 02285 if ( testResult ) { 02286 defPolyMesh_NodeSet.insert( (*pos).NodeList[i] ); 02287 bResult = true; 02288 } 02289 } 02290 } 02291 break; 02292 02293 default: 02294 std::cout << "CDR_PolygonalMesh_vs_MBV of BV Type (" << (*pos).BV->GetType() << ") doesn't support!\n"; 02295 break; 02296 } 02297 02298 // Restore the transformation of the bounding volume 02299 (*pos).BV->SetTransform( trx ); 02300 // Next Bounding Volume 02301 ++pos; 02302 } 02303 } // END CASE: the polygonal mesh object's transformation is on. 02304 //------------------------------------------------- 02305 02306 //------------------------------------------------- 02307 // Update Normals of Deformable Polygonal Mesh 02308 pPolygonalMeshObj->CalAndSetNormals(); 02309 //------------------------------------------------- 02310 // Update Bounding Volume Hierarchy of Deformable Polygonal Mesh 02311 pPolygonalMeshObj->GetBVHTree()->Update( defPolyMesh_NodeSet ); 02312 } 02313 //--------------------------------------------------------------- 02314 return bResult; 02315 }
| bool CDR_PolygonalMesh_vs_MBV | ( | TAPs::OpenGL::XPolygonalModel< T > * | pPolygonalMeshObj, | |
| TAPs::MultiBoundingVolume< T > const *const | pMBVObj | |||
| ) | [inline] |
| pPolygonalMeshObj | a PolygonalModel object |
| pMBVObj | a multi bounding volume object |
Definition at line 1769 of file TAPsColDetFns.cpp.
01773 { 01774 std::cout << "CDR_PolygonalMesh_vs_MBV( XPolygonalModel<T>, MultiBoundingVolume<T> ) -- NOT IMPLEMENTED YET!" << std::endl; 01775 bool bResult = false; 01776 //--------------------------------------------------------------- 01777 //--------------------------------------------------------------- 01778 return bResult; 01779 }
| bool CDR_PolygonalMesh_vs_MBV | ( | TAPs::OpenGL::PolygonalModel< T > * | pPolygonalMeshObj, | |
| TAPs::MultiBoundingVolume< T > const *const | pMBVObj | |||
| ) | [inline] |
Collision detection and response of a polygonal mesh model with a multi bounding volume object.
The polygonal mesh model can be an instance of PolygonalModel, XPolygonalModel, or HalfEdgeModel. The function returns true if collision occurs. The function deforms the polygonal mesh model to resolve the collision. The multi bounding volume object is unaffected.
| pPolygonalMeshObj | a PolygonalModel object |
| pMBVObj | a multi bounding volume object |
Definition at line 1753 of file TAPsColDetFns.cpp.
01757 { 01758 std::cout << "CDR_PolygonalMesh_vs_MBV( PolygonalModel<T>, MultiBoundingVolume<T> ) -- NOT IMPLEMENTED YET!" << std::endl; 01759 bool bResult = false; 01760 //--------------------------------------------------------------- 01761 //--------------------------------------------------------------- 01762 return bResult; 01763 }
| bool CDR_Strand_vs_MBV | ( | TAPs::OpenGL::ModelStrand< T > * | pStrandObj, | |
| TAPs::MultiBoundingVolume< T > const *const | pMBVObj, | |||
| TAPs::TransformationSupport< T > const *const | pTransform | |||
| ) | [inline] |
| pStrandObj | a strand object |
| pMBVObj | a multi bounding volume object |
| pTransform | an extra transformation for the MBV object |
Definition at line 91 of file TAPsColDetFns.cpp.
00096 { 00097 bool bResult = false; 00098 //--------------------------------------------------------------- 00099 //bool isThePointInsideTheBV; // the pt is inside or outside the bv 00100 Vector3<T> vDistance; // displacement vector 00101 TransformationSupport<T> transform; 00102 transform.DisableStatusApplyTransformation(); 00103 //--------------------------------------------------------------- 00104 // pTransform, if provided, always has its transformation support 00105 // changed by the haptic device. Therefore, we do not need to check 00106 // for its apply transformation status. 00107 if ( pTransform /*&& pTransform->GetStatusApplyTransformation()*/ ) { 00108 transform.ReturnMatrixTransform() *= pTransform->GetMatrixTransform(); 00109 transform.EnableStatusApplyTransformation(); 00110 } 00111 //--------------------------------------------------------------- 00112 if ( pMBVObj->GetTransform().GetStatusApplyTransformation() ) { 00113 transform.ReturnMatrixTransform() *= pMBVObj->GetTransform().GetMatrixTransform(); 00114 transform.EnableStatusApplyTransformation(); 00115 } 00116 TransformationSupport<T> savedTransform( transform ); 00117 //--------------------------------------------------------------- 00118 std::vector< BoundingVolume<T> * >::const_iterator pos = pMBVObj->GetBoundingVolumeList().begin(); 00119 //--------------------------------------------------------------- 00120 while ( pos != pMBVObj->GetBoundingVolumeList().end() ) { 00121 assert( *pos != NULL ); 00122 vDistance.SetXYZ( 0, 0, 0 ); 00123 transform = savedTransform; 00124 //------------------------------------------------- 00125 if ( (*pos)->GetTransform().GetStatusApplyTransformation() ) { 00126 transform.ReturnMatrixTransform() *= (*pos)->GetTransform().GetMatrixTransform(); 00127 transform.EnableStatusApplyTransformation(); 00128 } 00129 //------------------------------------------------- 00130 // Transform each vertex of the strand to the bounding volume coordinate 00131 int iDeepestPoint = -1; 00132 T tDeepestDistance = 1E12; 00133 Vector3<T> vDirection; 00134 Vector3<T> translation( transform.GetTranslation() ); 00135 Matrix3x3<T> inversedRotMatrix( transform.GetMatrixRotation().GetInverse() ); 00136 00137 switch ( (*pos)->GetType() ) { 00138 00139 //--------------------------------------------- 00140 case TAPs::Enum::BOUNDING_CYLINDER: 00141 //--------------------------------------------- 00142 #ifdef TAPs_STRAND_LOCK_SEGMENTS 00143 for ( unsigned int s = 0; s < pStrandObj->GetNumSegments(); ++s ) { 00144 // Skip locked or invisible segments 00145 if ( pStrandObj->GetSegmentLockStatus(s) || !pStrandObj->GetSegmentVisibleStatus(s) ) {} 00146 else { 00147 for ( int i = pStrandObj->GetStartPtOfSegment(s); i <= pStrandObj->GetEndPtOfSegment(s); ++i ) 00148 #else //TAPs_STRAND_LOCK_SEGMENTS 00149 { 00150 { 00151 for ( unsigned int i = 0; i <= pStrandObj->GetNumberOfLinks(); ++i ) 00152 #endif//TAPs_STRAND_LOCK_SEGMENTS 00153 { 00154 // If the point is fixed, do not move it. 00155 if ( pStrandObj->GetFixStatusOfPtNo(i) ) continue; 00156 00157 //------------------------------------------------------ 00158 // In the local coordinate of the bounding cylinder, 00159 // the cylinder axis is parallel to z-axis 00160 // where it is shifted by the cylinder center. 00161 // The cylinder has radius, height and center. 00162 // Its height is measured from -z and +z axis 00163 // where its center is situated between height/2 in -z and +z axis. 00164 Vector3<T> location = pStrandObj->GetPointPosition(i); 00165 if ( transform.GetStatusApplyTransformation() ) { 00166 location -= translation; 00167 location = inversedRotMatrix * location; 00168 } 00169 // Shift the location of point by the cylinder center 00170 // i.e. shift the cylinder to the origin (0,0,0) 00171 location -= (*pos)->GetCenter(); 00172 //------------------------------------------------------ 00173 // Now the cylinder is centered at the origin with its axis on the z-axis 00174 // where its height is from -height/2 to +height/2. 00175 // And the input point has been transformed into the cylinder coordinate. 00176 // The test can be performed. 00177 if ( TAPs::CGMath<T>::CD_CylinderAtOrigin_vs_Point( (*pos)->GetRadius(), (*pos)->GetHeight(), location, vDistance ) ) 00178 { 00179 bResult = true; 00180 //------------------------- 00181 // Now rotate it back by the rotation matrix (from the transform matrix). 00182 // REMARK: Translation (from the transform matrix) is NOT applied back, 00183 // because vDistance represents a displacement vector from 00184 // the input point to the cylinder surface. 00185 // I.e., the strand point is always in the world coordinates. 00186 if ( transform.GetStatusApplyTransformation() ) { 00187 vDistance = transform.GetMatrixRotation() * vDistance; 00188 } 00189 //------------------------- 00190 // This statement just ask the strand to move its collided points away 00191 pStrandObj->ChangeOnlyPointPositionByAddedWithThisVector( i, vDistance ); 00192 T tDistance = vDistance.Length(); 00193 if ( tDeepestDistance > tDistance ) { 00194 tDeepestDistance = tDistance; 00195 iDeepestPoint = i; 00196 vDirection = vDistance; 00197 } 00198 //------------------------- 00199 } 00200 }// Back to Next Strand Point 00201 } 00202 } 00203 break; 00204 // END: BOUNDING_CYLINDER 00205 00206 //--------------------------------------------- 00207 case TAPs::Enum::BOUNDING_SPHERE: 00208 //--------------------------------------------- 00209 #ifdef TAPs_STRAND_LOCK_SEGMENTS 00210 for ( unsigned int s = 0; s < pStrandObj->GetNumSegments(); ++s ) { 00211 // Skip locked or invisible segments 00212 if ( pStrandObj->GetSegmentLockStatus(s) || !pStrandObj->GetSegmentVisibleStatus(s) ) {} 00213 else { 00214 for ( int i = pStrandObj->GetStartPtOfSegment(s); i <= pStrandObj->GetEndPtOfSegment(s); ++i ) 00215 #else //TAPs_STRAND_LOCK_SEGMENTS 00216 { 00217 { 00218 for ( unsigned int i = 0; i <= pStrandObj->GetNumberOfLinks(); ++i ) 00219 #endif//TAPs_STRAND_LOCK_SEGMENTS 00220 { 00221 // If the point is fixed, do not move it. 00222 if ( pStrandObj->GetFixStatusOfPtNo(i) ) continue; 00223 00224 //------------------------------------------------------ 00225 // In the local coordinate of the bounding sphere centered at the origin 00226 Vector3<T> location = pStrandObj->GetPointPosition(i); 00227 if ( transform.GetStatusApplyTransformation() ) { 00228 location -= translation; 00229 location = inversedRotMatrix * location; 00230 } 00231 // Shift the location of point by the sphere center 00232 // i.e. shift the sphere to the origin (0,0,0) 00233 location -= (*pos)->GetCenter(); 00234 //------------------------------------------------------ 00235 // Now the sphere is centered at the origin 00236 // And the input point has been transformed into the sphere coordinate. 00237 // The test can be performed. 00238 if ( TAPs::CGMath<T>::CD_SphereAtOrigin_vs_Point( (*pos)->GetRadius(), location, vDistance ) ) 00239 { 00240 bResult = true; 00241 //------------------------- 00242 // Now rotate it back by the rotation matrix (from the transform matrix). 00243 // REMARK: Translation (from the transform matrix) is NOT applied back, 00244 // because vDistance represents a displacement vector from 00245 // the input point to the sphere surface. 00246 // I.e., the strand point is always in the world coordinates. 00247 if ( transform.GetStatusApplyTransformation() ) { 00248 vDistance = transform.GetMatrixRotation() * vDistance; 00249 } 00250 //------------------------- 00251 // This statement just ask the strand to move its collided points away 00252 pStrandObj->ChangeOnlyPointPositionByAddedWithThisVector( i, vDistance ); 00253 T tDistance = vDistance.Length(); 00254 if ( tDeepestDistance > tDistance ) { 00255 tDeepestDistance = tDistance; 00256 iDeepestPoint = i; 00257 vDirection = vDistance; 00258 } 00259 //------------------------- 00260 } 00261 }// Back to Next Strand Point 00262 } 00263 } 00264 break; 00265 // END: BOUNDING_SPHERE 00266 00267 }//END: switch ( (*pos)->GetType() ) {...} 00268 ++pos; // Next Bounding Volume 00269 } 00270 return bResult; 00271 }
1.5.6