support diamondsubdivision (thanks Jay for contribution)

support user-defined broadphase collision filtering (thanks Marten)
make sure btSimpeDynamicsWorld doesn't use cache friendly optimization in the solver (added an assert, and updated BasicDemo)
This commit is contained in:
ejcoumans 2007-06-29 22:13:15 +00:00
parent e33f5390dd
commit 5f8873c339
7 changed files with 72 additions and 32 deletions

View File

@ -19,6 +19,7 @@ subject to the following restrictions:
//#define CHECK_MEMORY_LEAKS 1
//#define USE_PARALLEL_DISPATCHER 1
//#define USE_SIMPLE_DYNAMICS_WORLD 1
int gNumObjects = 120;
#define HALF_EXTENTS btScalar(1.)
@ -150,11 +151,17 @@ void BasicDemo::initPhysics()
m_dispatcher->registerCollisionCreateFunc(BOX_SHAPE_PROXYTYPE,SPHERE_SHAPE_PROXYTYPE,m_boxSphereCF);
#endif //USE_PARALLEL_DISPATCHER
m_solver = new btSequentialImpulseConstraintSolver;
btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver;
m_solver = sol;
//m_dynamicsWorld = new btSimpleDynamicsWorld(m_dispatcher,m_overlappingPairCache,m_solver);
#ifdef USE_SIMPLE_DYNAMICS_WORLD
//btSimpleDynamicsWorld doesn't support 'cache friendly' optimization, so disable this
sol->setSolverMode(btSequentialImpulseConstraintSolver::SOLVER_RANDMIZE_ORDER);
m_dynamicsWorld = new btSimpleDynamicsWorld(m_dispatcher,m_overlappingPairCache,m_solver);
#else
m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_overlappingPairCache,m_solver);
#endif //USE_SIMPLE_DYNAMICS_WORLD
m_dynamicsWorld->getDispatchInfo().m_enableSPU = true;
m_dynamicsWorld->setGravity(btVector3(0,-10,0));

View File

@ -240,7 +240,10 @@ const float TRIANGLE_SIZE=20.f;
bool useFloatDatam=false;
bool flipQuadEdges=false;
groundShape = new btHeightfieldTerrainShape(width,length,heightfieldData,maxHeight,upIndex,useFloatDatam,flipQuadEdges);
btHeightfieldTerrainShape* heightFieldShape = new btHeightfieldTerrainShape(width,length,heightfieldData,maxHeight,upIndex,useFloatDatam,flipQuadEdges);;
groundShape = heightFieldShape;
heightFieldShape->setUseDiamondSubdivision(true);
btVector3 localScaling(20,20,20);
localScaling[upIndex]=1.f;
groundShape->setLocalScaling(localScaling);

View File

@ -24,7 +24,8 @@ subject to the following restrictions:
int gOverlappingPairs = 0;
btOverlappingPairCache::btOverlappingPairCache():
m_blockedForChanges(false)
m_blockedForChanges(false),
m_overlapFilterCallback(0)
//m_NumOverlapBroadphasePair(0)
{
}

View File

@ -26,13 +26,20 @@ subject to the following restrictions:
struct btOverlapCallback
{
virtual ~btOverlapCallback()
{
}
virtual ~btOverlapCallback()
{}
//return true for deletion of the pair
virtual bool processOverlap(btBroadphasePair& pair) = 0;
};
struct btOverlapFilterCallback
{
virtual ~btOverlapFilterCallback()
{}
// return true when pairs need collision
virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const = 0;
};
///btOverlappingPairCache maintains the objects with overlapping AABB
///Typically managed by the Broadphase, Axis3Sweep or btSimpleBroadphase
class btOverlappingPairCache : public btBroadphaseInterface
@ -44,6 +51,8 @@ class btOverlappingPairCache : public btBroadphaseInterface
//during the dispatch, check that user doesn't destroy/create proxy
bool m_blockedForChanges;
//if set, use the callback instead of the built in filter in needBroadphaseCollision
btOverlapFilterCallback* m_overlapFilterCallback;
public:
btOverlappingPairCache();
@ -67,6 +76,9 @@ class btOverlappingPairCache : public btBroadphaseInterface
inline bool needsBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const
{
if (m_overlapFilterCallback)
return m_overlapFilterCallback->needBroadphaseCollision(proxy0,proxy1);
bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
@ -92,7 +104,17 @@ class btOverlappingPairCache : public btBroadphaseInterface
return m_overlappingPairArray.size();
}
btOverlapFilterCallback* getOverlapFilterCallback()
{
return m_overlapFilterCallback;
}
void setOverlapFilterCallback(btOverlapFilterCallback* callback)
{
m_overlapFilterCallback = callback;
}
};
#endif //OVERLAPPING_PAIR_CACHE_H

View File

@ -26,7 +26,8 @@ m_heightfieldDataUnknown(heightfieldData),
m_maxHeight(maxHeight),
m_upAxis(upAxis),
m_useFloatData(useFloatData),
m_flipQuadEdges(flipQuadEdges)
m_flipQuadEdges(flipQuadEdges),
m_useDiamondSubdivision(false)
{
@ -282,38 +283,37 @@ void btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback
}
for(int j=startJ; j<endJ; j++)
{
for(int x=startX; x<endX; x++)
{
btVector3 vertices[3];
if (!m_flipQuadEdges)
if (m_flipQuadEdges || (m_useDiamondSubdivision && ((j+x) & 1)))
{
//first triangle
getVertex(x,j,vertices[0]);
getVertex(x,j+1,vertices[1]);
getVertex(x+1,j,vertices[2]);
callback->processTriangle(vertices,x,j);
//second triangle
getVertex(x+1,j,vertices[0]);
getVertex(x,j+1,vertices[1]);
getVertex(x+1,j+1,vertices[2]);
callback->processTriangle(vertices,x,j);
//first triangle
getVertex(x,j,vertices[0]);
getVertex(x+1,j,vertices[1]);
getVertex(x+1,j+1,vertices[2]);
callback->processTriangle(vertices,x,j);
//second triangle
getVertex(x,j,vertices[0]);
getVertex(x+1,j+1,vertices[1]);
getVertex(x,j+1,vertices[2]);
callback->processTriangle(vertices,x,j);
} else
{
//first triangle
getVertex(x,j,vertices[0]);
getVertex(x+1,j,vertices[1]);
getVertex(x+1,j+1,vertices[2]);
callback->processTriangle(vertices,x,j);
//second triangle
getVertex(x,j,vertices[0]);
getVertex(x+1,j+1,vertices[1]);
getVertex(x,j+1,vertices[2]);
callback->processTriangle(vertices,x,j);
//first triangle
getVertex(x,j,vertices[0]);
getVertex(x,j+1,vertices[1]);
getVertex(x+1,j,vertices[2]);
callback->processTriangle(vertices,x,j);
//second triangle
getVertex(x+1,j,vertices[0]);
getVertex(x,j+1,vertices[1]);
getVertex(x+1,j+1,vertices[2]);
callback->processTriangle(vertices,x,j);
}
}
}

View File

@ -38,6 +38,7 @@ protected:
bool m_useFloatData;
bool m_flipQuadEdges;
bool m_useDiamondSubdivision;
int m_upAxis;
@ -62,6 +63,8 @@ public:
virtual ~btHeightfieldTerrainShape();
void setUseDiamondSubdivision(bool useDiamondSubdivision=true) { m_useDiamondSubdivision = useDiamondSubdivision;}
virtual int getShapeType() const
{
return TERRAIN_SHAPE_PROXYTYPE;

View File

@ -755,6 +755,10 @@ btScalar btSequentialImpulseConstraintSolver::solveGroup(btCollisionObject** bod
if (getSolverMode() & SOLVER_CACHE_FRIENDLY)
{
//you need to provide at least some bodies
//btSimpleDynamicsWorld needs to switch off SOLVER_CACHE_FRIENDLY
btAssert(bodies);
btAssert(numBodies);
return solveGroupCacheFriendly(bodies,numBodies,manifoldPtr, numManifolds,constraints,numConstraints,infoGlobal,debugDrawer,stackAlloc);
}