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:
@@ -19,6 +19,7 @@ subject to the following restrictions:
|
|||||||
//#define CHECK_MEMORY_LEAKS 1
|
//#define CHECK_MEMORY_LEAKS 1
|
||||||
//#define USE_PARALLEL_DISPATCHER 1
|
//#define USE_PARALLEL_DISPATCHER 1
|
||||||
|
|
||||||
|
//#define USE_SIMPLE_DYNAMICS_WORLD 1
|
||||||
|
|
||||||
int gNumObjects = 120;
|
int gNumObjects = 120;
|
||||||
#define HALF_EXTENTS btScalar(1.)
|
#define HALF_EXTENTS btScalar(1.)
|
||||||
@@ -150,11 +151,17 @@ void BasicDemo::initPhysics()
|
|||||||
m_dispatcher->registerCollisionCreateFunc(BOX_SHAPE_PROXYTYPE,SPHERE_SHAPE_PROXYTYPE,m_boxSphereCF);
|
m_dispatcher->registerCollisionCreateFunc(BOX_SHAPE_PROXYTYPE,SPHERE_SHAPE_PROXYTYPE,m_boxSphereCF);
|
||||||
#endif //USE_PARALLEL_DISPATCHER
|
#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);
|
m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_overlappingPairCache,m_solver);
|
||||||
|
#endif //USE_SIMPLE_DYNAMICS_WORLD
|
||||||
m_dynamicsWorld->getDispatchInfo().m_enableSPU = true;
|
m_dynamicsWorld->getDispatchInfo().m_enableSPU = true;
|
||||||
|
|
||||||
m_dynamicsWorld->setGravity(btVector3(0,-10,0));
|
m_dynamicsWorld->setGravity(btVector3(0,-10,0));
|
||||||
|
|||||||
@@ -240,7 +240,10 @@ const float TRIANGLE_SIZE=20.f;
|
|||||||
bool useFloatDatam=false;
|
bool useFloatDatam=false;
|
||||||
bool flipQuadEdges=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);
|
btVector3 localScaling(20,20,20);
|
||||||
localScaling[upIndex]=1.f;
|
localScaling[upIndex]=1.f;
|
||||||
groundShape->setLocalScaling(localScaling);
|
groundShape->setLocalScaling(localScaling);
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ subject to the following restrictions:
|
|||||||
int gOverlappingPairs = 0;
|
int gOverlappingPairs = 0;
|
||||||
|
|
||||||
btOverlappingPairCache::btOverlappingPairCache():
|
btOverlappingPairCache::btOverlappingPairCache():
|
||||||
m_blockedForChanges(false)
|
m_blockedForChanges(false),
|
||||||
|
m_overlapFilterCallback(0)
|
||||||
//m_NumOverlapBroadphasePair(0)
|
//m_NumOverlapBroadphasePair(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,13 +26,20 @@ subject to the following restrictions:
|
|||||||
|
|
||||||
struct btOverlapCallback
|
struct btOverlapCallback
|
||||||
{
|
{
|
||||||
virtual ~btOverlapCallback()
|
virtual ~btOverlapCallback()
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
//return true for deletion of the pair
|
//return true for deletion of the pair
|
||||||
virtual bool processOverlap(btBroadphasePair& pair) = 0;
|
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
|
///btOverlappingPairCache maintains the objects with overlapping AABB
|
||||||
///Typically managed by the Broadphase, Axis3Sweep or btSimpleBroadphase
|
///Typically managed by the Broadphase, Axis3Sweep or btSimpleBroadphase
|
||||||
class btOverlappingPairCache : public btBroadphaseInterface
|
class btOverlappingPairCache : public btBroadphaseInterface
|
||||||
@@ -44,6 +51,8 @@ class btOverlappingPairCache : public btBroadphaseInterface
|
|||||||
//during the dispatch, check that user doesn't destroy/create proxy
|
//during the dispatch, check that user doesn't destroy/create proxy
|
||||||
bool m_blockedForChanges;
|
bool m_blockedForChanges;
|
||||||
|
|
||||||
|
//if set, use the callback instead of the built in filter in needBroadphaseCollision
|
||||||
|
btOverlapFilterCallback* m_overlapFilterCallback;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
btOverlappingPairCache();
|
btOverlappingPairCache();
|
||||||
@@ -67,6 +76,9 @@ class btOverlappingPairCache : public btBroadphaseInterface
|
|||||||
|
|
||||||
inline bool needsBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const
|
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;
|
bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
|
||||||
collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
|
collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
|
||||||
|
|
||||||
@@ -92,7 +104,17 @@ class btOverlappingPairCache : public btBroadphaseInterface
|
|||||||
return m_overlappingPairArray.size();
|
return m_overlappingPairArray.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
btOverlapFilterCallback* getOverlapFilterCallback()
|
||||||
|
{
|
||||||
|
return m_overlapFilterCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setOverlapFilterCallback(btOverlapFilterCallback* callback)
|
||||||
|
{
|
||||||
|
m_overlapFilterCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
#endif //OVERLAPPING_PAIR_CACHE_H
|
#endif //OVERLAPPING_PAIR_CACHE_H
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ m_heightfieldDataUnknown(heightfieldData),
|
|||||||
m_maxHeight(maxHeight),
|
m_maxHeight(maxHeight),
|
||||||
m_upAxis(upAxis),
|
m_upAxis(upAxis),
|
||||||
m_useFloatData(useFloatData),
|
m_useFloatData(useFloatData),
|
||||||
m_flipQuadEdges(flipQuadEdges)
|
m_flipQuadEdges(flipQuadEdges),
|
||||||
|
m_useDiamondSubdivision(false)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
@@ -289,31 +290,30 @@ void btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback
|
|||||||
for(int x=startX; x<endX; x++)
|
for(int x=startX; x<endX; x++)
|
||||||
{
|
{
|
||||||
btVector3 vertices[3];
|
btVector3 vertices[3];
|
||||||
if (!m_flipQuadEdges)
|
if (m_flipQuadEdges || (m_useDiamondSubdivision && ((j+x) & 1)))
|
||||||
{
|
{
|
||||||
//first triangle
|
//first triangle
|
||||||
getVertex(x,j,vertices[0]);
|
getVertex(x,j,vertices[0]);
|
||||||
getVertex(x,j+1,vertices[1]);
|
getVertex(x+1,j,vertices[1]);
|
||||||
getVertex(x+1,j,vertices[2]);
|
getVertex(x+1,j+1,vertices[2]);
|
||||||
callback->processTriangle(vertices,x,j);
|
callback->processTriangle(vertices,x,j);
|
||||||
//second triangle
|
//second triangle
|
||||||
getVertex(x+1,j,vertices[0]);
|
getVertex(x,j,vertices[0]);
|
||||||
getVertex(x,j+1,vertices[1]);
|
getVertex(x+1,j+1,vertices[1]);
|
||||||
getVertex(x+1,j+1,vertices[2]);
|
getVertex(x,j+1,vertices[2]);
|
||||||
callback->processTriangle(vertices,x,j);
|
callback->processTriangle(vertices,x,j);
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
//first triangle
|
//first triangle
|
||||||
getVertex(x,j,vertices[0]);
|
getVertex(x,j,vertices[0]);
|
||||||
getVertex(x+1,j,vertices[1]);
|
getVertex(x,j+1,vertices[1]);
|
||||||
getVertex(x+1,j+1,vertices[2]);
|
getVertex(x+1,j,vertices[2]);
|
||||||
callback->processTriangle(vertices,x,j);
|
callback->processTriangle(vertices,x,j);
|
||||||
//second triangle
|
//second triangle
|
||||||
getVertex(x,j,vertices[0]);
|
getVertex(x+1,j,vertices[0]);
|
||||||
getVertex(x+1,j+1,vertices[1]);
|
getVertex(x,j+1,vertices[1]);
|
||||||
getVertex(x,j+1,vertices[2]);
|
getVertex(x+1,j+1,vertices[2]);
|
||||||
callback->processTriangle(vertices,x,j);
|
callback->processTriangle(vertices,x,j);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ protected:
|
|||||||
|
|
||||||
bool m_useFloatData;
|
bool m_useFloatData;
|
||||||
bool m_flipQuadEdges;
|
bool m_flipQuadEdges;
|
||||||
|
bool m_useDiamondSubdivision;
|
||||||
|
|
||||||
int m_upAxis;
|
int m_upAxis;
|
||||||
|
|
||||||
@@ -62,6 +63,8 @@ public:
|
|||||||
virtual ~btHeightfieldTerrainShape();
|
virtual ~btHeightfieldTerrainShape();
|
||||||
|
|
||||||
|
|
||||||
|
void setUseDiamondSubdivision(bool useDiamondSubdivision=true) { m_useDiamondSubdivision = useDiamondSubdivision;}
|
||||||
|
|
||||||
virtual int getShapeType() const
|
virtual int getShapeType() const
|
||||||
{
|
{
|
||||||
return TERRAIN_SHAPE_PROXYTYPE;
|
return TERRAIN_SHAPE_PROXYTYPE;
|
||||||
|
|||||||
@@ -755,6 +755,10 @@ btScalar btSequentialImpulseConstraintSolver::solveGroup(btCollisionObject** bod
|
|||||||
|
|
||||||
if (getSolverMode() & SOLVER_CACHE_FRIENDLY)
|
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);
|
return solveGroupCacheFriendly(bodies,numBodies,manifoldPtr, numManifolds,constraints,numConstraints,infoGlobal,debugDrawer,stackAlloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user