TAPsColDetFns.cpp File Reference

#include "TAPsColDetFns.hpp"

Include dependency graph for TAPsColDetFns.cpp:

This graph shows which files directly or indirectly include this file:

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 Documentation

#define TAPs_STRAND_MODEL_HPP

Definition at line 85 of file TAPsColDetFns.cpp.


Function Documentation

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 }

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 
) [inline]

Parameters:
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 }

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 
) [inline]

Parameters:
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 }

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 
) [inline]

Parameters:
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 }

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 
) [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

Parameters:
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 }

template<typename T>
bool CDR_DeformPolygonalMesh_vs_DeformPolygonalMesh ( TAPs::OpenGL::HalfEdgeModel< T > *const   pDefPolyMesh_1,
TAPs::OpenGL::HalfEdgeModel< T > *const   pDefPolyMesh_2,
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.

Parameters:
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 }

template<typename T>
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.

Parameters:
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 }

template<typename T>
bool CDR_PolygonalMesh_vs_BV ( TAPs::OpenGL::HETriMeshOneModelMultiParts< T > *  pPolygonalMeshObj,
TAPs::BoundingVolume< T > const *const   pBVObj 
) [inline]

Parameters:
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 }

template<typename T>
bool CDR_PolygonalMesh_vs_BV ( TAPs::OpenGL::HalfEdgeModel< T > *  pPolygonalMeshObj,
TAPs::BoundingVolume< T > const *const   pBVObj 
) [inline]

Parameters:
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 }

template<typename T>
bool CDR_PolygonalMesh_vs_BV ( TAPs::OpenGL::XPolygonalModel< T > *  pPolygonalMeshObj,
TAPs::BoundingVolume< T > const *const   pBVObj 
) [inline]

Parameters:
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 }

template<typename T>
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.

Parameters:
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 }

template<typename T>
bool CDR_PolygonalMesh_vs_MBV ( TAPs::OpenGL::HETriMeshOneModelMultiParts< T > *  pPolygonalMeshObj,
TAPs::MultiBoundingVolume< T > const *const   pMBVObj,
TAPs::Vector3< T > *  totalForce,
gain 
) [inline]

Parameters:
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 }

template<typename T>
bool CDR_PolygonalMesh_vs_MBV ( TAPs::OpenGL::HalfEdgeModel< T > *  pPolygonalMeshObj,
TAPs::MultiBoundingVolume< T > const *const   pMBVObj 
) [inline]

Parameters:
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 }

template<typename T>
bool CDR_PolygonalMesh_vs_MBV ( TAPs::OpenGL::XPolygonalModel< T > *  pPolygonalMeshObj,
TAPs::MultiBoundingVolume< T > const *const   pMBVObj 
) [inline]

Parameters:
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 }

template<typename T>
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.

Parameters:
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 }

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 
) [inline]

Parameters:
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 }


Generated on Mon Oct 13 11:31:58 2008 for TAPs by  doxygen 1.5.6