diff --git a/Demos/CollisionInterfaceDemo/CollisionInterfaceDemo.cpp b/Demos/CollisionInterfaceDemo/CollisionInterfaceDemo.cpp index bfdd44924..e8f6d2512 100644 --- a/Demos/CollisionInterfaceDemo/CollisionInterfaceDemo.cpp +++ b/Demos/CollisionInterfaceDemo/CollisionInterfaceDemo.cpp @@ -27,7 +27,7 @@ subject to the following restrictions: #include "GL_ShapeDrawer.h" #include "CollisionInterfaceDemo.h" #include "GlutStuff.h" - +#include "GLDebugDrawer.h" float yaw=0.f,pitch=0.f,roll=0.f; const int maxNumObjects = 4; @@ -41,7 +41,7 @@ btCollisionWorld* collisionWorld = 0; int screenWidth = 640; int screenHeight = 480; - +GLDebugDrawer debugDrawer; int main(int argc,char** argv) { @@ -117,8 +117,12 @@ void CollisionInterfaceDemo::displayCallback(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDisable(GL_LIGHTING); + + btDispatcherInfo dispatchInfo; + dispatchInfo.m_debugDraw = &debugDrawer; + if (collisionWorld) - collisionWorld->performDiscreteCollisionDetection(); + collisionWorld->performDiscreteCollisionDetection(dispatchInfo); int i; diff --git a/Demos/EPAPenDepthDemo/PenetrationTestBullet.cpp b/Demos/EPAPenDepthDemo/PenetrationTestBullet.cpp index 5b19bc105..8fab6eecb 100644 --- a/Demos/EPAPenDepthDemo/PenetrationTestBullet.cpp +++ b/Demos/EPAPenDepthDemo/PenetrationTestBullet.cpp @@ -645,7 +645,12 @@ static void RenderCallback() BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); yStart += yIncr; + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"gLastUsedMethod=%d\n", gLastUsedMethod); + BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); + yStart += yIncr; + diff --git a/Demos/MovingConcaveDemo/ConcaveDemo.h b/Demos/MovingConcaveDemo/ConcaveDemo.h index bacef7282..d29ae5d22 100644 --- a/Demos/MovingConcaveDemo/ConcaveDemo.h +++ b/Demos/MovingConcaveDemo/ConcaveDemo.h @@ -17,10 +17,15 @@ subject to the following restrictions: #include "DemoApplication.h" +class btCollisionAlgorithmCreateFunc; + ///ConcaveDemo shows usage of static concave triangle meshes ///It also shows per-triangle material (friction/restitution) through CustomMaterialCombinerCallback class ConcaveDemo : public DemoApplication { + + btCollisionAlgorithmCreateFunc* m_gimpactCollisionCreateFunc; + public: void initPhysics(); diff --git a/Demos/MovingConcaveDemo/ConcavePhysicsDemo.cpp b/Demos/MovingConcaveDemo/ConcavePhysicsDemo.cpp index c4dd5da16..64e883c16 100644 --- a/Demos/MovingConcaveDemo/ConcavePhysicsDemo.cpp +++ b/Demos/MovingConcaveDemo/ConcavePhysicsDemo.cpp @@ -14,6 +14,7 @@ subject to the following restrictions: */ #include "btBulletDynamicsCommon.h" +#include "ConcaveDemo.h" #include "LinearMath/btDefaultMotionState.h" #include "LinearMath/btIDebugDraw.h" @@ -27,7 +28,7 @@ subject to the following restrictions: #include "BMF_Api.h" #include "GLDebugDrawer.h" -#include "ConcaveDemo.h" + #include "GL_ShapeDrawer.h" #include "GlutStuff.h" @@ -1634,11 +1635,13 @@ void ConcaveDemo::initPhysics() btOverlappingPairCache* broadphase = new btSimpleBroadphase(); m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase); - dispatcher->registerCollisionCreateFunc(GIMPACT_SHAPE_PROXYTYPE,GIMPACT_SHAPE_PROXYTYPE,new btConcaveConcaveCollisionAlgorithm::CreateFunc); - dispatcher->registerCollisionCreateFunc(TRIANGLE_MESH_SHAPE_PROXYTYPE,GIMPACT_SHAPE_PROXYTYPE,new btConcaveConcaveCollisionAlgorithm::CreateFunc); - dispatcher->registerCollisionCreateFunc(GIMPACT_SHAPE_PROXYTYPE,TRIANGLE_MESH_SHAPE_PROXYTYPE,new btConcaveConcaveCollisionAlgorithm::CreateFunc); - + m_gimpactCollisionCreateFunc = new btConcaveConcaveCollisionAlgorithm::CreateFunc; + dispatcher->registerCollisionCreateFunc(GIMPACT_SHAPE_PROXYTYPE,GIMPACT_SHAPE_PROXYTYPE,m_gimpactCollisionCreateFunc); + dispatcher->registerCollisionCreateFunc(TRIANGLE_MESH_SHAPE_PROXYTYPE,GIMPACT_SHAPE_PROXYTYPE,m_gimpactCollisionCreateFunc); + dispatcher->registerCollisionCreateFunc(GIMPACT_SHAPE_PROXYTYPE,TRIANGLE_MESH_SHAPE_PROXYTYPE,m_gimpactCollisionCreateFunc); + dispatcher->registerCollisionCreateFunc(STATIC_PLANE_PROXYTYPE,GIMPACT_SHAPE_PROXYTYPE,m_gimpactCollisionCreateFunc); + dispatcher->registerCollisionCreateFunc(GIMPACT_SHAPE_PROXYTYPE,STATIC_PLANE_PROXYTYPE,m_gimpactCollisionCreateFunc); bool isDynamic = false; diff --git a/Demos/OpenGL/DemoApplication.cpp b/Demos/OpenGL/DemoApplication.cpp index e8c2ca022..0da553c2f 100644 --- a/Demos/OpenGL/DemoApplication.cpp +++ b/Demos/OpenGL/DemoApplication.cpp @@ -35,6 +35,12 @@ int numObjects = 0; const int maxNumObjects = 16384; btTransform startTransforms[maxNumObjects]; btCollisionShape* gShapePtr[maxNumObjects];//1 rigidbody has 1 shape (no re-use of shapes) +#define SHOW_NUM_DEEP_PENETRATIONS 1 + +#ifdef SHOW_NUM_DEEP_PENETRATIONS +extern int gNumDeepPenetrationChecks; +extern int gNumGjkChecks; +#endif // DemoApplication::DemoApplication() @@ -778,11 +784,11 @@ void DemoApplication::renderme() yStart += yIncr; } + } #endif //USE_QUICKPROF - glRasterPos3f(xOffset,yStart,0); sprintf(buf,"mouse to interact"); BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); @@ -856,6 +862,20 @@ void DemoApplication::renderme() BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); yStart += yIncr; +#ifdef SHOW_NUM_DEEP_PENETRATIONS + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"gNumDeepPenetrationChecks = %d",gNumDeepPenetrationChecks); + BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); + yStart += yIncr; + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"gNumGjkChecks= %d",gNumGjkChecks); + BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); + yStart += yIncr; + +#endif //SHOW_NUM_DEEP_PENETRATIONS + resetPerspectiveProjection(); } @@ -865,6 +885,11 @@ void DemoApplication::renderme() void DemoApplication::clientResetScene() { +#ifdef SHOW_NUM_DEEP_PENETRATIONS + gNumDeepPenetrationChecks = 0; + gNumGjkChecks = 0; +#endif //SHOW_NUM_DEEP_PENETRATIONS + if (m_dynamicsWorld) { m_dynamicsWorld->stepSimulation(1.f/60.f,0); diff --git a/src/BulletCollision/BroadphaseCollision/btDispatcher.h b/src/BulletCollision/BroadphaseCollision/btDispatcher.h index bbc5bd3f5..415c398a1 100644 --- a/src/BulletCollision/BroadphaseCollision/btDispatcher.h +++ b/src/BulletCollision/BroadphaseCollision/btDispatcher.h @@ -38,7 +38,9 @@ struct btDispatcherInfo DISPATCH_CONTINUOUS }; btDispatcherInfo() - :m_dispatchFunc(DISPATCH_DISCRETE), + :m_timeStep(0.f), + m_stepCount(0), + m_dispatchFunc(DISPATCH_DISCRETE), m_timeOfImpact(1.f), m_useContinuous(false), m_debugDraw(0), diff --git a/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp b/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp index 507fcaf21..a0d13dacf 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp +++ b/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp @@ -25,6 +25,9 @@ subject to the following restrictions: //must be above the machine epsilon #define REL_ERROR2 1.0e-6f +//temp globals, to improve GJK/EPA/penetration calculations +int gNumDeepPenetrationChecks = 0; +int gNumGjkChecks = 0; #ifdef __SPU__ #include @@ -39,7 +42,7 @@ m_minkowskiA(objectA), m_minkowskiB(objectB), m_ignoreMargin(false), m_lastUsedMethod(-1), -m_catchDegeneracies(0) +m_catchDegeneracies(1) { } @@ -57,6 +60,8 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result& float marginA = m_minkowskiA->getMargin(); float marginB = m_minkowskiB->getMargin(); + gNumGjkChecks++; + //for CCD we don't use margins if (m_ignoreMargin) { @@ -71,7 +76,7 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result& bool isValid = false; bool checkSimplex = false; bool checkPenetration = true; - m_degenerateSimplex = false; + m_degenerateSimplex = 0; m_lastUsedMethod = -1; @@ -109,6 +114,7 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result& //exit 0: the new point is already in the simplex, or we didn't come any closer if (m_simplexSolver->inSimplex(w)) { + m_degenerateSimplex = 1; checkSimplex = true; break; } @@ -116,14 +122,12 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result& float f0 = squaredDistance - delta; float f1 = squaredDistance * REL_ERROR2; - if (f0 <= 0.f) - { - m_degenerateSimplex = 2; - } - - if (f0 >= 0.f && (f0 <= f1)) - //if (f0 <= f1) + if (f0 <= f1) { + if (f0 <= 0.f) + { + m_degenerateSimplex = 2; + } checkSimplex = true; break; } @@ -133,7 +137,7 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result& //calculate the closest point to the origin (update vector v) if (!m_simplexSolver->closest(m_cachedSeparatingAxis)) { - m_degenerateSimplex = 1; + m_degenerateSimplex = 3; checkSimplex = true; break; } @@ -188,7 +192,10 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result& normalInB = pointOnA-pointOnB; float lenSqr = m_cachedSeparatingAxis.length2(); //valid normal - //if (lenSqr > (0.1f*margin)) //SIMD_EPSILON*SIMD_EPSILON)) + if (lenSqr < 0.00001) + { + m_degenerateSimplex = 5; + } if (lenSqr > SIMD_EPSILON*SIMD_EPSILON) { float rlen = 1.f / btSqrt(lenSqr ); @@ -200,6 +207,7 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result& pointOnB += m_cachedSeparatingAxis * (marginB / s); distance = ((1.f/rlen) - margin); isValid = true; + m_lastUsedMethod = 1; } else { @@ -207,8 +215,11 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result& } } + bool catchDegeneratePenetrationCase = + (m_catchDegeneracies && m_penetrationDepthSolver && m_degenerateSimplex && ((distance+margin) < 0.01)); + //if (checkPenetration && !isValid) - if (checkPenetration && (!isValid || (m_catchDegeneracies && m_penetrationDepthSolver && m_degenerateSimplex) )) + if (checkPenetration && (!isValid || catchDegeneratePenetrationCase )) { //penetration case @@ -217,6 +228,9 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result& { // Penetration depth case. btVector3 tmpPointOnA,tmpPointOnB; + + gNumDeepPenetrationChecks++; + bool isValid2 = m_penetrationDepthSolver->calcPenDepth( *m_simplexSolver, m_minkowskiA,m_minkowskiB,