TAPs 0.7.7.3
TAPsColDetFns.cpp File Reference
#include "TAPsColDetFns.hpp"
Include dependency graph for TAPsColDetFns.cpp:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Namespaces

namespace  Private

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.

Function Documentation

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.

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

Parameters:
pPolygonalMeshObja HalfEdgeModel object
ptAthe starting point of a line segment
ptBthe ending point of a line segment
listOfIntersectedPointsO/P: list of intersected points
listOfIntersectedFacesO/P: list of intersected faces
listOfClosestVerticesO/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:

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.

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.

Parameters:
pPolygonalMeshObja HalfEdgeModel object
ptAthe starting point of a line segment
ptBthe ending point of a line segment
listOfIntersectedPointsO/P: list of intersected points
listOfIntersectedFacesO/P: list of intersected faces
listOfClosestVerticesO/P: list of closest vertices
listOfRatiosO/P: list of ratios of the closest vertices relative to the line segment [0(ptA)-1(ptB)]
listOfIntersectionAnglesO/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:

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.

The function returns true if collision occurs. The function moves the deformable mesh to resolve the collision. The multi bounding volume object is unaffected.

Parameters:
pDeformMeshObja deformable mesh object
pMBVObja multi bounding volume object
pTransforman 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:

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.

Each polygonal mesh model can be an instance of PolygonalModel, XPolygonalModel, or HalfEdgeModel. The function returns true if collision occurs. The function deforms the deformable polygonal mesh model to resolve the collision. The rigid polygonal mesh model is unaffected.

Parameters:
pDefPolyMesha deformable polygonal mesh model
pRigidPolyMesha 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:

template<typename T >
bool CDR_PolygonalMesh_vs_BV ( TAPs::OpenGL::HETriMeshOneModelMultiParts< T > *  pPolygonalMeshObj,
TAPs::BoundingVolume< T > const *const  pBVObj 
)
Parameters:
pPolygonalMeshObja HETriMeshOneModelMultiParts object
pBVObja 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:

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.

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.

Parameters:
pPolygonalMeshObja HalfEdgeModel object
pBVObja 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:

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.

The polygonal mesh model can be an instance of PolygonalModel, XPolygonalModel, or HalfEdgeModel. The function returns true if collision occurs. The function deforms the polygonal mesh model to resolve the collision. The multi bounding volume object is unaffected.

Parameters:
pPolygonalMeshObja HalfEdgeModel object
pMBVObja 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:

template<typename T >
bool CDR_PolygonalMesh_vs_MBV ( TAPs::OpenGL::HETriMeshOneModelMultiParts< T > *  pPolygonalMeshObj,
TAPs::MultiBoundingVolume< T > const *const  pMBVObj,
TAPs::Vector3< T > *  totalForce,
gain 
)
Parameters:
pPolygonalMeshObja HETriMeshOneModelMultiParts object
pMBVObja multi bounding volume object
totalForcetotal force
gaingain

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:

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

The function returns true if collision occurs. The function moves the strand to resolve the collision. The deformable mesh object is unaffected.

Parameters:
pStrandObja strand object
pDeformMeshObja 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:

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.

The function returns true if collision occurs. The function moves the strand to resolve the collision. The multi bouding volume is unaffected.

Parameters:
pStrandObja strand object
pMBVObja multi bounding volume object
pTransforman 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:

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

The function returns true if collision occurs. The function moves the suture to resolve the collision. The deformable mesh object is unaffected.

Parameters:
pSutureObja suture object
pDeformMeshObja 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:

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.

The function returns true if collision occurs. The function moves the suture to resolve the collision. The multi bouding volume is unaffected.

Parameters:
pSutureObja suture object
pMBVObja multi bounding volume object
pTransforman 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:

template<typename T >
bool CDRigid_PolygonalMesh_vs_MBV ( TAPs::OpenGL::HETriMeshOneModelMultiParts< T > *  pPolygonalMeshObj,
TAPs::MultiBoundingVolume< T > const *const  pMBVObj,
TAPs::Vector3< T > *  totalForce,
gain 
)
Parameters:
pPolygonalMeshObja HETriMeshOneModelMultiParts object
pMBVObja multi bounding volume object
totalForcetotal force
gaingain

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:

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.

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.

Parameters:
pPolygonalMeshObja HalfEdgeModel object
pMBVObja 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:

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines