Share btGjkPairDetector, btGjkEpa2, btVoronoiSimplexSolver with SPU/Multithreaded implementation (remove duplicate code)

Make btTypedConstraint and btPersistentManifold both derive from btTypedObject to make SPU-side generic constraint solver easier.

Note: all build systems need to be updated: remove SpuVoronoiSimplexSolver.cpp, SpuGjkPairDetector.cpp, SpuEpaPenetrationDepthSolver.cpp, SpuGjkEpa2.cpp
This commit is contained in:
erwin.coumans
2009-08-07 08:57:56 +00:00
parent 5d2cf447e4
commit aef97d6015
30 changed files with 283 additions and 2505 deletions

View File

@@ -96,7 +96,7 @@ bool btContinuousConvexCollision::calcTimeOfImpact(
{
btGjkPairDetector gjk(m_convexA,m_convexB,m_simplexSolver,m_penetrationDepthSolver);
btGjkPairDetector gjk(m_convexA,m_convexB,m_convexA->getShapeType(),m_convexB->getShapeType(),m_convexA->getMargin(),m_convexB->getMargin(),m_simplexSolver,m_penetrationDepthSolver);
btGjkPairDetector::ClosestPointInput input;
//we don't use margins during CCD

View File

@@ -14,8 +14,8 @@ subject to the following restrictions:
*/
#ifndef CONVEX_PENETRATION_DEPTH_H
#define CONVEX_PENETRATION_DEPTH_H
#ifndef __CONVEX_PENETRATION_DEPTH_H
#define __CONVEX_PENETRATION_DEPTH_H
class btStackAlloc;
class btVector3;

View File

@@ -68,7 +68,43 @@ namespace gjkepa2_impl
const btConvexShape* m_shapes[2];
btMatrix3x3 m_toshape1;
btTransform m_toshape0;
#ifdef __SPU__
bool m_enableMargin;
#else
btVector3 (btConvexShape::*Ls)(const btVector3&) const;
#endif//__SPU__
MinkowskiDiff()
{
}
#ifdef __SPU__
void EnableMargin(bool enable)
{
m_enableMargin = enable;
}
inline btVector3 Support0(const btVector3& d) const
{
if (m_enableMargin)
{
return m_shapes[0]->localGetSupportVertexNonVirtual(d);
} else
{
return m_shapes[0]->localGetSupportVertexWithoutMarginNonVirtual(d);
}
}
inline btVector3 Support1(const btVector3& d) const
{
if (m_enableMargin)
{
return m_toshape0*(m_shapes[1]->localGetSupportVertexNonVirtual(m_toshape1*d));
} else
{
return m_toshape0*(m_shapes[1]->localGetSupportVertexWithoutMarginNonVirtual(m_toshape1*d));
}
}
#else
void EnableMargin(bool enable)
{
if(enable)
@@ -84,6 +120,8 @@ namespace gjkepa2_impl
{
return(m_toshape0*((m_shapes[1])->*(Ls))(m_toshape1*d));
}
#endif //__SPU__
inline btVector3 Support(const btVector3& d) const
{
return(Support0(d)-Support1(-d));
@@ -858,6 +896,7 @@ bool btGjkEpaSolver2::Penetration( const btConvexShape* shape0,
return(false);
}
#ifndef __SPU__
//
btScalar btGjkEpaSolver2::SignedDistance(const btVector3& position,
btScalar margin,
@@ -923,6 +962,7 @@ bool btGjkEpaSolver2::SignedDistance(const btConvexShape* shape0,
else
return(true);
}
#endif //__SPU__
/* Symbols cleanup */

View File

@@ -25,6 +25,10 @@ class btGjkEpaPenetrationDepthSolver : public btConvexPenetrationDepthSolver
{
public :
btGjkEpaPenetrationDepthSolver()
{
}
bool calcPenDepth( btSimplexSolverInterface& simplexSolver,
const btConvexShape* pConvexA, const btConvexShape* pConvexB,
const btTransform& transformA, const btTransform& transformB,

View File

@@ -38,20 +38,48 @@ int gNumDeepPenetrationChecks = 0;
int gNumGjkChecks = 0;
btGjkPairDetector::btGjkPairDetector(const btConvexShape* objectA,const btConvexShape* objectB,btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver* penetrationDepthSolver)
:m_penetrationDepthSolver(penetrationDepthSolver),
m_simplexSolver(simplexSolver),
m_minkowskiA(objectA),
m_minkowskiB(objectB),
m_shapeTypeA(objectA->getShapeType()),
m_shapeTypeB(objectB->getShapeType()),
m_marginA(objectA->getMargin()),
m_marginB(objectB->getMargin()),
m_ignoreMargin(false),
m_lastUsedMethod(-1),
m_catchDegeneracies(1)
{
}
btGjkPairDetector::btGjkPairDetector(const btConvexShape* objectA,const btConvexShape* objectB,int shapeTypeA,int shapeTypeB,btScalar marginA, btScalar marginB, btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver* penetrationDepthSolver)
:m_cachedSeparatingAxis(btScalar(0.),btScalar(0.),btScalar(1.)),
m_penetrationDepthSolver(penetrationDepthSolver),
m_simplexSolver(simplexSolver),
m_minkowskiA(objectA),
m_minkowskiB(objectB),
m_shapeTypeA(shapeTypeA),
m_shapeTypeB(shapeTypeB),
m_marginA(marginA),
m_marginB(marginB),
m_ignoreMargin(false),
m_lastUsedMethod(-1),
m_catchDegeneracies(1)
{
}
void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults)
void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults)
{
(void)swapResults;
getClosestPointsNonVirtual(input,output,debugDraw);
}
#ifdef __SPU__
void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw)
#else
void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw)
#endif
{
m_cachedSeparatingDistance = 0.f;
@@ -64,21 +92,9 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result&
localTransA.getOrigin() -= positionOffset;
localTransB.getOrigin() -= positionOffset;
#ifdef __SPU__
btScalar marginA = m_minkowskiA->getMarginNonVirtual();
btScalar marginB = m_minkowskiB->getMarginNonVirtual();
#else
btScalar marginA = m_minkowskiA->getMargin();
btScalar marginB = m_minkowskiB->getMargin();
#ifdef TEST_NON_VIRTUAL
btScalar marginAv = m_minkowskiA->getMarginNonVirtual();
btScalar marginBv = m_minkowskiB->getMarginNonVirtual();
btAssert(marginA == marginAv);
btAssert(marginB == marginBv);
#endif //TEST_NON_VIRTUAL
#endif
btScalar marginA = m_marginA;
btScalar marginB = m_marginB;
gNumGjkChecks++;
@@ -123,6 +139,15 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result&
btVector3 seperatingAxisInA = (-m_cachedSeparatingAxis)* input.m_transformA.getBasis();
btVector3 seperatingAxisInB = m_cachedSeparatingAxis* input.m_transformB.getBasis();
#if 1
btVector3 pInA = m_minkowskiA->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInA);
btVector3 qInB = m_minkowskiB->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInB);
// btVector3 pInA = localGetSupportingVertexWithoutMargin(m_shapeTypeA, m_minkowskiA, seperatingAxisInA,input.m_convexVertexData[0]);//, &featureIndexA);
// btVector3 qInB = localGetSupportingVertexWithoutMargin(m_shapeTypeB, m_minkowskiB, seperatingAxisInB,input.m_convexVertexData[1]);//, &featureIndexB);
#else
#ifdef __SPU__
btVector3 pInA = m_minkowskiA->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInA);
btVector3 qInB = m_minkowskiB->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInB);
@@ -136,6 +161,8 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result&
btAssert((qInBv-qInB).length() < 0.0001);
#endif //
#endif //__SPU__
#endif
btVector3 pWorld = localTransA(pInA);
btVector3 qWorld = localTransB(qInB);
@@ -291,7 +318,7 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result&
if (checkPenetration && (!isValid || catchDegeneratePenetrationCase ))
{
//penetration case
//if there is no way to handle penetrations, bail out
if (m_penetrationDepthSolver)
{
@@ -373,6 +400,7 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result&
}
}
}
}

View File

@@ -36,6 +36,11 @@ class btGjkPairDetector : public btDiscreteCollisionDetectorInterface
btSimplexSolverInterface* m_simplexSolver;
const btConvexShape* m_minkowskiA;
const btConvexShape* m_minkowskiB;
int m_shapeTypeA;
int m_shapeTypeB;
btScalar m_marginA;
btScalar m_marginB;
bool m_ignoreMargin;
btScalar m_cachedSeparatingDistance;
@@ -50,10 +55,14 @@ public:
btGjkPairDetector(const btConvexShape* objectA,const btConvexShape* objectB,btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver* penetrationDepthSolver);
btGjkPairDetector(const btConvexShape* objectA,const btConvexShape* objectB,int shapeTypeA,int shapeTypeB,btScalar marginA, btScalar marginB, btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver* penetrationDepthSolver);
virtual ~btGjkPairDetector() {};
virtual void getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults=false);
void getClosestPointsNonVirtual(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw);
void setMinkowskiA(btConvexShape* minkA)
{
m_minkowskiA = minkA;

View File

@@ -25,7 +25,8 @@ ContactProcessedCallback gContactProcessedCallback = 0;
btPersistentManifold::btPersistentManifold()
:m_body0(0),
:btTypedObject(BT_PERSISTENT_MANIFOLD_TYPE),
m_body0(0),
m_body1(0),
m_cachedPoints (0),
m_index1a(0)

View File

@@ -32,7 +32,11 @@ typedef bool (*ContactProcessedCallback)(btManifoldPoint& cp,void* body0,void* b
extern ContactDestroyedCallback gContactDestroyedCallback;
enum btContactManifoldTypes
{
BT_PERSISTENT_MANIFOLD_TYPE = 1,
MAX_CONTACT_MANIFOLD_TYPE
};
#define MANIFOLD_CACHE_SIZE 4
@@ -43,7 +47,7 @@ extern ContactDestroyedCallback gContactDestroyedCallback;
///reduces the cache to 4 points, when more then 4 points are added, using following rules:
///the contact point with deepest penetration is always kept, and it tries to maximuze the area covered by the points
///note that some pairs of objects might have more then one contact manifold.
ATTRIBUTE_ALIGNED16( class) btPersistentManifold
ATTRIBUTE_ALIGNED16( class) btPersistentManifold : public btTypedObject
{
btManifoldPoint m_pointCache[MANIFOLD_CACHE_SIZE];
@@ -72,11 +76,11 @@ public:
btPersistentManifold();
btPersistentManifold(void* body0,void* body1,int , btScalar contactBreakingThreshold,btScalar contactProcessingThreshold)
: m_body0(body0),m_body1(body1),m_cachedPoints(0),
: btTypedObject(BT_PERSISTENT_MANIFOLD_TYPE),
m_body0(body0),m_body1(body1),m_cachedPoints(0),
m_contactBreakingThreshold(contactBreakingThreshold),
m_contactProcessingThreshold(contactProcessingThreshold)
{
}
SIMD_FORCE_INLINE void* getBody0() { return m_body0;}