![]() |
TAPs 0.7.7.3
|
#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 |
Functions | |
| template<typename T > | |
| BEGIN_NAMESPACE_TAPs__CD__Fn bool | CDR_Strand_vs_MBV (TAPs::OpenGL::ModelStrand< T > *pStrandObj, TAPs::MultiBoundingVolume< T > const *const pMBVObj, TAPs::TransformationSupport< T > const *const pTransform) |
| Collision detection and response of a strand object with a multi bounding volume object. | |
| 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 | 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. | |
| template<typename T > | |
| bool | CDR_Suture_vs_MBV (TAPs::OpenGL::ModelSuture< T > *pSutureObj, TAPs::MultiBoundingVolume< T > const *const pMBVObj, TAPs::TransformationSupport< T > const *const pTransform) |
| Collision detection and response of a suture object with a multi bounding volume object. | |
| template<typename T > | |
| bool | CDR_Strand_vs_DeformMesh (TAPs::OpenGL::ModelStrand< T > *pStrandObj, TAPs::DeformMesh< T > const *const pDeformMeshObj) |
| Collision detection and response of a strand object with a deformable mesh object (TAPsDeformMesh.hpp). | |
| template<typename T > | |
| bool | CDR_Suture_vs_DeformMesh (TAPs::OpenGL::ModelSuture< T > *pSutureObj, TAPs::DeformMesh< T > const *const pDeformMeshObj) |
| Collision detection and response of a suture object with a deformable mesh object (TAPsDeformMesh.hpp). | |
| template<typename T > | |
| bool | CDR_DeformMesh_vs_MBV (TAPs::DeformMesh< T > *pDeformMeshObj, TAPs::MultiBoundingVolume< T > const *const pMBVObj, TAPs::TransformationSupport< T > const *const pTransform) |
| Collision detection and response of a deformable mesh object (TAPsDeformMesh.hpp) with a multi bounding volume object. | |
| template<typename T > | |
| bool | CDR_PolygonalMesh_vs_BV (TAPs::OpenGL::HalfEdgeModel< T > *pPolygonalMeshObj, TAPs::BoundingVolume< T > const *const pBVObj) |
| Collision detection and response of a polygonal mesh model with a bounding volume object. | |
| template<typename T > | |
| bool | CDR_PolygonalMesh_vs_BV (TAPs::OpenGL::HETriMeshOneModelMultiParts< T > *pPolygonalMeshObj, TAPs::BoundingVolume< T > const *const pBVObj) |
| 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) |
| Collision detection and response of a polygonal mesh model with a line segment. | |
| 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, std::vector< T > *listOfRatios, std::vector< T > *listOfIntersectionAngles) |
| Collision detection and response of a polygonal mesh model with a line segment. | |
| template<typename T > | |
| bool | CDR_PolygonalMesh_vs_MBV (TAPs::OpenGL::HalfEdgeModel< 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 | CDRigid_PolygonalMesh_vs_MBV (TAPs::OpenGL::HalfEdgeModel< T > *pPolygonalMeshObj, TAPs::MultiBoundingVolume< T > const *const pMBVObj) |
| Collision detection of a polygonal mesh model with a multi bounding volume object. | |
| 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 | CDRigid_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_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. | |
| 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 | ||
| ) |
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 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 Collision detection and response of a polygonal mesh model with a line segment.
The polygonal mesh model can be an instance of PolygonalModel, XPolygonalModel, or HalfEdgeModel. The function returns true if collision occurs. The function returns the closest vertex on the triangle intersected by the line segment
| pPolygonalMeshObj | a 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 1287 of file TAPsColDetFns.cpp.
Referenced by AdvSimSupport_DS< T, DATA >::ProcessForwardPuncturingIPGonRBDModelToHexFEMModel_SectionCleared(), AdvSimSupport_DS< T, DATA >::ProcessForwardPuncturingIPGonRBDModelToHexFEMModel_SectionPunctured(), and AdvSimConstraint_ForModelSurgicalSutureWithHeadNeedle< T, DATA >::ProcessPuncturingOfHeadNeedleRepresentedByIPGWithFEMModel().
{
std::cout << __FILE__ << " " << __LINE__ << " ";
std::cout << "CD_PolygonalMesh_vs_LineSegment( HalfEdgeModel<T>, ... ) -- NOT IMPLEMENTED YET!" << std::endl;
#ifdef TAPs_DEBUG_COLLISION_DETECTION
pPolygonalMeshObj->GetBVHTree()->ClearFlags();
#endif//TAPs_DEBUG_COLLISION_DETECTION
//#ifdef TAPs_DEBUG_MODE
std::cout << "CD_PolygonalMesh_vs_LineSegment( HalfEdgeModel<T>, ... )\n";
//#endif//TAPs_DEBUG_MODE
std::cout << "BVHTree: " << *(pPolygonalMeshObj->GetBVHTree()) << "\n";
bool bResult = false;
// Collision Detection
bResult = pPolygonalMeshObj->GetBVHTree()->TestIntersectionWithLineSegmentTillLeafNodes( ptA, ptB );
//---------------------------------------------------------------
// Collision Response
//if ( bResult ) {
//}
//---------------------------------------------------------------
return bResult;
}
Here is the caller graph for this function:| 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, | ||
| std::vector< T > * | listOfRatios, | ||
| std::vector< T > * | listOfIntersectionAngles | ||
| ) |
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 list of each closest vertex on the triangles intersected by the line segment. It also returns the list of the intersected triangles and the list of intersected points. The list of ratios of the intersected points are returned as well. All of the list returned are arranged by the ratios from low to high.
| 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 |
| listOfRatios | O/P: list of ratios of the closest vertices relative to the line segment [0(ptA)-1(ptB)] |
| listOfIntersectionAngles | O/P: list of intersection angles (in degrees) -- between the line and the intersected face |
Definition at line 1325 of file TAPsColDetFns.cpp.
References CGMath< T >::FindIntersectionLineSegmentTriangle(), HEFace< T >::GetPtrsToVerticesAndNumberOfVertices(), Length(), ListOfContactPts, and ListOfForces.
{
ListOfContactPts.clear();
ListOfForces.clear();
#ifdef TAPs_DEBUG_COLLISION_DETECTION
pPolygonalMeshObj->GetBVHTree()->ClearFlags();
#endif//TAPs_DEBUG_COLLISION_DETECTION
bool bResult = false;
// Collision Detection
bResult = pPolygonalMeshObj->GetBVHTree()->TestIntersectionWithLineSegmentTillLeafNodes( ptA, ptB );
//---------------------------------------------------------------
if ( bResult ) {
// Include pPolygonalMeshObj's transformation
TAPs::Matrix4x4<T> invTrx( pPolygonalMeshObj->GetTransform().RefToMatrixTransform().GetInverse() );
TAPs::Vector3<T> A = invTrx * *ptA;
TAPs::Vector3<T> B = invTrx * *ptB;
std::vector< BVHNode<T> * > & nodeList = pPolygonalMeshObj->GetBVHTree()->GetListOfCollidedNodes();
T ratio, intersectionAngle;
Vector3<T> projPt;
HEFace<T> * triangle;
std::vector< HEVertex<T> * const > vertexList;
int noOfVertices;
for ( int i = 0; i < static_cast<int>( nodeList.size() ); ++i ) {
// Check intersection of the line segment with the primitive triangle in the BV node
triangle = nodeList[i]->GetAPrimitiveHalfEdgeFace();
vertexList = triangle->GetPtrsToVerticesAndNumberOfVertices( noOfVertices );
bool result = CGMath<T>::FindIntersectionLineSegmentTriangle(
A, B, // I/P: a line segment
vertexList[0]->GetPosition(), // I/P: the triangle
vertexList[1]->GetPosition(),
vertexList[2]->GetPosition(),
ratio, // O/P: the ratio
intersectionAngle, // O/P: the intersection angle (in degrees)
projPt // O/P: the projected point
);
if ( result ) {
#ifdef TAPs_ADVANCED_SIMULATION
// Sort the elements by ratio -- from low to high
std::vector< T >::iterator itR = listOfRatios->begin();
std::vector< T >::iterator itA = listOfIntersectionAngles->begin();
std::vector< TAPs::Vector3<T> >::iterator itIP = listOfIntersectedPoints->begin();
std::vector< TAPs::HEFace<T>* >::iterator itIF = listOfIntersectedFaces->begin();
std::vector< TAPs::HEVertex<T>* >::iterator itCV = listOfClosestVertices->begin();
while ( itR != listOfRatios->end() ) {
if ( *itR > ratio ) {
if ( itR != listOfRatios->begin() ) {
--itR;
--itA;
--itIP;
--itIF;
--itCV;
}
break;
}
++itR;
++itA;
++itIP;
++itIF;
++itCV;
}
listOfIntersectedPoints->insert( itIP, projPt );
listOfIntersectedFaces->insert( itIF, triangle );
listOfRatios->insert( itR, ratio );
listOfIntersectionAngles->insert( itA, intersectionAngle );
//listOfIntersectedPoints->push_back( projPt );
//listOfIntersectedFaces->push_back( triangle );
//listOfRatios->push_back( ratio );
// Find the closest point
T distance0 = ( projPt - vertexList[0]->GetPosition() ).Length();
T distance1 = ( projPt - vertexList[1]->GetPosition() ).Length();
T distance2 = ( projPt - vertexList[2]->GetPosition() ).Length();
if ( distance0 < distance1 ) {
if ( distance0 < distance2 ) {
listOfClosestVertices->insert( itCV, vertexList[0] );
//listOfClosestVertices->push_back( vertexList[0] );
//vertexList[0]->SimFlags.SetSimulationConstraints( TAPs::Enum::AddOn::PUNCTURED );
}
else {
listOfClosestVertices->insert( itCV, vertexList[2] );
//listOfClosestVertices->push_back( vertexList[2] );
//vertexList[2]->SimFlags.SetSimulationConstraints( TAPs::Enum::AddOn::PUNCTURED );
}
}
else {
if ( distance1 < distance2 ) {
listOfClosestVertices->insert( itCV, vertexList[1] );
//listOfClosestVertices->push_back( vertexList[1] );
//vertexList[1]->SimFlags.SetSimulationConstraints( TAPs::Enum::AddOn::PUNCTURED );
}
else {
listOfClosestVertices->insert( itCV, vertexList[2] );
//listOfClosestVertices->push_back( vertexList[2] );
//vertexList[2]->SimFlags.SetSimulationConstraints( TAPs::Enum::AddOn::PUNCTURED );
}
}
#endif//TAPs_ADVANCED_SIMULATION
//std::cout << __FILE__ << " " << __LINE__ << " -- ";
//std::cout << "Line Segment intersected Node " << nodeList[i] << "\n";
}
}
}
return bResult;
}
Here is the call graph for this function:| bool CDR_DeformMesh_vs_MBV | ( | TAPs::DeformMesh< T > * | pDeformMeshObj, |
| TAPs::MultiBoundingVolume< T > const *const | pMBVObj, | ||
| TAPs::TransformationSupport< T > const *const | pTransform | ||
| ) |
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.
| pDeformMeshObj | a deformable mesh object |
| pMBVObj | a multi bounding volume object |
| pTransform | an extra transformation for the MBV object |
Definition at line 616 of file TAPsColDetFns.cpp.
References BOUNDING_CYLINDER, BOUNDING_SPHERE, TransformationSupport< T >::GetMatrixRotation(), TransformationSupport< T >::GetMatrixTransform(), TransformationSupport< T >::GetTranslation(), and Vector3< T >::SetXYZ().
{
bool bResult = false;
//---------------------------------------------------------------
int iNoRows;
int iNoCols;
pDeformMeshObj->GetNumberOfRowsAndColumns( iNoRows, iNoCols );
//---------------------------------------------------------------
Vector3<T> vDistance; // displacement vector
TransformationSupport<T> transform;
//---------------------------------------------------------------
if ( pTransform ) {
transform.ReturnMatrixTransform() *= pTransform->GetMatrixTransform();
}
//---------------------------------------------------------------
transform.ReturnMatrixTransform() *= pMBVObj->GetTransform().GetMatrixTransform();
TransformationSupport<T> savedTransform( transform );
//---------------------------------------------------------------
std::vector< BoundingVolume<T> * >::const_iterator pos = pMBVObj->GetBoundingVolumeList().begin();
//---------------------------------------------------------------
while ( pos != pMBVObj->GetBoundingVolumeList().end() ) {
assert( *pos != NULL );
vDistance.SetXYZ( 0, 0, 0 );
transform = savedTransform;
//-------------------------------------------------
transform.ReturnMatrixTransform() *= (*pos)->GetTransform().GetMatrixTransform();
//-------------------------------------------------
// For transforming each vertex of the deformable mesh to the bounding volume coordinate
Vector3<T> translation( transform.GetTranslation() );
Matrix3x3<T> inversedRotMatrix( transform.GetMatrixRotation().GetInverse() );
switch ( (*pos)->GetType() ) {
//---------------------------------------------
case TAPs::Enum::BOUNDING_CYLINDER:
//---------------------------------------------
// Transform each vertex of the flat skin to the bounding volume coordinate
// Exclude the boundary
for ( int r = 1; r < iNoRows-1; ++r ) {
for ( int c = 1; c < iNoCols-1; ++c ) {
//-------------------------------
// In the local coordinate of the bounding cylinder,
// the cylinder axis is parallel to z-axis
// where it is shifted by the cylinder center.
// The cylinder has radius, height and center.
// Its height is measured from -z and +z axis
// where its center is situated between height/2 in -z and +z axis.
Vector3<T> location = pDeformMeshObj->GetPositionOfPointNumber( r, c );
location -= translation;
location = inversedRotMatrix * location;
// Shift the location of point by the cylinder center
// i.e. shift the cylinder to the origin (0,0,0)
location -= (*pos)->GetCenter();
//-------------------------------
// Now the cylinder is centered at the origin with its axis on the z-axis
// where its height is from -height/2 to +height/2.
// And the input point has been transformed into the cylinder coordinate.
// The test can be performed.
if ( TAPs::CGMath<T>::CD_CylinderAtOrigin_vs_Point( (*pos)->GetRadius(), (*pos)->GetHeight(), location, vDistance ) )
{
bResult = true;
//-----------------------------
// Now rotate it back by the rotation matrix (from the transform matrix).
// REMARK: Translation (from the transform matrix) is NOT applied back,
// because vDistance represents a displacement vector from
// the input point to the cylinder surface.
// I.e., the deformable mesh point is always in the world coordinates.
vDistance = transform.GetMatrixRotation() * vDistance;
//-----------------------------
// This statement just ask the vertex (row,col) of the flat skin to move its collided points away
//pDeformMeshObj->SetParticleFixStatus( r, c, true ); // DEBUG
//pDeformMeshObj->MovePositionOfPointNumber( r, c, vDistance );
// DEBUG (HACKING)
pDeformMeshObj->MovePositionOfPointNumber( r, c, Vector3<T>( 0, -1, 0 ) );
//-----------------------------
}
}// Back to the Next Column of the Flat Skin
}// Back to the Next Row of the Flat Skin
break;
// END: BOUNDING_CYLINDER
//---------------------------------------------
case TAPs::Enum::BOUNDING_SPHERE:
//---------------------------------------------
// Transform each vertex of the flat skin to the bounding volume coordinate
// Exclude the boundary
for ( int r = 1; r < iNoRows-1; ++r ) {
for ( int c = 1; c < iNoCols-1; ++c ) {
//-------------------------------
// In the local coordinate of the bounding cylinder,
// the cylinder axis is parallel to z-axis
// where it is shifted by the cylinder center.
// The cylinder has radius, height and center.
// Its height is measured from -z and +z axis
// where its center is situated between height/2 in -z and +z axis.
Vector3<T> location = pDeformMeshObj->GetPositionOfPointNumber( r, c );
location -= translation;
location = inversedRotMatrix * location;
// Shift the location of point by the cylinder center
// i.e. shift the cylinder to the origin (0,0,0)
location -= (*pos)->GetCenter();
//-------------------------------
// Now the cylinder is centered at the origin with its axis on the z-axis
// where its height is from -height/2 to +height/2.
// And the input point has been transformed into the cylinder coordinate.
// The test can be performed.
if ( TAPs::CGMath<T>::CD_SphereAtOrigin_vs_Point( (*pos)->GetRadius(), location, vDistance ) )
{
bResult = true;
//-----------------------------
// Now rotate it back by the rotation matrix (from the transform matrix).
// REMARK: Translation (from the transform matrix) is NOT applied back,
// because vDistance represents a displacement vector from
// the input point to the cylinder surface.
// I.e., the deformable mesh point is always in the world coordinates.
vDistance = transform.GetMatrixRotation() * vDistance;
//-----------------------------
// This statement just ask the vertex (row,col) of the flat skin to move its collided points away
//pDeformMeshObj->SetParticleFixStatus( r, c, true ); // DEBUG
//pDeformMeshObj->MovePositionOfPointNumber( r, c, vDistance );
// DEBUG (HACKING)
pDeformMeshObj->MovePositionOfPointNumber( r, c, Vector3<T>( 0, -1, 0 ) );
//-----------------------------
}
}// Back to the Next Column of the Flat Skin
}// Back to the Next Row of the Flat Skin
break;
// END: BOUNDING_SPHERE
}//END: switch ( (*pos)->GetType() ) {...}
//-------------------------------------------------
++pos; // Next Bounding Volume
}
//---------------------------------------------------------------
return bResult;
}
Here is the call graph for this function:| 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.
Each polygonal mesh model can be an instance of PolygonalModel, XPolygonalModel, or HalfEdgeModel. The function returns true if collision occurs. The function deforms the deformable polygonal mesh model to resolve the collision. The rigid polygonal mesh model is unaffected.
| pDefPolyMesh | a deformable polygonal mesh model |
| pRigidPolyMesh | a rigid polygonal mesh model |
Definition at line 2735 of file TAPsColDetFns.cpp.
References HEFace< T >::GetPtrsToVerticesAndNumberOfVertices(), Vector3< T >::Length(), and Vector3< T >::Normalized().
{
//---------------------------------------------------------------
if ( pDefPolyMesh->GetBVHTree()->TestOverlapWithTillLeafNodes( pRigidPolyMesh->GetBVHTree() ) )
{
//-------------------------------------------------
T separateDistanceConstraint;
Vector3<T> N, centerA;
T separateDistance;
HEFace<T> * primB;
std::vector< HEVertex<T> * const > vertexList;
int noOfVertices;
//-------------------------------------------------
std::vector< BVHNode<T> * > * listOfCollidedNode_Def = &pDefPolyMesh->GetBVHTree()->GetListOfCollidedNodes();
std::vector< BVHNode<T> * > * listOfCollidedNode_Rigid = &pDefPolyMesh->GetBVHTree()->GetListOfCollidedNodesThat();
std::set< BVHNode<T> * > defPolyMesh_NodeSet;
//-------------------------------------------------
// Deform the deformable polygonal mesh away from the rigid polygonal mesh
for ( int i = 0; i < static_cast<int>( listOfCollidedNode_Def->size() ); ++i ) {
separateDistanceConstraint = 0.5 * ( (*listOfCollidedNode_Def)[i]->GetRadius()
+ (*listOfCollidedNode_Rigid)[i]->GetRadius() );
centerA = ( pRigidPolyMesh->GetTransform().GetMatrixTransform() *
Vector4<T>( (*listOfCollidedNode_Rigid)[i]->GetCenter() ) ).GetVector3();
N = centerA - (*listOfCollidedNode_Def)[i]->GetCenter();
separateDistance = separateDistanceConstraint - N.Length();
if ( separateDistance > Math<T>::ZERO ) {
N.Normalized();
N *= separateDistance;
primB = (*listOfCollidedNode_Def)[i]->GetAPrimitiveHalfEdgeFace();
vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices );
//-------------------------------
// For each vertex in a primitive
for ( int j = 0; j < noOfVertices; ++j ) {
vertexList[j]->SetPosition( vertexList[j]->GetPosition() - N );
}
}
// List of BVNodes to be updated
defPolyMesh_NodeSet.insert( (*listOfCollidedNode_Def)[i] );
}
//-------------------------------------------------
// Update Normals of Deformable Polygonal Mesh
pDefPolyMesh->CalAndSetNormals();
//-------------------------------------------------
// Update Bounding Volume Hierarchy of Deformable Polygonal Mesh
pDefPolyMesh->GetBVHTree()->Update( defPolyMesh_NodeSet );
//-------------------------------------------------
return true;
}
//---------------------------------------------------------------
return false;
}
Here is the call graph for this function:| bool CDR_PolygonalMesh_vs_BV | ( | TAPs::OpenGL::HETriMeshOneModelMultiParts< T > * | pPolygonalMeshObj, |
| TAPs::BoundingVolume< T > const *const | pBVObj | ||
| ) |
| pPolygonalMeshObj | a HETriMeshOneModelMultiParts object |
| pBVObj | a bounding volume object |
Definition at line 896 of file TAPsColDetFns.cpp.
References BOUNDING_CYLINDER, BOUNDING_SPHERE, CDScaleForSphereBVWithTriangle, TransformationSupport< T >::GetMatrixTransform(), HEFace< T >::GetPtrsToVerticesAndNumberOfVertices(), Matrix4x4< T >::Inversed(), Length(), ListOfContactPts, ListOfForces, TransformationSupport< T >::SetMatrixTransform(), and Vector3< T >::SetXYZ().
{
ListOfContactPts.clear();
ListOfForces.clear();
#ifdef TAPs_DEBUG_COLLISION_DETECTION
pPolygonalMeshObj->GetBVHTree()->ClearFlags();
#endif//TAPs_DEBUG_COLLISION_DETECTION
//#ifdef TAPs_DEBUG_MODE
std::cout << "CDR_PolygonalMesh_vs_BV( HalfEdgeModel<T>, BoundingVolume<T> )\n";
//#endif//TAPs_DEBUG_MODE
std::cout << "BVHTree: " << *(pPolygonalMeshObj->GetBVHTree()) << "\n";
bool bResult = false;
// Collision Detection
bResult = pPolygonalMeshObj->GetBVHTree()->TestOverlapWithTillLeafNodes( pBVObj );
//---------------------------------------------------------------
// Collision Response
if ( bResult ) {
// Reset the result for primitive-primitive test,
// because the previous result is only from bounding volume test.
bResult = false;
//-------------------------------------------------
T separateDistanceConstraint;
Vector3<T> N, centerA;
T separateDistance;
HEFace<T> * primB;
std::vector< HEVertex<T> * const > vertexList;
int noOfVertices;
//-------------------------------------------------
TransformationSupport<T> trxMBV; // default constructor is an identity transformation
//-------------------------------------------------
std::set< BVHNode<T> * > defPolyMesh_NodeSet;
// Get the list of collided nodes and bounding volumes
std::vector< BVsAndNodesList<T> > * bvList = &pPolygonalMeshObj->GetBVHTree()->GetListOfCollidedBoundingVolumesAndNodes();
//-------------------------------------------------
// Traverse the list of bounding volumes
std::vector< BVsAndNodesList<T> >::const_iterator pos = bvList->begin();
//-------------------------------------------------
//std::cout << "CDR_PolygonalMesh_vs_BV(...) for HETriMeshOneModelMultiParts --> \n";
//std::cout << "\tCASE: the polygonal mesh object's transformation is on. -- NOT IMPLEMENTED YET!\n";
// Mesh's inverse transformation
Matrix4x4<T> trxInvMesh = pPolygonalMeshObj->GetTransform().GetMatrixTransform();
trxInvMesh.Inversed();
Vector3<T> vOrigin( (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(0,0,0,1)).GetVector3() );
while ( pos != bvList->end() ) {
int count = 0;
// Store the transformation of the bounding volume including the mesh's inverse transformation
TransformationSupport<T> trx = (*pos).BV->GetTransform();
(*pos).BV->GetTransform().SetMatrixTransform( trxInvMesh * trx.GetMatrixTransform() );
//-----------------------------------------
// Deform the deformable polygonal mesh away from the rigid polygonal mesh
switch ( (*pos).BV->GetType() ) {
case TAPs::Enum::BOUNDING_SPHERE:
{
std::cout << "BV: " << (*pos).BV->GetName() << "\n";
// For Test against triangle
//---------------------------------------------
// Transform the BV due to its transformation, center, and radius
T radiusOfBV = (*pos).BV->GetRadius();
Vector3<T> C( (*pos).BV->GetCenter() );
Matrix4x4<T> translation( 1, 0, 0, C[0],
0, 1, 0, C[1],
0, 0, 1, C[2],
0, 0, 0, 1 );
Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV );
Matrix4x4<T> scale( S[0], 0, 0, 0,
0, S[1], 0, 0,
0, 0, S[2], 0,
0, 0, 0, 1 );
// The BV's current transformation includes the mesh's inverse transformation (see the code above)
Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale;
// BV Sphere's center and radius after the whole transformation from
// BV's transformation to mesh's inverse transformation.
// I.e., transforming the BV to mesh's coordinate
Vector3<T> centerOfBV_inMeshCoord = (mat * Vector4<T>(0,0,0,1)).GetVector3();
T radiusOfBV_inMeshCoord = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV_inMeshCoord ).Length();
// Inverse the mesh's transformation to the BV's pure transformation
mat = pPolygonalMeshObj->GetTransform().GetMatrixTransform() * mat;
// BV Sphere's center and radius after the BV's pure transformation
Vector3<T> centerOfBV( (mat * Vector4<T>(0,0,0,1)).GetVector3() );
radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length();
//---------------------------------------------
count = 0;
for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) {
bool testResult = false;
// Assume triangle is in Sphere Node
// Test the triangle in sphere node with BVSphere
primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace();
vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices );
Vector3<T> cdrVec[3];
//*
// Test against each vertex in the triangle
//-----------------------------------
for ( int j = 0; j < noOfVertices; ++j ) {
if( (*pos).BV->TestPointLocation( vertexList[j]->GetPosition(), &(cdrVec[j]) ) )
{
vertexList[j]->SetPosition( vertexList[j]->GetPosition() + cdrVec[j] );
Vector3<T> force( (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(cdrVec[j])).GetVector3() - vOrigin );
//ListOfContactPts.push_back( Vector3<GLfloat>( (*pos).BV->GetCenter()[0], (*pos).BV->GetCenter()[1], (*pos).BV->GetCenter()[2] ) );
ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) );
ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) );
testResult = true;
}
}
//-----------------------------------
//*/
//*
// Test against triangle
//-----------------------------------
//Vector3<T> contactPt;
if ( TAPs::CGMath<T>::FindIntersectionSphereTriangle(
centerOfBV_inMeshCoord, radiusOfBV_inMeshCoord, // BVSphere properties
vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices
cdrVec[0], cdrVec[1], cdrVec[2] // out vectors
//, &contactPt
) ) {
Vector3<T> force_1( cdrVec[0] * CDScaleForSphereBVWithTriangle );
Vector3<T> force_2( cdrVec[1] * CDScaleForSphereBVWithTriangle );
Vector3<T> force_3( cdrVec[2] * CDScaleForSphereBVWithTriangle );
vertexList[0]->SetPosition( vertexList[0]->GetPosition() + force_1 );
vertexList[1]->SetPosition( vertexList[1]->GetPosition() + force_2 );
vertexList[2]->SetPosition( vertexList[2]->GetPosition() + force_3 );
force_1 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_1)).GetVector3() - vOrigin;
force_2 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_2)).GetVector3() - vOrigin;
force_3 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_3)).GetVector3() - vOrigin;
//ListOfContactPts.push_back( Vector3<GLfloat>( contactPt[0], contactPt[1], contactPt[2] ) );
ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) );
Vector3<T> force( ( force_1 + force_2 + force_3 )/3 );
ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) );
testResult = true;
}
//-----------------------------------
//*/
std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n";
// List of BVNodes to be updated
if ( testResult ) {
defPolyMesh_NodeSet.insert( (*pos).NodeList[i] );
bResult = true;
}
}
}
break;
case TAPs::Enum::BOUNDING_CYLINDER:
{
std::cout << "BV: " << (*pos).BV->GetName() << "\n";
// For Test against triangle
//---------------------------------------------
// Transform the BV due to its transformation, center, and radius
T radiusOfBV = (*pos).BV->GetRadius();
Vector3<T> C( (*pos).BV->GetCenter() );
Matrix4x4<T> translation( 1, 0, 0, C[0],
0, 1, 0, C[1],
0, 0, 1, C[2],
0, 0, 0, 1 );
Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV );
Matrix4x4<T> scale( S[0], 0, 0, 0,
0, S[1], 0, 0,
0, 0, S[2], 0,
0, 0, 0, 1 );
// The BV's current transformation includes the mesh's inverse transformation (see the code above)
Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale;
// BV Sphere's center and radius after the whole transformation from
// BV's transformation to mesh's inverse transformation.
// I.e., transforming the BV to mesh's coordinate
T halfHeightOfBV = (*pos).BV->GetHeight() / 2.0;
Vector3<T> centerOfBV_inMeshCoord = (mat * Vector4<T>(0,0,0,1)).GetVector3();
T radiusOfBV_inMeshCoord = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV_inMeshCoord ).Length();
Vector3<T> topPtOfBV_inMeshCoord( (mat * Vector4<T>(0,0,halfHeightOfBV,1)).GetVector3() );
Vector3<T> bottomPtOfBV_inMeshCoord( (mat * Vector4<T>(0,0,-halfHeightOfBV,1)).GetVector3() );
// Inverse the mesh's transformation to the BV's pure transformation
mat = pPolygonalMeshObj->GetTransform().GetMatrixTransform() * mat;
// BV Sphere's center and radius after the BV's pure transformation
Vector3<T> centerOfBV( (mat * Vector4<T>(0,0,0,1)).GetVector3() );
radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length();
Vector3<T> topPtOfBV( (mat * Vector4<T>(0,0,halfHeightOfBV,1)).GetVector3() );
Vector3<T> bottomPtOfBV( (mat * Vector4<T>(0,0,-halfHeightOfBV,1)).GetVector3() );
//---------------------------------------------
count = 0;
for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) {
bool testResult = false;
// Assume triangle is in Sphere Node
// Test the triangle in sphere node with BVCylinder
primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace();
vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices );
Vector3<T> cdrVec[3];
//*
// Test against each vertex in the triangle
//-----------------------------------
for ( int j = 0; j < noOfVertices; ++j ) {
if( (*pos).BV->TestPointLocation( vertexList[j]->GetPosition(), &(cdrVec[j]) ) )
{
vertexList[j]->SetPosition( vertexList[j]->GetPosition() + cdrVec[j] );
Vector3<T> force( (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(cdrVec[j])).GetVector3() - vOrigin );
//ListOfContactPts.push_back( Vector3<GLfloat>( (*pos).BV->GetCenter()[0], (*pos).BV->GetCenter()[1], (*pos).BV->GetCenter()[2] ) );
ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) );
ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) );
testResult = true;
}
}
//-----------------------------------
//*/
//*
// Test against triangle
//-----------------------------------
Vector3<T> contactPt;
if ( TAPs::CGMath<T>::FindIntersectionCylinderTriangle(
topPtOfBV_inMeshCoord, bottomPtOfBV_inMeshCoord, radiusOfBV_inMeshCoord, // BVCylinder properties
vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices
cdrVec[0], cdrVec[1], cdrVec[2] // out vectors
, &contactPt
) ) {
Vector3<T> force_1( cdrVec[0] * CDScaleForSphereBVWithTriangle );
Vector3<T> force_2( cdrVec[1] * CDScaleForSphereBVWithTriangle );
Vector3<T> force_3( cdrVec[2] * CDScaleForSphereBVWithTriangle );
vertexList[0]->SetPosition( vertexList[0]->GetPosition() + force_1 );
vertexList[1]->SetPosition( vertexList[1]->GetPosition() + force_2 );
vertexList[2]->SetPosition( vertexList[2]->GetPosition() + force_3 );
force_1 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_1)).GetVector3() - vOrigin;
force_2 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_2)).GetVector3() - vOrigin;
force_3 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_3)).GetVector3() - vOrigin;
contactPt = ( (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(contactPt)).GetVector3() );
ListOfContactPts.push_back( Vector3<GLfloat>( contactPt[0], contactPt[1], contactPt[2] ) );
Vector3<T> force( ( force_1 + force_2 + force_3 )/3 );
ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) );
testResult = true;
}
//-----------------------------------
//*/
std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n";
// List of BVNodes to be updated
if ( testResult ) {
defPolyMesh_NodeSet.insert( (*pos).NodeList[i] );
bResult = true;
}
}
}
break;
default:
std::cout << "CDR_PolygonalMesh_vs_BV of BV Type (" << (*pos).BV->GetType() << ") doesn't support!\n";
break;
}
// Restore the transformation of the bounding volume
//(*pos).BV->GetTransform().SetMatrixTransform( trx.GetMatrixTransform() );
(*pos).BV->SetTransform( trx );
// Next Bounding Volume
++pos;
}
//-------------------------------------------------
//-------------------------------------------------
// Update Normals of Deformable Polygonal Mesh
//pPolygonalMeshObj->CalAndSetNormals(); // commented out to rely on AdvanceSimulation to update the normals
//-------------------------------------------------
// Update Bounding Volume Hierarchy of Deformable Polygonal Mesh
pPolygonalMeshObj->GetBVHTree()->Update( defPolyMesh_NodeSet );
// FOR HETriMeshOneModelMultiParts
//-------------------------------------------------
// Update for the model's internal simulation
for ( int i = 0; i < static_cast<int>( pPolygonalMeshObj->GetListOfParts().size() ); ++i ) {
pPolygonalMeshObj->GetPtrToPartNo(i)->UpdateStateToArray();
}
}
//---------------------------------------------------------------
if ( totalForce ) {
totalForce->SetXYZ( 0, 0, 0 );
Vector3<float> force( 0, 0, 0 );
for ( int i = 0; i < ListOfForces.size(); ++i ) {
force += ListOfForces[i];
}
force *= gain;
(*totalForce).SetXYZ( force[0], force[1], force[2] );
}
return bResult;
}
Here is the call graph for this function:| bool CDR_PolygonalMesh_vs_BV | ( | TAPs::OpenGL::HalfEdgeModel< T > * | pPolygonalMeshObj, |
| TAPs::BoundingVolume< T > const *const | pBVObj | ||
| ) |
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. 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. Collision detection and response of a polygonal mesh model with a bounding volume object.
The polygonal mesh model can be an instance of PolygonalModel, XPolygonalModel, or HalfEdgeModel. The function returns true if collision occurs. The function deforms the polygonal mesh model to resolve the collision. The bounding volume object is unaffected.
| pPolygonalMeshObj | a HalfEdgeModel object |
| pBVObj | a bounding volume object |
Definition at line 803 of file TAPsColDetFns.cpp.
References BOUNDING_SPHERE, HEFace< T >::GetPtrsToVerticesAndNumberOfVertices(), Vector3< T >::Length(), and Vector3< T >::Normalized().
{
#ifdef TAPs_DEBUG_COLLISION_DETECTION
//pPolygonalMeshObj->GetBVHTree()->ClearFlags();
#endif//TAPs_DEBUG_COLLISION_DETECTION
#ifdef TAPs_DEBUG_MODE
std::cout << "CDR_HalfEdgeMesh_vs_BV( HalfEdgeModel<T>, BoundingVolume<T> )\n";
#endif//TAPs_DEBUG_MODE
//std::cout << "BVHTree: " << *(pPolygonalMeshObj->GetBVHTree()) << "\n";
//---------------------------------------------------------------
if ( pPolygonalMeshObj->GetBVHTree()->TestOverlapWithTillLeafNodes( pBVObj ) )
{
//-------------------------------------------------
T separateDistanceConstraint;
Vector3<T> N, centerA;
T separateDistance;
HEFace<T> * primB;
std::vector< HEVertex<T> * const > vertexList;
int noOfVertices;
//-------------------------------------------------
std::vector< BVHNode<T> * > * listOfCollidedNode_Def = &pPolygonalMeshObj->GetBVHTree()->GetListOfCollidedNodes();
std::set< BVHNode<T> * > defPolyMesh_NodeSet;
//std::cout << "listOfCollidedNode_Def SIZE: " << listOfCollidedNode_Def->size() << "\n";
// Collision Response
//-------------------------------------------------
// Deform the deformable polygonal mesh away from the rigid polygonal mesh
switch ( pBVObj->GetType() ) {
case TAPs::Enum::BOUNDING_SPHERE:
for ( int i = 0; i < static_cast<int>( listOfCollidedNode_Def->size() ); ++i ) {
separateDistanceConstraint = 0.5 * ( (*listOfCollidedNode_Def)[i]->GetRadius() + pBVObj->GetRadius() );
//centerA = ( pRigidPolyMesh->GetTransform().GetMatrixTransform() *
// Vector4<T>( (*listOfCollidedNode_Rigid)[i]->GetCenter() ) ).GetVector3();
centerA = pBVObj->GetCenter();
N = centerA - (*listOfCollidedNode_Def)[i]->GetCenter();
separateDistance = separateDistanceConstraint - N.Length();
if ( true ) {
//if ( separateDistance > Math<T>::ZERO ) {
N.Normalized();
N *= separateDistance;
primB = (*listOfCollidedNode_Def)[i]->GetAPrimitiveHalfEdgeFace();
vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices );
//-------------------------------
// For each vertex in a primitive
for ( int j = 0; j < noOfVertices; ++j ) {
//vertexList[j]->SetPosition( vertexList[j]->GetPosition() - N );
vertexList[j]->SetPosition( vertexList[j]->GetPosition() - Vector3<T>( 0.01, 0.01, 0.01 ) );
//vertexList[j]->
}
}
#ifdef TAPs_DEBUG_COLLISION_DETECTION
//(*listOfCollidedNode_Def)[i]->flag = true;
#endif//TAPs_DEBUG_COLLISION_DETECTION
// List of BVNodes to be updated
defPolyMesh_NodeSet.insert( (*listOfCollidedNode_Def)[i] );
}
break;
default:
std::cout << "CDR_PolygonalMesh_vs_BV of BV Type (" << pBVObj->GetType() << ") doesn't support!\n";
break;
}
//-------------------------------------------------
// Update Normals of Deformable Polygonal Mesh
pPolygonalMeshObj->CalAndSetNormals();
//-------------------------------------------------
// Update Bounding Volume Hierarchy of Deformable Polygonal Mesh
pPolygonalMeshObj->GetBVHTree()->Update( defPolyMesh_NodeSet );
//-------------------------------------------------
return true;
}
//---------------------------------------------------------------
return false;
}
Here is the call graph for this function:| bool CDR_PolygonalMesh_vs_MBV | ( | TAPs::OpenGL::HalfEdgeModel< T > * | pPolygonalMeshObj, |
| TAPs::MultiBoundingVolume< T > const *const | pMBVObj | ||
| ) |
Collision detection and response of a polygonal mesh model with a multi bounding volume object.
The polygonal mesh model can be an instance of PolygonalModel, XPolygonalModel, or HalfEdgeModel. The function returns true if collision occurs. The function deforms the polygonal mesh model to resolve the collision. The multi bounding volume object is unaffected.
| pPolygonalMeshObj | a HalfEdgeModel object |
| pMBVObj | a multi bounding volume object |
Definition at line 1488 of file TAPsColDetFns.cpp.
References BOUNDING_CYLINDER, BOUNDING_SPHERE, CDScaleForCylinderBVWithTriangle, CDScaleForSphereBVWithTriangle, TransformationSupport< T >::GetMatrixTransform(), HEFace< T >::GetPtrsToVerticesAndNumberOfVertices(), Matrix4x4< T >::Inversed(), Length(), and TransformationSupport< T >::SetMatrixTransform().
{
#ifdef TAPs_DEBUG_COLLISION_DETECTION
pPolygonalMeshObj->GetBVHTree()->ClearFlags();
#endif//TAPs_DEBUG_COLLISION_DETECTION
//#ifdef TAPs_DEBUG_MODE
std::cout << "CDR_PolygonalMesh_vs_MBV( HalfEdgeModel<T>, MultiBoundingVolume<T> )\n";
//#endif//TAPs_DEBUG_MODE
std::cout << "BVHTree: " << *(pPolygonalMeshObj->GetBVHTree()) << "\n";
bool bResult = false;
// Collision Detection
bResult = pPolygonalMeshObj->GetBVHTree()->TestOverlapWithTillLeafNodes( pMBVObj );
//---------------------------------------------------------------
// Collision Response
if ( bResult ) {
// Reset the result for primitive-primitive test,
// because the previous result is only from bounding volume test.
bResult = false;
//-------------------------------------------------
T separateDistanceConstraint;
Vector3<T> N, centerA;
T separateDistance;
HEFace<T> * primB;
std::vector< HEVertex<T> * const > vertexList;
int noOfVertices;
//-------------------------------------------------
TransformationSupport<T> trxMBV; // default constructor is an identity transformation
trxMBV = pMBVObj->GetTransform();
//-------------------------------------------------
std::set< BVHNode<T> * > defPolyMesh_NodeSet;
// Get the list of collided nodes and bounding volumes
std::vector< BVsAndNodesList<T> > * bvList = &pPolygonalMeshObj->GetBVHTree()->GetListOfCollidedBoundingVolumesAndNodes();
//-------------------------------------------------
// Traverse the list of bounding volumes
std::vector< BVsAndNodesList<T> >::const_iterator pos = bvList->begin();
//-------------------------------------------------
//std::cout << "CDR_PolygonalMesh_vs_MBV(...) for HalfEdgeModel --> \n";
//std::cout << "\tCASE: the polygonal mesh object's transformation is on. -- NOT IMPLEMENTED YET!\n";
// Mesh's inverse transformation
Matrix4x4<T> trxInvMesh = pPolygonalMeshObj->GetTransform().GetMatrixTransform();
trxInvMesh.Inversed();
while ( pos != bvList->end() ) {
int count = 0;
// Store the transformation of the bounding volume including the mesh's inverse transformation
TransformationSupport<T> trx = (*pos).BV->GetTransform();
(*pos).BV->GetTransform().SetMatrixTransform( trxInvMesh * trxMBV.GetMatrixTransform() * trx.GetMatrixTransform() );
//-----------------------------------------
// Deform the deformable polygonal mesh away from the rigid polygonal mesh
switch ( (*pos).BV->GetType() ) {
case TAPs::Enum::BOUNDING_SPHERE:
{
std::cout << "BV: " << (*pos).BV->GetName() << "\n";
// For Test against triangle
//---------------------------------------------
// Transform the BV due to its transformation, center, and radius
T radiusOfBV = (*pos).BV->GetRadius();
Vector3<T> C( (*pos).BV->GetCenter() );
Matrix4x4<T> translation( 1, 0, 0, C[0],
0, 1, 0, C[1],
0, 0, 1, C[2],
0, 0, 0, 1 );
Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV );
Matrix4x4<T> scale( S[0], 0, 0, 0,
0, S[1], 0, 0,
0, 0, S[2], 0,
0, 0, 0, 1 );
// The BV's current transformation includes the mesh's inverse transformation (see the code above)
Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale;
// BV Sphere's center and radius after the whole transformation from
// BV's transformation to mesh's inverse transformation.
// I.e., transforming the BV to mesh's coordinate
Vector3<T> centerOfBV_inMeshCoord = (mat * Vector4<T>(0,0,0,1)).GetVector3();
T radiusOfBV_inMeshCoord = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV_inMeshCoord ).Length();
// Inverse the mesh's transformation to the BV's pure transformation
mat = pPolygonalMeshObj->GetTransform().GetMatrixTransform() * mat;
// BV Sphere's center and radius after the BV's pure transformation
Vector3<T> centerOfBV( (mat * Vector4<T>(0,0,0,1)).GetVector3() );
radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length();
//---------------------------------------------
count = 0;
for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) {
bool testResult = false;
// Assume triangle is in Sphere Node
// Test the triangle in sphere node with BVSphere
primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace();
vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices );
Vector3<T> cdrVec[3];
//*
// Test against each vertex in the triangle
//-----------------------------------
for ( int j = 0; j < noOfVertices; ++j ) {
if( (*pos).BV->TestPointLocation( vertexList[j]->GetPosition(), &(cdrVec[j]) ) )
{
vertexList[j]->SetPosition( vertexList[j]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[j])).GetVector3() );
testResult = true;
}
}
//-----------------------------------
//*/
//*
// Test against triangle
//-----------------------------------
//Vector3<T> contactPt;
if ( TAPs::CGMath<T>::FindIntersectionSphereTriangle(
centerOfBV_inMeshCoord, radiusOfBV_inMeshCoord, // BVSphere properties
vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices
cdrVec[0], cdrVec[1], cdrVec[2] // out vectors
//, &contactPt
) ) {
vertexList[0]->SetPosition( vertexList[0]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[0])).GetVector3()*CDScaleForSphereBVWithTriangle );
vertexList[1]->SetPosition( vertexList[1]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[1])).GetVector3()*CDScaleForSphereBVWithTriangle );
vertexList[2]->SetPosition( vertexList[2]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[2])).GetVector3()*CDScaleForSphereBVWithTriangle );
testResult = true;
}
//-----------------------------------
//*/
std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n";
// List of BVNodes to be updated
if ( testResult ) {
defPolyMesh_NodeSet.insert( (*pos).NodeList[i] );
bResult = true;
}
}
}
break;
case TAPs::Enum::BOUNDING_CYLINDER:
{
std::cout << "BV: " << (*pos).BV->GetName() << "\n";
// For Test against triangle
//---------------------------------------------
// Transform the BV due to its transformation, center, and radius
T radiusOfBV = (*pos).BV->GetRadius();
Vector3<T> C( (*pos).BV->GetCenter() );
Matrix4x4<T> translation( 1, 0, 0, C[0],
0, 1, 0, C[1],
0, 0, 1, C[2],
0, 0, 0, 1 );
Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV );
Matrix4x4<T> scale( S[0], 0, 0, 0,
0, S[1], 0, 0,
0, 0, S[2], 0,
0, 0, 0, 1 );
// The BV's current transformation includes the mesh's inverse transformation (see the code above)
Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale;
// BV Sphere's center and radius after the whole transformation from
// BV's transformation to mesh's inverse transformation.
// I.e., transforming the BV to mesh's coordinate
T halfHeightOfBV = (*pos).BV->GetHeight() / 2.0;
Vector3<T> centerOfBV_inMeshCoord = (mat * Vector4<T>(0,0,0,1)).GetVector3();
T radiusOfBV_inMeshCoord = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV_inMeshCoord ).Length();
Vector3<T> topPtOfBV_inMeshCoord( (mat * Vector4<T>(0,0,halfHeightOfBV,1)).GetVector3() );
Vector3<T> bottomPtOfBV_inMeshCoord( (mat * Vector4<T>(0,0,-halfHeightOfBV,1)).GetVector3() );
// Inverse the mesh's transformation to the BV's pure transformation
mat = pPolygonalMeshObj->GetTransform().GetMatrixTransform() * mat;
// BV Sphere's center and radius after the BV's pure transformation
Vector3<T> centerOfBV( (mat * Vector4<T>(0,0,0,1)).GetVector3() );
radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length();
Vector3<T> topPtOfBV( (mat * Vector4<T>(0,0,halfHeightOfBV,1)).GetVector3() );
Vector3<T> bottomPtOfBV( (mat * Vector4<T>(0,0,-halfHeightOfBV,1)).GetVector3() );
//---------------------------------------------
count = 0;
for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) {
bool testResult = false;
// Assume triangle is in Sphere Node
// Test the triangle in sphere node with BVCylinder
primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace();
vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices );
Vector3<T> cdrVec[3];
//*
// Test against each vertex in the triangle
//-----------------------------------
for ( int j = 0; j < noOfVertices; ++j ) {
if( (*pos).BV->TestPointLocation( vertexList[j]->GetPosition(), &(cdrVec[j]) ) )
{
vertexList[j]->SetPosition( vertexList[j]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[j])).GetVector3() );
testResult = true;
}
}
//-----------------------------------
//*/
//*
// Test against triangle
//-----------------------------------
if ( TAPs::CGMath<T>::FindIntersectionCylinderTriangle(
topPtOfBV_inMeshCoord, bottomPtOfBV_inMeshCoord, radiusOfBV_inMeshCoord, // BVCylinder properties
vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices
cdrVec[0], cdrVec[1], cdrVec[2] // out vectors
) ) {
vertexList[0]->SetPosition( vertexList[0]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[0])).GetVector3()*CDScaleForCylinderBVWithTriangle );
vertexList[1]->SetPosition( vertexList[1]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[1])).GetVector3()*CDScaleForCylinderBVWithTriangle );
vertexList[2]->SetPosition( vertexList[2]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[2])).GetVector3()*CDScaleForCylinderBVWithTriangle );
testResult = true;
}
//-----------------------------------
//*/
std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n";
// List of BVNodes to be updated
if ( testResult ) {
defPolyMesh_NodeSet.insert( (*pos).NodeList[i] );
bResult = true;
}
}
}
break;
default:
std::cout << "CDR_PolygonalMesh_vs_MBV of BV Type (" << (*pos).BV->GetType() << ") doesn't support!\n";
break;
}
// Restore the transformation of the bounding volume
(*pos).BV->SetTransform( trx );
// Next Bounding Volume
++pos;
}
//-------------------------------------------------
//-------------------------------------------------
// Update Normals of Deformable Polygonal Mesh
pPolygonalMeshObj->CalAndSetNormals();
//-------------------------------------------------
// Update Bounding Volume Hierarchy of Deformable Polygonal Mesh
pPolygonalMeshObj->GetBVHTree()->Update( defPolyMesh_NodeSet );
}
//---------------------------------------------------------------
return bResult;
}
Here is the call graph for this function:| bool CDR_PolygonalMesh_vs_MBV | ( | TAPs::OpenGL::HETriMeshOneModelMultiParts< T > * | pPolygonalMeshObj, |
| TAPs::MultiBoundingVolume< T > const *const | pMBVObj, | ||
| TAPs::Vector3< T > * | totalForce, | ||
| T | gain | ||
| ) |
| pPolygonalMeshObj | a HETriMeshOneModelMultiParts object |
| pMBVObj | a multi bounding volume object |
| totalForce | total force |
| gain | gain |
Definition at line 2046 of file TAPsColDetFns.cpp.
References BOUNDING_CYLINDER, BOUNDING_SPHERE, CDScaleForSphereBVWithTriangle, TransformationSupport< T >::GetMatrixTransform(), HEFace< T >::GetPtrsToVerticesAndNumberOfVertices(), Matrix4x4< T >::Inversed(), Length(), ListOfContactPts, ListOfForces, TransformationSupport< T >::SetMatrixTransform(), and Vector3< T >::SetXYZ().
{
ListOfContactPts.clear();
ListOfForces.clear();
#ifdef TAPs_DEBUG_COLLISION_DETECTION
pPolygonalMeshObj->GetBVHTree()->ClearFlags();
#endif//TAPs_DEBUG_COLLISION_DETECTION
//#ifdef TAPs_DEBUG_MODE
//std::cout << "CDR_PolygonalMesh_vs_MBV( HalfEdgeModel<T>, MultiBoundingVolume<T> )\n";
//#endif//TAPs_DEBUG_MODE
//std::cout << "BVHTree: " << *(pPolygonalMeshObj->GetBVHTree()) << "\n";
bool bResult = false;
// Collision Detection
bResult = pPolygonalMeshObj->GetBVHTree()->TestOverlapWithTillLeafNodes( pMBVObj );
//---------------------------------------------------------------
// Collision Response
if ( bResult ) {
// Reset the result for primitive-primitive test,
// because the previous result is only from bounding volume test.
bResult = false;
//-------------------------------------------------
//T separateDistanceConstraint;
Vector3<T> N, centerA;
//T separateDistance;
HEFace<T> * primB;
std::vector< HEVertex<T> * const > vertexList;
int noOfVertices;
//-------------------------------------------------
TransformationSupport<T> trxMBV( pMBVObj->GetTransform() );
//-------------------------------------------------
std::set< BVHNode<T> * > defPolyMesh_NodeSet;
// Get the list of collided nodes and bounding volumes
std::vector< BVsAndNodesList<T> > * bvList = &pPolygonalMeshObj->GetBVHTree()->GetListOfCollidedBoundingVolumesAndNodes();
//-------------------------------------------------
// Traverse the list of bounding volumes
std::vector< BVsAndNodesList<T> >::const_iterator pos = bvList->begin();
//-------------------------------------------------
//std::cout << "CDR_PolygonalMesh_vs_MBV(...) for HETriMeshOneModelMultiParts --> \n";
//std::cout << "\tCASE: the polygonal mesh object's transformation is on. -- NOT IMPLEMENTED YET!\n";
// Mesh's inverse transformation
Matrix4x4<T> trxInvMesh = pPolygonalMeshObj->GetTransform().GetMatrixTransform();
trxInvMesh.Inversed();
Vector3<T> vOrigin( (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(0,0,0,1)).GetVector3() );
while ( pos != bvList->end() ) {
//int count = 0;
// Store the transformation of the bounding volume including the mesh's inverse transformation
TransformationSupport<T> trx = (*pos).BV->GetTransform();
(*pos).BV->GetTransform().SetMatrixTransform( trxInvMesh * trxMBV.GetMatrixTransform() * trx.GetMatrixTransform() );
//-----------------------------------------
// Deform the deformable polygonal mesh away from the rigid polygonal mesh
switch ( (*pos).BV->GetType() ) {
case TAPs::Enum::BOUNDING_SPHERE:
{
//std::cout << "BV: " << (*pos).BV->GetName() << "\n";
// For Test against triangle
//---------------------------------------------
// Transform the BV due to its transformation, center, and radius
T radiusOfBV = (*pos).BV->GetRadius();
Vector3<T> C( (*pos).BV->GetCenter() );
Matrix4x4<T> translation( 1, 0, 0, C[0],
0, 1, 0, C[1],
0, 0, 1, C[2],
0, 0, 0, 1 );
Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV );
Matrix4x4<T> scale( S[0], 0, 0, 0,
0, S[1], 0, 0,
0, 0, S[2], 0,
0, 0, 0, 1 );
// The BV's current transformation includes the mesh's inverse transformation (see the code above)
Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale;
// BV Sphere's center and radius after the whole transformation from
// BV's transformation to mesh's inverse transformation.
// I.e., transforming the BV to mesh's coordinate
Vector3<T> centerOfBV_inMeshCoord = (mat * Vector4<T>(0,0,0,1)).GetVector3();
T radiusOfBV_inMeshCoord = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV_inMeshCoord ).Length();
// Inverse the mesh's transformation to the BV's pure transformation
mat = pPolygonalMeshObj->GetTransform().GetMatrixTransform() * mat;
// BV Sphere's center and radius after the BV's pure transformation
Vector3<T> centerOfBV( (mat * Vector4<T>(0,0,0,1)).GetVector3() );
radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length();
//---------------------------------------------
//count = 0;
for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) {
bool testResult = false;
// Assume triangle is in Sphere Node
// Test the triangle in sphere node with BVSphere
primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace();
vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices );
Vector3<T> cdrVec[3];
//*
// Test against each vertex in the triangle
//-----------------------------------
for ( int j = 0; j < noOfVertices; ++j ) {
if( (*pos).BV->TestPointLocation( vertexList[j]->GetPosition(), &(cdrVec[j]) ) )
{
vertexList[j]->SetPosition( vertexList[j]->GetPosition() + cdrVec[j] );
Vector3<T> force( (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(cdrVec[j])).GetVector3() - vOrigin );
//ListOfContactPts.push_back( Vector3<GLfloat>( (*pos).BV->GetCenter()[0], (*pos).BV->GetCenter()[1], (*pos).BV->GetCenter()[2] ) );
ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) );
ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) );
testResult = true;
}
}
//-----------------------------------
//*/
//*
// Test against triangle
//-----------------------------------
//Vector3<T> contactPt;
if ( TAPs::CGMath<T>::FindIntersectionSphereTriangle(
centerOfBV_inMeshCoord, radiusOfBV_inMeshCoord, // BVSphere properties
vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices
cdrVec[0], cdrVec[1], cdrVec[2] // out vectors
//, &contactPt
) ) {
Vector3<T> force_1( cdrVec[0] * CDScaleForSphereBVWithTriangle );
Vector3<T> force_2( cdrVec[1] * CDScaleForSphereBVWithTriangle );
Vector3<T> force_3( cdrVec[2] * CDScaleForSphereBVWithTriangle );
vertexList[0]->SetPosition( vertexList[0]->GetPosition() + force_1 );
vertexList[1]->SetPosition( vertexList[1]->GetPosition() + force_2 );
vertexList[2]->SetPosition( vertexList[2]->GetPosition() + force_3 );
force_1 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_1)).GetVector3() - vOrigin;
force_2 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_2)).GetVector3() - vOrigin;
force_3 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_3)).GetVector3() - vOrigin;
//ListOfContactPts.push_back( Vector3<GLfloat>( contactPt[0], contactPt[1], contactPt[2] ) );
ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) );
Vector3<T> force( ( force_1 + force_2 + force_3 )/3 );
ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) );
testResult = true;
}
//-----------------------------------
//*/
//std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n";
// List of BVNodes to be updated
if ( testResult ) {
defPolyMesh_NodeSet.insert( (*pos).NodeList[i] );
bResult = true;
}
}
}
break;
case TAPs::Enum::BOUNDING_CYLINDER:
{
//std::cout << "BV: " << (*pos).BV->GetName() << "\n";
// For Test against triangle
//---------------------------------------------
// Transform the BV due to its transformation, center, and radius
T radiusOfBV = (*pos).BV->GetRadius();
Vector3<T> C( (*pos).BV->GetCenter() );
Matrix4x4<T> translation( 1, 0, 0, C[0],
0, 1, 0, C[1],
0, 0, 1, C[2],
0, 0, 0, 1 );
Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV );
Matrix4x4<T> scale( S[0], 0, 0, 0,
0, S[1], 0, 0,
0, 0, S[2], 0,
0, 0, 0, 1 );
// The BV's current transformation includes the mesh's inverse transformation (see the code above)
Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale;
// BV Sphere's center and radius after the whole transformation from
// BV's transformation to mesh's inverse transformation.
// I.e., transforming the BV to mesh's coordinate
T halfHeightOfBV = (*pos).BV->GetHeight() / 2.0;
Vector3<T> centerOfBV_inMeshCoord = (mat * Vector4<T>(0,0,0,1)).GetVector3();
T radiusOfBV_inMeshCoord = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV_inMeshCoord ).Length();
Vector3<T> topPtOfBV_inMeshCoord( (mat * Vector4<T>(0,0,halfHeightOfBV,1)).GetVector3() );
Vector3<T> bottomPtOfBV_inMeshCoord( (mat * Vector4<T>(0,0,-halfHeightOfBV,1)).GetVector3() );
// Inverse the mesh's transformation to the BV's pure transformation
mat = pPolygonalMeshObj->GetTransform().GetMatrixTransform() * mat;
// BV Sphere's center and radius after the BV's pure transformation
Vector3<T> centerOfBV( (mat * Vector4<T>(0,0,0,1)).GetVector3() );
radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length();
Vector3<T> topPtOfBV( (mat * Vector4<T>(0,0,halfHeightOfBV,1)).GetVector3() );
Vector3<T> bottomPtOfBV( (mat * Vector4<T>(0,0,-halfHeightOfBV,1)).GetVector3() );
//---------------------------------------------
//count = 0;
for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) {
bool testResult = false;
// Assume triangle is in Sphere Node
// Test the triangle in sphere node with BVCylinder
primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace();
vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices );
Vector3<T> cdrVec[3];
//*
// Test against each vertex in the triangle
//-----------------------------------
for ( int j = 0; j < noOfVertices; ++j ) {
if( (*pos).BV->TestPointLocation( vertexList[j]->GetPosition(), &(cdrVec[j]) ) )
{
vertexList[j]->SetPosition( vertexList[j]->GetPosition() + cdrVec[j] );
Vector3<T> force( (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(cdrVec[j])).GetVector3() - vOrigin );
//ListOfContactPts.push_back( Vector3<GLfloat>( (*pos).BV->GetCenter()[0], (*pos).BV->GetCenter()[1], (*pos).BV->GetCenter()[2] ) );
ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) );
ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) );
testResult = true;
}
}
//-----------------------------------
//*/
//*
// Test against triangle
//-----------------------------------
Vector3<T> contactPt;
if ( TAPs::CGMath<T>::FindIntersectionCylinderTriangle(
topPtOfBV_inMeshCoord, bottomPtOfBV_inMeshCoord, radiusOfBV_inMeshCoord, // BVCylinder properties
vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices
cdrVec[0], cdrVec[1], cdrVec[2] // out vectors
, &contactPt
) ) {
Vector3<T> force_1( cdrVec[0] * CDScaleForSphereBVWithTriangle );
Vector3<T> force_2( cdrVec[1] * CDScaleForSphereBVWithTriangle );
Vector3<T> force_3( cdrVec[2] * CDScaleForSphereBVWithTriangle );
vertexList[0]->SetPosition( vertexList[0]->GetPosition() + force_1 );
vertexList[1]->SetPosition( vertexList[1]->GetPosition() + force_2 );
vertexList[2]->SetPosition( vertexList[2]->GetPosition() + force_3 );
force_1 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_1)).GetVector3() - vOrigin;
force_2 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_2)).GetVector3() - vOrigin;
force_3 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_3)).GetVector3() - vOrigin;
contactPt = ( (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(contactPt)).GetVector3() );
ListOfContactPts.push_back( Vector3<GLfloat>( contactPt[0], contactPt[1], contactPt[2] ) );
Vector3<T> force( ( force_1 + force_2 + force_3 )/3 );
ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) );
testResult = true;
}
//-----------------------------------
//*/
//std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n";
// List of BVNodes to be updated
if ( testResult ) {
defPolyMesh_NodeSet.insert( (*pos).NodeList[i] );
bResult = true;
}
}
}
break;
default:
std::cout << "CDR_PolygonalMesh_vs_MBV of BV Type (" << (*pos).BV->GetType() << ") doesn't support!\n";
break;
}
// Restore the transformation of the bounding volume
//(*pos).BV->GetTransform().SetMatrixTransform( trx.GetMatrixTransform() );
(*pos).BV->SetTransform( trx );
// Next Bounding Volume
++pos;
}
//-------------------------------------------------
//-------------------------------------------------
// Update Normals of Deformable Polygonal Mesh
//pPolygonalMeshObj->CalAndSetNormals(); // commented out to rely on AdvanceSimulation to update the normals
//-------------------------------------------------
// Update Bounding Volume Hierarchy of Deformable Polygonal Mesh
pPolygonalMeshObj->GetBVHTree()->Update( defPolyMesh_NodeSet );
// FOR HETriMeshOneModelMultiParts
//-------------------------------------------------
// Update for the model's internal simulation
for ( int i = 0; i < static_cast<int>( pPolygonalMeshObj->GetListOfParts().size() ); ++i ) {
pPolygonalMeshObj->GetPtrToPartNo(i)->UpdateStateToArray();
}
}
//---------------------------------------------------------------
if ( totalForce ) {
totalForce->SetXYZ( 0, 0, 0 );
Vector3<float> force( 0, 0, 0 );
for ( int i = 0; i < static_cast<int>( ListOfForces.size() ); ++i ) {
force += ListOfForces[i];
}
force *= gain;
(*totalForce).SetXYZ( force[0], force[1], force[2] );
}
return bResult;
}
Here is the call graph for this function:| bool CDR_Strand_vs_DeformMesh | ( | TAPs::OpenGL::ModelStrand< T > * | pStrandObj, |
| TAPs::DeformMesh< T > const *const | pDeformMeshObj | ||
| ) |
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.
| pStrandObj | a strand object |
| pDeformMeshObj | a deformable mesh object |
Definition at line 518 of file TAPsColDetFns.cpp.
References Length().
{
bool bResult = false;
//---------------------------------------------------------------
T distance, length;
int iClosestRow, iClosestCol;
Vector3<T> strandPos, skinPos;
int iNoRows;
int iNoCols;
pDeformMeshObj->GetNumberOfRowsAndColumns( iNoRows, iNoCols );
for ( int i = 0; i < pStrandObj->GetNumberOfLinks(); ++i ) {
iClosestRow = -1;
iClosestCol = -1;
distance = 0.1;
strandPos = pStrandObj->GetPointPosition( i );
for ( int r = 0; r < iNoRows; ++r ) {
for ( int c = 0; c < iNoCols; ++c ) {
skinPos = pDeformMeshObj->GetPositionOfPointNumber( r, c );
length = (strandPos - skinPos).Length();
if ( length < distance ) {
iClosestRow = r;
iClosestCol = c;
distance = length;
}
}
}
if ( iClosestRow >= 0 ) {
bResult = true;
pStrandObj->ChangeOnlyPointPositionByAddedWithThisVector( i, Vector3<T>( 0, 0.1, 0 ) );
}
}
//---------------------------------------------------------------
return bResult;
}
Here is the call graph for this function:| BEGIN_NAMESPACE_TAPs__CD__Fn bool CDR_Strand_vs_MBV | ( | TAPs::OpenGL::ModelStrand< T > * | pStrandObj, |
| TAPs::MultiBoundingVolume< T > const *const | pMBVObj, | ||
| TAPs::TransformationSupport< T > const *const | pTransform | ||
| ) |
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.
| pStrandObj | a strand object |
| pMBVObj | a multi bounding volume object |
| pTransform | an extra transformation for the MBV object |
Definition at line 23 of file TAPsColDetFns.cpp.
References BOUNDING_CYLINDER, BOUNDING_SPHERE, TransformationSupport< T >::GetMatrixRotation(), TransformationSupport< T >::GetMatrixTransform(), TransformationSupport< T >::GetTranslation(), Vector3< T >::Length(), and Vector3< T >::SetXYZ().
{
bool bResult = false;
//---------------------------------------------------------------
//bool isThePointInsideTheBV; // the pt is inside or outside the bv
Vector3<T> vDistance; // displacement vector
TransformationSupport<T> transform;
//---------------------------------------------------------------
if ( pTransform ) {
transform.ReturnMatrixTransform() *= pTransform->GetMatrixTransform();
}
//---------------------------------------------------------------
transform.ReturnMatrixTransform() *= pMBVObj->GetTransform().GetMatrixTransform();
TransformationSupport<T> savedTransform( transform );
//---------------------------------------------------------------
std::vector< BoundingVolume<T> * >::const_iterator pos = pMBVObj->GetBoundingVolumeList().begin();
//---------------------------------------------------------------
while ( pos != pMBVObj->GetBoundingVolumeList().end() ) {
assert( *pos != NULL );
vDistance.SetXYZ( 0, 0, 0 );
transform = savedTransform;
//-------------------------------------------------
transform.ReturnMatrixTransform() *= (*pos)->GetTransform().GetMatrixTransform();
//-------------------------------------------------
// Transform each vertex of the strand to the bounding volume coordinate
int iDeepestPoint = -1;
T tDeepestDistance = 9E60;
Vector3<T> vDirection;
Vector3<T> translation( transform.GetTranslation() );
Matrix3x3<T> inversedRotMatrix( transform.GetMatrixRotation().GetInverse() );
switch ( (*pos)->GetType() ) {
//---------------------------------------------
case TAPs::Enum::BOUNDING_CYLINDER:
//---------------------------------------------
#ifdef TAPs_STRAND_LOCK_SEGMENTS
for ( unsigned int s = 0; s < pStrandObj->GetNumSegments(); ++s ) {
// Skip locked or invisible segments
if ( pStrandObj->GetSegmentLockStatus(s) || !pStrandObj->GetSegmentVisibleStatus(s) ) {}
else {
for ( int i = pStrandObj->GetStartPtOfSegment(s); i <= pStrandObj->GetEndPtOfSegment(s); ++i )
#else //TAPs_STRAND_LOCK_SEGMENTS
{
{
for ( unsigned int i = 0; i <= pStrandObj->GetNumberOfLinks(); ++i )
#endif//TAPs_STRAND_LOCK_SEGMENTS
{
// If the point is fixed, do not move it.
if ( pStrandObj->GetFixStatusOfPtNo(i) ) continue;
//------------------------------------------------------
// In the local coordinate of the bounding cylinder,
// the cylinder axis is parallel to z-axis
// where it is shifted by the cylinder center.
// The cylinder has radius, height and center.
// Its height is measured from -z and +z axis
// where its center is situated between height/2 in -z and +z axis.
Vector3<T> location = pStrandObj->GetPointPosition(i);
location -= translation;
location = inversedRotMatrix * location;
// Shift the location of point by the cylinder center
// i.e. shift the cylinder to the origin (0,0,0)
location -= (*pos)->GetCenter();
//------------------------------------------------------
// Now the cylinder is centered at the origin with its axis on the z-axis
// where its height is from -height/2 to +height/2.
// And the input point has been transformed into the cylinder coordinate.
// The test can be performed.
if ( TAPs::CGMath<T>::CD_CylinderAtOrigin_vs_Point( (*pos)->GetRadius(), (*pos)->GetHeight(), location, vDistance ) )
{
bResult = true;
//-------------------------
// Now rotate it back by the rotation matrix (from the transform matrix).
// REMARK: Translation (from the transform matrix) is NOT applied back,
// because vDistance represents a displacement vector from
// the input point to the cylinder surface.
// I.e., the strand point is always in the world coordinates.
vDistance = transform.GetMatrixRotation() * vDistance;
//-------------------------
// This statement just ask the strand to move its collided points away
pStrandObj->ChangeOnlyPointPositionByAddedWithThisVector( i, vDistance );
T tDistance = vDistance.Length();
if ( tDeepestDistance > tDistance ) {
tDeepestDistance = tDistance;
iDeepestPoint = i;
vDirection = vDistance;
}
//-------------------------
}
}// Back to Next Strand Point
}
}
break;
// END: BOUNDING_CYLINDER
//---------------------------------------------
case TAPs::Enum::BOUNDING_SPHERE:
//---------------------------------------------
#ifdef TAPs_STRAND_LOCK_SEGMENTS
for ( unsigned int s = 0; s < pStrandObj->GetNumSegments(); ++s ) {
// Skip locked or invisible segments
if ( pStrandObj->GetSegmentLockStatus(s) || !pStrandObj->GetSegmentVisibleStatus(s) ) {}
else {
for ( int i = pStrandObj->GetStartPtOfSegment(s); i <= pStrandObj->GetEndPtOfSegment(s); ++i )
#else //TAPs_STRAND_LOCK_SEGMENTS
{
{
for ( unsigned int i = 0; i <= pStrandObj->GetNumberOfLinks(); ++i )
#endif//TAPs_STRAND_LOCK_SEGMENTS
{
// If the point is fixed, do not move it.
if ( pStrandObj->GetFixStatusOfPtNo(i) ) continue;
//------------------------------------------------------
// In the local coordinate of the bounding sphere centered at the origin
Vector3<T> location = pStrandObj->GetPointPosition(i);
location -= translation;
location = inversedRotMatrix * location;
// Shift the location of point by the sphere center
// i.e. shift the sphere to the origin (0,0,0)
location -= (*pos)->GetCenter();
//------------------------------------------------------
// Now the sphere is centered at the origin
// And the input point has been transformed into the sphere coordinate.
// The test can be performed.
if ( TAPs::CGMath<T>::CD_SphereAtOrigin_vs_Point( (*pos)->GetRadius(), location, vDistance ) )
{
bResult = true;
//-------------------------
// Now rotate it back by the rotation matrix (from the transform matrix).
// REMARK: Translation (from the transform matrix) is NOT applied back,
// because vDistance represents a displacement vector from
// the input point to the sphere surface.
// I.e., the strand point is always in the world coordinates.
vDistance = transform.GetMatrixRotation() * vDistance;
//-------------------------
// This statement just ask the strand to move its collided points away
pStrandObj->ChangeOnlyPointPositionByAddedWithThisVector( i, vDistance );
T tDistance = vDistance.Length();
if ( tDeepestDistance > tDistance ) {
tDeepestDistance = tDistance;
iDeepestPoint = i;
vDirection = vDistance;
}
//-------------------------
}
}// Back to Next Strand Point
}
}
break;
// END: BOUNDING_SPHERE
}//END: switch ( (*pos)->GetType() ) {...}
++pos; // Next Bounding Volume
}
return bResult;
}
Here is the call graph for this function:| bool CDR_Suture_vs_DeformMesh | ( | TAPs::OpenGL::ModelSuture< T > * | pSutureObj, |
| TAPs::DeformMesh< T > const *const | pDeformMeshObj | ||
| ) |
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.
| pSutureObj | a suture object |
| pDeformMeshObj | a deformable mesh object |
Definition at line 567 of file TAPsColDetFns.cpp.
References Length().
{
bool bResult = false;
//---------------------------------------------------------------
T distance, length;
int iClosestRow, iClosestCol;
Vector3<T> suturePos, skinPos;
int iNoRows;
int iNoCols;
pDeformMeshObj->GetNumberOfRowsAndColumns( iNoRows, iNoCols );
for ( int i = 0; i < pSutureObj->GetNumberOfStrandLinksWithoutNeedle(); ++i ) {
iClosestRow = -1;
iClosestCol = -1;
distance = 0.1;
suturePos = pSutureObj->GetPointPosition( i );
for ( int r = 0; r < iNoRows; ++r ) {
for ( int c = 0; c < iNoCols; ++c ) {
skinPos = pDeformMeshObj->GetPositionOfPointNumber( r, c );
length = (suturePos - skinPos).Length();
if ( length < distance ) {
iClosestRow = r;
iClosestCol = c;
distance = length;
}
}
}
if ( iClosestRow >= 0 ) {
bResult = true;
pSutureObj->ChangeOnlyPointPositionByAddedWithThisVector( i, Vector3<T>( 0, 0.1, 0 ) );
}
}
//---------------------------------------------------------------
return bResult;
}
Here is the call graph for this function:| bool CDR_Suture_vs_MBV | ( | TAPs::OpenGL::ModelSuture< T > * | pSutureObj, |
| TAPs::MultiBoundingVolume< T > const *const | pMBVObj, | ||
| TAPs::TransformationSupport< T > const *const | pTransform | ||
| ) |
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.
| pSutureObj | a suture object |
| pMBVObj | a multi bounding volume object |
| pTransform | an extra transformation for the MBV object |
Definition at line 340 of file TAPsColDetFns.cpp.
References BOUNDING_CYLINDER, BOUNDING_SPHERE, TransformationSupport< T >::GetMatrixRotation(), TransformationSupport< T >::GetMatrixTransform(), TransformationSupport< T >::GetTranslation(), Vector3< T >::Length(), and Vector3< T >::SetXYZ().
{
bool bResult = false;
//---------------------------------------------------------------
//bool isThePointInsideTheBV; // the pt is inside or outside the bv
Vector3<T> vDistance; // displacement vector
TransformationSupport<T> transform;
//---------------------------------------------------------------
if ( pTransform ) {
transform.ReturnMatrixTransform() *= pTransform->GetMatrixTransform();
}
//---------------------------------------------------------------
transform.ReturnMatrixTransform() *= pMBVObj->GetTransform().GetMatrixTransform();
TransformationSupport<T> savedTransform( transform );
//---------------------------------------------------------------
std::vector< BoundingVolume<T> * >::const_iterator pos = pMBVObj->GetBoundingVolumeList().begin();
//---------------------------------------------------------------
while ( pos != pMBVObj->GetBoundingVolumeList().end() ) {
assert( *pos != NULL );
vDistance.SetXYZ( 0, 0, 0 );
transform = savedTransform;
//-------------------------------------------------
transform.ReturnMatrixTransform() *= (*pos)->GetTransform().GetMatrixTransform();
//-------------------------------------------------
// Transform each vertex of the strand to the bounding volume coordinate
int iDeepestPoint = -1;
//T tDeepestDistance = Math<T>::MAX;
//T tDeepestDistance = std::numeric_limits<T>::max();
T tDeepestDistance = 5E32;
Vector3<T> vDirection;
Vector3<T> translation( transform.GetTranslation() );
Matrix3x3<T> inversedRotMatrix( transform.GetMatrixRotation().GetInverse() );
switch ( (*pos)->GetType() ) {
//---------------------------------------------
case TAPs::Enum::BOUNDING_CYLINDER:
//---------------------------------------------
#ifdef TAPs_STRAND_LOCK_SEGMENTS
for ( unsigned int s = 0; s < pSutureObj->GetNumSegments(); ++s ) {
// Skip locked or invisible segments
if ( pSutureObj->GetSegmentLockStatus(s) || !pSutureObj->GetSegmentVisibleStatus(s) ) {}
else {
for ( int i = pSutureObj->GetStartPtOfSegment(s); i <= pSutureObj->GetEndPtOfSegment(s); ++i )
#else //TAPs_STRAND_LOCK_SEGMENTS
{
{
for ( unsigned int i = 0; i <= pSutureObj->GetNumberOfStrandLinksWithoutNeedle(); ++i )
#endif//TAPs_STRAND_LOCK_SEGMENTS
{
// If the point is fixed, do not move it.
if ( pSutureObj->GetFixStatusOfPtNo(i) ) continue;
//------------------------------------------------------
// In the local coordinate of the bounding cylinder,
// the cylinder axis is parallel to z-axis
// where it is shifted by the cylinder center.
// The cylinder has radius, height and center.
// Its height is measured from -z and +z axis
// where its center is situated between height/2 in -z and +z axis.
Vector3<T> location = pSutureObj->GetPointPosition(i);
location -= translation;
location = inversedRotMatrix * location;
// Shift the location of point by the cylinder center
// i.e. shift the cylinder to the origin (0,0,0)
location -= (*pos)->GetCenter();
//------------------------------------------------------
// Now the cylinder is centered at the origin with its axis on the z-axis
// where its height is from -height/2 to +height/2.
// And the input point has been transformed into the cylinder coordinate.
// The test can be performed.
if ( TAPs::CGMath<T>::CD_CylinderAtOrigin_vs_Point( (*pos)->GetRadius(), (*pos)->GetHeight(), location, vDistance ) )
{
bResult = true;
//-------------------------
// Now rotate it back by the rotation matrix (from the transform matrix).
// REMARK: Translation (from the transform matrix) is NOT applied back,
// because vDistance represents a displacement vector from
// the input point to the cylinder surface.
// I.e., the suture point is always in the world coordinates.
vDistance = transform.GetMatrixRotation() * vDistance;
//-------------------------
// This statement just ask the strand to move its collided points away
pSutureObj->ChangeOnlyPointPositionByAddedWithThisVector( i, vDistance );
T tDistance = vDistance.Length();
if ( tDeepestDistance > tDistance ) {
tDeepestDistance = tDistance;
iDeepestPoint = i;
vDirection = vDistance;
}
//-------------------------
}
}// Back to Next Strand Point
}
}
break;
// END: BOUNDING_CYLINDER
//---------------------------------------------
case TAPs::Enum::BOUNDING_SPHERE:
//---------------------------------------------
#ifdef TAPs_STRAND_LOCK_SEGMENTS
for ( unsigned int s = 0; s < pSutureObj->GetNumSegments(); ++s ) {
// Skip locked or invisible segments
if ( pSutureObj->GetSegmentLockStatus(s) || !pSutureObj->GetSegmentVisibleStatus(s) ) {}
else {
for ( int i = pSutureObj->GetStartPtOfSegment(s); i <= pSutureObj->GetEndPtOfSegment(s); ++i )
#else //TAPs_STRAND_LOCK_SEGMENTS
{
{
for ( unsigned int i = 0; i <= pSutureObj->GetNumberOfStrandLinksWithoutNeedle(); ++i )
#endif//TAPs_STRAND_LOCK_SEGMENTS
{
// If the point is fixed, do not move it.
if ( pSutureObj->GetFixStatusOfPtNo(i) ) continue;
//------------------------------------------------------
// In the local coordinate of the bounding sphere centered at the origin
Vector3<T> location = pSutureObj->GetPointPosition(i);
location -= translation;
location = inversedRotMatrix * location;
// Shift the location of point by the sphere center
// i.e. shift the sphere to the origin (0,0,0)
location -= (*pos)->GetCenter();
//------------------------------------------------------
// Now the sphere is centered at the origin
// And the input point has been transformed into the sphere coordinate.
// The test can be performed.
if ( TAPs::CGMath<T>::CD_SphereAtOrigin_vs_Point( (*pos)->GetRadius(), location, vDistance ) )
{
bResult = true;
//-------------------------
// Now rotate it back by the rotation matrix (from the transform matrix).
// REMARK: Translation (from the transform matrix) is NOT applied back,
// because vDistance represents a displacement vector from
// the input point to the sphere surface.
// I.e., the suture point is always in the world coordinates.
vDistance = transform.GetMatrixRotation() * vDistance;
//-------------------------
// This statement just ask the strand to move its collided points away
pSutureObj->ChangeOnlyPointPositionByAddedWithThisVector( i, vDistance );
T tDistance = vDistance.Length();
if ( tDeepestDistance > tDistance ) {
tDeepestDistance = tDistance;
iDeepestPoint = i;
vDirection = vDistance;
}
//-------------------------
}
}// Back to Next Strand Point
}
}
break;
// END: BOUNDING_SPHERE
}//END: switch ( (*pos)->GetType() ) {...}
++pos; // Next Bounding Volume
}
return bResult;
}
Here is the call graph for this function:| bool CDRigid_PolygonalMesh_vs_MBV | ( | TAPs::OpenGL::HETriMeshOneModelMultiParts< T > * | pPolygonalMeshObj, |
| TAPs::MultiBoundingVolume< T > const *const | pMBVObj, | ||
| TAPs::Vector3< T > * | totalForce, | ||
| T | gain | ||
| ) |
| pPolygonalMeshObj | a HETriMeshOneModelMultiParts object |
| pMBVObj | a multi bounding volume object |
| totalForce | total force |
| gain | gain |
Definition at line 2389 of file TAPsColDetFns.cpp.
References BOUNDING_CYLINDER, BOUNDING_SPHERE, CDScaleForSphereBVWithTriangle, TransformationSupport< T >::GetMatrixTransform(), HEFace< T >::GetPtrsToVerticesAndNumberOfVertices(), Matrix4x4< T >::Inversed(), Length(), ListOfContactPts, ListOfForces, TransformationSupport< T >::SetMatrixTransform(), and Vector3< T >::SetXYZ().
{
ListOfContactPts.clear();
ListOfForces.clear();
#ifdef TAPs_DEBUG_COLLISION_DETECTION
pPolygonalMeshObj->GetBVHTree()->ClearFlags();
#endif//TAPs_DEBUG_COLLISION_DETECTION
//#ifdef TAPs_DEBUG_MODE
//std::cout << "CDR_PolygonalMesh_vs_MBV( HalfEdgeModel<T>, MultiBoundingVolume<T> )\n";
//#endif//TAPs_DEBUG_MODE
//std::cout << "BVHTree: " << *(pPolygonalMeshObj->GetBVHTree()) << "\n";
bool bResult = false;
// Collision Detection
bResult = pPolygonalMeshObj->GetBVHTree()->TestOverlapWithTillLeafNodes( pMBVObj );
//---------------------------------------------------------------
// Collision Response
if ( bResult ) {
// Reset the result for primitive-primitive test,
// because the previous result is only from bounding volume test.
bResult = false;
//-------------------------------------------------
//T separateDistanceConstraint;
Vector3<T> N, centerA;
//T separateDistance;
HEFace<T> * primB;
std::vector< HEVertex<T> * const > vertexList;
int noOfVertices;
//-------------------------------------------------
TransformationSupport<T> trxMBV( pMBVObj->GetTransform() );
//-------------------------------------------------
std::set< BVHNode<T> * > defPolyMesh_NodeSet;
// Get the list of collided nodes and bounding volumes
std::vector< BVsAndNodesList<T> > * bvList = &pPolygonalMeshObj->GetBVHTree()->GetListOfCollidedBoundingVolumesAndNodes();
//-------------------------------------------------
// Traverse the list of bounding volumes
std::vector< BVsAndNodesList<T> >::const_iterator pos = bvList->begin();
//-------------------------------------------------
// Mesh's inverse transformation
Matrix4x4<T> trxInvMesh = pPolygonalMeshObj->GetTransform().GetMatrixTransform();
trxInvMesh.Inversed();
Vector3<T> vOrigin( (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(0,0,0,1)).GetVector3() );
while ( pos != bvList->end() ) {
//int count = 0;
// Store the transformation of the bounding volume including the mesh's inverse transformation
TransformationSupport<T> trx = (*pos).BV->GetTransform();
(*pos).BV->GetTransform().SetMatrixTransform( trxInvMesh * trxMBV.GetMatrixTransform() * trx.GetMatrixTransform() );
//-----------------------------------------
// Deform the deformable polygonal mesh away from the rigid polygonal mesh
switch ( (*pos).BV->GetType() ) {
case TAPs::Enum::BOUNDING_SPHERE:
{
//std::cout << "BV: " << (*pos).BV->GetName() << "\n";
// For Test against triangle
//---------------------------------------------
// Transform the BV due to its transformation, center, and radius
T radiusOfBV = (*pos).BV->GetRadius();
Vector3<T> C( (*pos).BV->GetCenter() );
Matrix4x4<T> translation( 1, 0, 0, C[0],
0, 1, 0, C[1],
0, 0, 1, C[2],
0, 0, 0, 1 );
Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV );
Matrix4x4<T> scale( S[0], 0, 0, 0,
0, S[1], 0, 0,
0, 0, S[2], 0,
0, 0, 0, 1 );
// The BV's current transformation includes the mesh's inverse transformation (see the code above)
Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale;
// BV Sphere's center and radius after the whole transformation from
// BV's transformation to mesh's inverse transformation.
// I.e., transforming the BV to mesh's coordinate
Vector3<T> centerOfBV_inMeshCoord = (mat * Vector4<T>(0,0,0,1)).GetVector3();
T radiusOfBV_inMeshCoord = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV_inMeshCoord ).Length();
// Inverse the mesh's transformation to the BV's pure transformation
mat = pPolygonalMeshObj->GetTransform().GetMatrixTransform() * mat;
// BV Sphere's center and radius after the BV's pure transformation
Vector3<T> centerOfBV( (mat * Vector4<T>(0,0,0,1)).GetVector3() );
radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length();
//---------------------------------------------
//count = 0;
for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) {
bool testResult = false;
// Assume triangle is in Sphere Node
// Test the triangle in sphere node with BVSphere
primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace();
vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices );
Vector3<T> cdrVec[3];
//*
// Test against each vertex in the triangle
//-----------------------------------
for ( int j = 0; j < noOfVertices; ++j ) {
if( (*pos).BV->TestPointLocation( vertexList[j]->GetPosition(), &(cdrVec[j]) ) )
{
//vertexList[j]->SetPosition( vertexList[j]->GetPosition() + cdrVec[j] );
Vector3<T> force( (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(cdrVec[j])).GetVector3() - vOrigin );
//ListOfContactPts.push_back( Vector3<GLfloat>( (*pos).BV->GetCenter()[0], (*pos).BV->GetCenter()[1], (*pos).BV->GetCenter()[2] ) );
ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) );
ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) );
testResult = true;
}
}
//-----------------------------------
//*/
//*
// Test against triangle
//-----------------------------------
//Vector3<T> contactPt;
if ( TAPs::CGMath<T>::FindIntersectionSphereTriangle(
centerOfBV_inMeshCoord, radiusOfBV_inMeshCoord, // BVSphere properties
vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices
cdrVec[0], cdrVec[1], cdrVec[2] // out vectors
//, &contactPt
) ) {
Vector3<T> force_1( cdrVec[0] * CDScaleForSphereBVWithTriangle );
Vector3<T> force_2( cdrVec[1] * CDScaleForSphereBVWithTriangle );
Vector3<T> force_3( cdrVec[2] * CDScaleForSphereBVWithTriangle );
//vertexList[0]->SetPosition( vertexList[0]->GetPosition() + force_1 );
//vertexList[1]->SetPosition( vertexList[1]->GetPosition() + force_2 );
//vertexList[2]->SetPosition( vertexList[2]->GetPosition() + force_3 );
force_1 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_1)).GetVector3() - vOrigin;
force_2 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_2)).GetVector3() - vOrigin;
force_3 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_3)).GetVector3() - vOrigin;
//ListOfContactPts.push_back( Vector3<GLfloat>( contactPt[0], contactPt[1], contactPt[2] ) );
ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) );
Vector3<T> force( ( force_1 + force_2 + force_3 )/3 );
ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) );
testResult = true;
}
//-----------------------------------
//*/
//std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n";
// List of BVNodes to be updated
if ( testResult ) {
defPolyMesh_NodeSet.insert( (*pos).NodeList[i] );
bResult = true;
}
}
}
break;
case TAPs::Enum::BOUNDING_CYLINDER:
{
//std::cout << "BV: " << (*pos).BV->GetName() << "\n";
// For Test against triangle
//---------------------------------------------
// Transform the BV due to its transformation, center, and radius
T radiusOfBV = (*pos).BV->GetRadius();
Vector3<T> C( (*pos).BV->GetCenter() );
Matrix4x4<T> translation( 1, 0, 0, C[0],
0, 1, 0, C[1],
0, 0, 1, C[2],
0, 0, 0, 1 );
Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV );
Matrix4x4<T> scale( S[0], 0, 0, 0,
0, S[1], 0, 0,
0, 0, S[2], 0,
0, 0, 0, 1 );
// The BV's current transformation includes the mesh's inverse transformation (see the code above)
Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale;
// BV Sphere's center and radius after the whole transformation from
// BV's transformation to mesh's inverse transformation.
// I.e., transforming the BV to mesh's coordinate
T halfHeightOfBV = (*pos).BV->GetHeight() / 2.0;
Vector3<T> centerOfBV_inMeshCoord = (mat * Vector4<T>(0,0,0,1)).GetVector3();
T radiusOfBV_inMeshCoord = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV_inMeshCoord ).Length();
Vector3<T> topPtOfBV_inMeshCoord( (mat * Vector4<T>(0,0,halfHeightOfBV,1)).GetVector3() );
Vector3<T> bottomPtOfBV_inMeshCoord( (mat * Vector4<T>(0,0,-halfHeightOfBV,1)).GetVector3() );
// Inverse the mesh's transformation to the BV's pure transformation
mat = pPolygonalMeshObj->GetTransform().GetMatrixTransform() * mat;
// BV Sphere's center and radius after the BV's pure transformation
Vector3<T> centerOfBV( (mat * Vector4<T>(0,0,0,1)).GetVector3() );
radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length();
Vector3<T> topPtOfBV( (mat * Vector4<T>(0,0,halfHeightOfBV,1)).GetVector3() );
Vector3<T> bottomPtOfBV( (mat * Vector4<T>(0,0,-halfHeightOfBV,1)).GetVector3() );
//---------------------------------------------
//count = 0;
for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) {
bool testResult = false;
// Assume triangle is in Sphere Node
// Test the triangle in sphere node with BVCylinder
primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace();
vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices );
Vector3<T> cdrVec[3];
//*
// Test against each vertex in the triangle
//-----------------------------------
for ( int j = 0; j < noOfVertices; ++j ) {
if( (*pos).BV->TestPointLocation( vertexList[j]->GetPosition(), &(cdrVec[j]) ) )
{
//vertexList[j]->SetPosition( vertexList[j]->GetPosition() + cdrVec[j] );
Vector3<T> force( (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(cdrVec[j])).GetVector3() - vOrigin );
//ListOfContactPts.push_back( Vector3<GLfloat>( (*pos).BV->GetCenter()[0], (*pos).BV->GetCenter()[1], (*pos).BV->GetCenter()[2] ) );
ListOfContactPts.push_back( Vector3<GLfloat>( centerOfBV[0], centerOfBV[1], centerOfBV[2] ) );
ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) );
testResult = true;
}
}
//-----------------------------------
//*/
//*
// Test against triangle
//-----------------------------------
Vector3<T> contactPt;
if ( TAPs::CGMath<T>::FindIntersectionCylinderTriangle(
topPtOfBV_inMeshCoord, bottomPtOfBV_inMeshCoord, radiusOfBV_inMeshCoord, // BVCylinder properties
vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices
cdrVec[0], cdrVec[1], cdrVec[2] // out vectors
, &contactPt
) ) {
Vector3<T> force_1( cdrVec[0] * CDScaleForSphereBVWithTriangle );
Vector3<T> force_2( cdrVec[1] * CDScaleForSphereBVWithTriangle );
Vector3<T> force_3( cdrVec[2] * CDScaleForSphereBVWithTriangle );
//vertexList[0]->SetPosition( vertexList[0]->GetPosition() + force_1 );
//vertexList[1]->SetPosition( vertexList[1]->GetPosition() + force_2 );
//vertexList[2]->SetPosition( vertexList[2]->GetPosition() + force_3 );
force_1 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_1)).GetVector3() - vOrigin;
force_2 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_2)).GetVector3() - vOrigin;
force_3 = (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(force_3)).GetVector3() - vOrigin;
contactPt = ( (pPolygonalMeshObj->GetTransform().GetMatrixTransform() * Vector4<T>(contactPt)).GetVector3() );
ListOfContactPts.push_back( Vector3<GLfloat>( contactPt[0], contactPt[1], contactPt[2] ) );
Vector3<T> force( ( force_1 + force_2 + force_3 )/3 );
ListOfForces.push_back( Vector3<GLfloat>( force[0], force[1], force[2] ) );
testResult = true;
}
//-----------------------------------
//*/
//std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n";
// List of BVNodes to be updated
if ( testResult ) {
defPolyMesh_NodeSet.insert( (*pos).NodeList[i] );
bResult = true;
}
}
}
break;
default:
std::cout << "CDRigid_PolygonalMesh_vs_MBV of BV Type (" << (*pos).BV->GetType() << ") doesn't support!\n";
break;
}
// Restore the transformation of the bounding volume
//(*pos).BV->GetTransform().SetMatrixTransform( trx.GetMatrixTransform() );
(*pos).BV->SetTransform( trx );
// Next Bounding Volume
++pos;
}
//-------------------------------------------------
//-------------------------------------------------
// Update Normals of Deformable Polygonal Mesh
//pPolygonalMeshObj->CalAndSetNormals(); // commented out to rely on AdvanceSimulation to update the normals
//-------------------------------------------------
// Update Bounding Volume Hierarchy of Deformable Polygonal Mesh
//pPolygonalMeshObj->GetBVHTree()->Update( defPolyMesh_NodeSet );
// FOR HETriMeshOneModelMultiParts
//-------------------------------------------------
// Update for the model's internal simulation
//for ( int i = 0; i < static_cast<int>( pPolygonalMeshObj->GetListOfParts().size() ); ++i ) {
// pPolygonalMeshObj->GetPtrToPartNo(i)->UpdateStateToArray();
//}
}
//---------------------------------------------------------------
if ( totalForce ) {
totalForce->SetXYZ( 0, 0, 0 );
Vector3<float> force( 0, 0, 0 );
for ( int i = 0; i < static_cast<int>( ListOfForces.size() ); ++i ) {
force += ListOfForces[i];
}
force *= gain;
(*totalForce).SetXYZ( force[0], force[1], force[2] );
}
return bResult;
}
Here is the call graph for this function:| bool CDRigid_PolygonalMesh_vs_MBV | ( | TAPs::OpenGL::HalfEdgeModel< T > * | pPolygonalMeshObj, |
| TAPs::MultiBoundingVolume< T > const *const | pMBVObj | ||
| ) |
Collision detection 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 does not resolve the collision. It returns the total collision force.
| pPolygonalMeshObj | a HalfEdgeModel object |
| pMBVObj | a multi bounding volume object |
Definition at line 1767 of file TAPsColDetFns.cpp.
References BOUNDING_CYLINDER, BOUNDING_SPHERE, TransformationSupport< T >::GetMatrixTransform(), HEFace< T >::GetPtrsToVerticesAndNumberOfVertices(), Matrix4x4< T >::Inversed(), Length(), and TransformationSupport< T >::SetMatrixTransform().
{
#ifdef TAPs_DEBUG_COLLISION_DETECTION
pPolygonalMeshObj->GetBVHTree()->ClearFlags();
#endif//TAPs_DEBUG_COLLISION_DETECTION
//#ifdef TAPs_DEBUG_MODE
std::cout << "CDR_PolygonalMesh_vs_MBV( HalfEdgeModel<T>, MultiBoundingVolume<T> )\n";
//#endif//TAPs_DEBUG_MODE
std::cout << "BVHTree: " << *(pPolygonalMeshObj->GetBVHTree()) << "\n";
bool bResult = false;
// Collision Detection
bResult = pPolygonalMeshObj->GetBVHTree()->TestOverlapWithTillLeafNodes( pMBVObj );
//---------------------------------------------------------------
// Collision Response
if ( bResult ) {
// Reset the result for primitive-primitive test,
// because the previous result is only from bounding volume test.
bResult = false;
//-------------------------------------------------
T separateDistanceConstraint;
Vector3<T> N, centerA;
T separateDistance;
HEFace<T> * primB;
std::vector< HEVertex<T> * const > vertexList;
int noOfVertices;
//-------------------------------------------------
TransformationSupport<T> trxMBV; // default constructor is an identity transformation
trxMBV = pMBVObj->GetTransform();
//-------------------------------------------------
std::set< BVHNode<T> * > defPolyMesh_NodeSet;
// Get the list of collided nodes and bounding volumes
std::vector< BVsAndNodesList<T> > * bvList = &pPolygonalMeshObj->GetBVHTree()->GetListOfCollidedBoundingVolumesAndNodes();
//-------------------------------------------------
// Traverse the list of bounding volumes
std::vector< BVsAndNodesList<T> >::const_iterator pos = bvList->begin();
//-------------------------------------------------
//std::cout << "CDR_PolygonalMesh_vs_MBV(...) for HalfEdgeModel --> \n";
//std::cout << "\tCASE: the polygonal mesh object's transformation is on. -- NOT IMPLEMENTED YET!\n";
// Mesh's inverse transformation
Matrix4x4<T> trxInvMesh = pPolygonalMeshObj->GetTransform().GetMatrixTransform();
trxInvMesh.Inversed();
while ( pos != bvList->end() ) {
int count = 0;
// Store the transformation of the bounding volume including the mesh's inverse transformation
TransformationSupport<T> trx = (*pos).BV->GetTransform();
(*pos).BV->GetTransform().SetMatrixTransform( trxInvMesh * trxMBV.GetMatrixTransform() * trx.GetMatrixTransform() );
//-----------------------------------------
// Deform the deformable polygonal mesh away from the rigid polygonal mesh
switch ( (*pos).BV->GetType() ) {
case TAPs::Enum::BOUNDING_SPHERE:
{
std::cout << "BV: " << (*pos).BV->GetName() << "\n";
// For Test against triangle
//---------------------------------------------
// Transform the BV due to its transformation, center, and radius
T radiusOfBV = (*pos).BV->GetRadius();
Vector3<T> C( (*pos).BV->GetCenter() );
Matrix4x4<T> translation( 1, 0, 0, C[0],
0, 1, 0, C[1],
0, 0, 1, C[2],
0, 0, 0, 1 );
Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV );
Matrix4x4<T> scale( S[0], 0, 0, 0,
0, S[1], 0, 0,
0, 0, S[2], 0,
0, 0, 0, 1 );
// The BV's current transformation includes the mesh's inverse transformation (see the code above)
Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale;
// BV Sphere's center and radius after the whole transformation from
// BV's transformation to mesh's inverse transformation.
// I.e., transforming the BV to mesh's coordinate
Vector3<T> centerOfBV_inMeshCoord = (mat * Vector4<T>(0,0,0,1)).GetVector3();
T radiusOfBV_inMeshCoord = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV_inMeshCoord ).Length();
// Inverse the mesh's transformation to the BV's pure transformation
mat = pPolygonalMeshObj->GetTransform().GetMatrixTransform() * mat;
// BV Sphere's center and radius after the BV's pure transformation
Vector3<T> centerOfBV( (mat * Vector4<T>(0,0,0,1)).GetVector3() );
radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length();
//---------------------------------------------
count = 0;
for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) {
bool testResult = false;
// Assume triangle is in Sphere Node
// Test the triangle in sphere node with BVSphere
primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace();
vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices );
Vector3<T> cdrVec[3];
//*
// Test against each vertex in the triangle
//-----------------------------------
for ( int j = 0; j < noOfVertices; ++j ) {
if( (*pos).BV->TestPointLocation( vertexList[j]->GetPosition(), &(cdrVec[j]) ) )
{
//vertexList[j]->SetPosition( vertexList[j]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[j])).GetVector3() );
testResult = true;
}
}
//-----------------------------------
//*/
//*
// Test against triangle
//-----------------------------------
//Vector3<T> contactPt;
if ( TAPs::CGMath<T>::FindIntersectionSphereTriangle(
centerOfBV_inMeshCoord, radiusOfBV_inMeshCoord, // BVSphere properties
vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices
cdrVec[0], cdrVec[1], cdrVec[2] // out vectors
//, &contactPt
) ) {
//vertexList[0]->SetPosition( vertexList[0]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[0])).GetVector3()*CDScaleForSphereBVWithTriangle );
//vertexList[1]->SetPosition( vertexList[1]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[1])).GetVector3()*CDScaleForSphereBVWithTriangle );
//vertexList[2]->SetPosition( vertexList[2]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[2])).GetVector3()*CDScaleForSphereBVWithTriangle );
testResult = true;
}
//-----------------------------------
//*/
std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n";
// List of BVNodes to be updated
if ( testResult ) {
defPolyMesh_NodeSet.insert( (*pos).NodeList[i] );
bResult = true;
}
}
}
break;
case TAPs::Enum::BOUNDING_CYLINDER:
{
std::cout << "BV: " << (*pos).BV->GetName() << "\n";
// For Test against triangle
//---------------------------------------------
// Transform the BV due to its transformation, center, and radius
T radiusOfBV = (*pos).BV->GetRadius();
Vector3<T> C( (*pos).BV->GetCenter() );
Matrix4x4<T> translation( 1, 0, 0, C[0],
0, 1, 0, C[1],
0, 0, 1, C[2],
0, 0, 0, 1 );
Vector3<T> S( radiusOfBV, radiusOfBV, radiusOfBV );
Matrix4x4<T> scale( S[0], 0, 0, 0,
0, S[1], 0, 0,
0, 0, S[2], 0,
0, 0, 0, 1 );
// The BV's current transformation includes the mesh's inverse transformation (see the code above)
Matrix4x4<T> mat = (*pos).BV->GetTransform().GetMatrixTransform() * translation * scale;
// BV Sphere's center and radius after the whole transformation from
// BV's transformation to mesh's inverse transformation.
// I.e., transforming the BV to mesh's coordinate
T halfHeightOfBV = (*pos).BV->GetHeight() / 2.0;
Vector3<T> centerOfBV_inMeshCoord = (mat * Vector4<T>(0,0,0,1)).GetVector3();
T radiusOfBV_inMeshCoord = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV_inMeshCoord ).Length();
Vector3<T> topPtOfBV_inMeshCoord( (mat * Vector4<T>(0,0,halfHeightOfBV,1)).GetVector3() );
Vector3<T> bottomPtOfBV_inMeshCoord( (mat * Vector4<T>(0,0,-halfHeightOfBV,1)).GetVector3() );
// Inverse the mesh's transformation to the BV's pure transformation
mat = pPolygonalMeshObj->GetTransform().GetMatrixTransform() * mat;
// BV Sphere's center and radius after the BV's pure transformation
Vector3<T> centerOfBV( (mat * Vector4<T>(0,0,0,1)).GetVector3() );
radiusOfBV = ( (mat * Vector4<T>(1,0,0,1)) - centerOfBV ).Length();
Vector3<T> topPtOfBV( (mat * Vector4<T>(0,0,halfHeightOfBV,1)).GetVector3() );
Vector3<T> bottomPtOfBV( (mat * Vector4<T>(0,0,-halfHeightOfBV,1)).GetVector3() );
//---------------------------------------------
count = 0;
for ( int i = 0; i < static_cast<int>( (*pos).NodeList.size() ); ++i ) {
bool testResult = false;
// Assume triangle is in Sphere Node
// Test the triangle in sphere node with BVCylinder
primB = (*pos).NodeList[i]->GetAPrimitiveHalfEdgeFace();
vertexList = primB->GetPtrsToVerticesAndNumberOfVertices( noOfVertices );
Vector3<T> cdrVec[3];
//*
// Test against each vertex in the triangle
//-----------------------------------
for ( int j = 0; j < noOfVertices; ++j ) {
if( (*pos).BV->TestPointLocation( vertexList[j]->GetPosition(), &(cdrVec[j]) ) )
{
//vertexList[j]->SetPosition( vertexList[j]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[j])).GetVector3() );
testResult = true;
}
}
//-----------------------------------
//*/
//*
// Test against triangle
//-----------------------------------
if ( TAPs::CGMath<T>::FindIntersectionCylinderTriangle(
topPtOfBV_inMeshCoord, bottomPtOfBV_inMeshCoord, radiusOfBV_inMeshCoord, // BVCylinder properties
vertexList[0]->GetPosition(), vertexList[1]->GetPosition(), vertexList[2]->GetPosition(), // triangle vertices
cdrVec[0], cdrVec[1], cdrVec[2] // out vectors
) ) {
//vertexList[0]->SetPosition( vertexList[0]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[0])).GetVector3()*CDScaleForCylinderBVWithTriangle );
//vertexList[1]->SetPosition( vertexList[1]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[1])).GetVector3()*CDScaleForCylinderBVWithTriangle );
//vertexList[2]->SetPosition( vertexList[2]->GetPosition() + (trxInvMesh * Vector4<T>(cdrVec[2])).GetVector3()*CDScaleForCylinderBVWithTriangle );
testResult = true;
}
//-----------------------------------
//*/
std::cout << "\t\tCount#" << ++count << ": " << (*pos).NodeList[i] << "\n";
// List of BVNodes to be updated
if ( testResult ) {
defPolyMesh_NodeSet.insert( (*pos).NodeList[i] );
bResult = true;
}
}
}
break;
default:
std::cout << "CDR_PolygonalMesh_vs_MBV of BV Type (" << (*pos).BV->GetType() << ") doesn't support!\n";
break;
}
// Restore the transformation of the bounding volume
(*pos).BV->SetTransform( trx );
// Next Bounding Volume
++pos;
}
//-------------------------------------------------
//-------------------------------------------------
// Update Normals of Deformable Polygonal Mesh
//pPolygonalMeshObj->CalAndSetNormals();
//-------------------------------------------------
// Update Bounding Volume Hierarchy of Deformable Polygonal Mesh
//pPolygonalMeshObj->GetBVHTree()->Update( defPolyMesh_NodeSet );
}
//---------------------------------------------------------------
return bResult;
}
Here is the call graph for this function: