Added support for separating axis test for polyhedral shapes

Added initial support for polyhedral contact clipping. 
This clipping takes a separating normal, that can be computed using either SAT or GJK/EPA.
To enable clipping, use btPolyhedralConvexShape::initializePolyhedralFeatures(); (needs to be enabled for both convex shapes)
No concave trimesh support for SAT/clipping yet. To enable SAT, see the toggle in btConvexConvexAlgorithm.
Fixes in contact normal in btGjkPairDetector. Hopefully this doesn't cause any regression (we need unit tests!)
This commit is contained in:
erwin.coumans
2011-03-29 08:52:18 +00:00
parent 1f5af32203
commit 784e7fdb39
10 changed files with 824 additions and 8 deletions

View File

@@ -48,7 +48,7 @@ subject to the following restrictions:
#include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h"
#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
#include "BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.h"
///////////
@@ -330,7 +330,6 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
}
#endif //BT_DISABLE_CAPSULE_CAPSULE_COLLIDER
#ifdef USE_SEPDISTANCE_UTIL2
if (dispatchInfo.m_useConvexConservativeDistanceUtil)
{
@@ -389,6 +388,54 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
}
#endif //USE_SEPDISTANCE_UTIL2
if (min0->isPolyhedral() && min1->isPolyhedral())
{
btPolyhedralConvexShape* polyhedronA = (btPolyhedralConvexShape*) min0;
btPolyhedralConvexShape* polyhedronB = (btPolyhedralConvexShape*) min1;
if (polyhedronA->getConvexPolyhedron() && polyhedronB->getConvexPolyhedron())
{
btScalar maxDist = 0.f;
if (dispatchInfo.m_convexMaxDistanceUseCPT)
{
maxDist = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactProcessingThreshold();
} else
{
maxDist = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold();
}
maxDist =0.f;
btVector3 sepNormalWorldSpace;
//#define USE_SAT_TEST
#ifdef USE_SAT_TEST
bool foundSepAxis = btPolyhedralContactClipping::findSeparatingAxis(
*polyhedronA->getConvexPolyhedron(), *polyhedronB->getConvexPolyhedron(),
body0->getWorldTransform(),
body1->getWorldTransform(),
sepNormalWorldSpace);
#else
bool foundSepAxis = true;
sepNormalWorldSpace = gjkPairDetector.getCachedSeparatingAxis().normalized();
#endif //USE_SAT_TEST
if (foundSepAxis)
{
btPolyhedralContactClipping::clipFaceContacts(sepNormalWorldSpace, *polyhedronA->getConvexPolyhedron(), *polyhedronB->getConvexPolyhedron(),
body0->getWorldTransform(),
body1->getWorldTransform(), maxDist, *resultOut);
if (m_ownManifold)
{
resultOut->refreshContactPoints();
}
return;
}
}
}
//now perform 'm_numPerturbationIterations' collision queries with the perturbated collision objects
//perform perturbation when more then 'm_minimumPointsPerturbationThreshold' points