Work on some improvements for GJK/PenetrationTestBullet.cpp. if this introduces issue, will need to revert.

This commit is contained in:
ejcoumans
2006-11-14 21:53:59 +00:00
parent 6bc090fd28
commit b5afb11282
7 changed files with 80 additions and 22 deletions

View File

@@ -27,7 +27,7 @@ subject to the following restrictions:
#include "GL_ShapeDrawer.h" #include "GL_ShapeDrawer.h"
#include "CollisionInterfaceDemo.h" #include "CollisionInterfaceDemo.h"
#include "GlutStuff.h" #include "GlutStuff.h"
#include "GLDebugDrawer.h"
float yaw=0.f,pitch=0.f,roll=0.f; float yaw=0.f,pitch=0.f,roll=0.f;
const int maxNumObjects = 4; const int maxNumObjects = 4;
@@ -41,7 +41,7 @@ btCollisionWorld* collisionWorld = 0;
int screenWidth = 640; int screenWidth = 640;
int screenHeight = 480; int screenHeight = 480;
GLDebugDrawer debugDrawer;
int main(int argc,char** argv) int main(int argc,char** argv)
{ {
@@ -117,8 +117,12 @@ void CollisionInterfaceDemo::displayCallback(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_LIGHTING); glDisable(GL_LIGHTING);
btDispatcherInfo dispatchInfo;
dispatchInfo.m_debugDraw = &debugDrawer;
if (collisionWorld) if (collisionWorld)
collisionWorld->performDiscreteCollisionDetection(); collisionWorld->performDiscreteCollisionDetection(dispatchInfo);
int i; int i;

View File

@@ -645,7 +645,12 @@ static void RenderCallback()
BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
yStart += yIncr; yStart += yIncr;
glRasterPos3f(xOffset,yStart,0);
sprintf(buf,"gLastUsedMethod=%d\n", gLastUsedMethod);
BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
yStart += yIncr;

View File

@@ -17,10 +17,15 @@ subject to the following restrictions:
#include "DemoApplication.h" #include "DemoApplication.h"
class btCollisionAlgorithmCreateFunc;
///ConcaveDemo shows usage of static concave triangle meshes ///ConcaveDemo shows usage of static concave triangle meshes
///It also shows per-triangle material (friction/restitution) through CustomMaterialCombinerCallback ///It also shows per-triangle material (friction/restitution) through CustomMaterialCombinerCallback
class ConcaveDemo : public DemoApplication class ConcaveDemo : public DemoApplication
{ {
btCollisionAlgorithmCreateFunc* m_gimpactCollisionCreateFunc;
public: public:
void initPhysics(); void initPhysics();

View File

@@ -14,6 +14,7 @@ subject to the following restrictions:
*/ */
#include "btBulletDynamicsCommon.h" #include "btBulletDynamicsCommon.h"
#include "ConcaveDemo.h"
#include "LinearMath/btDefaultMotionState.h" #include "LinearMath/btDefaultMotionState.h"
#include "LinearMath/btIDebugDraw.h" #include "LinearMath/btIDebugDraw.h"
@@ -27,7 +28,7 @@ subject to the following restrictions:
#include "BMF_Api.h" #include "BMF_Api.h"
#include "GLDebugDrawer.h" #include "GLDebugDrawer.h"
#include "ConcaveDemo.h"
#include "GL_ShapeDrawer.h" #include "GL_ShapeDrawer.h"
#include "GlutStuff.h" #include "GlutStuff.h"
@@ -1634,11 +1635,13 @@ void ConcaveDemo::initPhysics()
btOverlappingPairCache* broadphase = new btSimpleBroadphase(); btOverlappingPairCache* broadphase = new btSimpleBroadphase();
m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase); 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; bool isDynamic = false;

View File

@@ -35,6 +35,12 @@ int numObjects = 0;
const int maxNumObjects = 16384; const int maxNumObjects = 16384;
btTransform startTransforms[maxNumObjects]; btTransform startTransforms[maxNumObjects];
btCollisionShape* gShapePtr[maxNumObjects];//1 rigidbody has 1 shape (no re-use of shapes) 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() DemoApplication::DemoApplication()
@@ -778,11 +784,11 @@ void DemoApplication::renderme()
yStart += yIncr; yStart += yIncr;
} }
} }
#endif //USE_QUICKPROF #endif //USE_QUICKPROF
glRasterPos3f(xOffset,yStart,0); glRasterPos3f(xOffset,yStart,0);
sprintf(buf,"mouse to interact"); sprintf(buf,"mouse to interact");
BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
@@ -856,6 +862,20 @@ void DemoApplication::renderme()
BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
yStart += yIncr; 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(); resetPerspectiveProjection();
} }
@@ -865,6 +885,11 @@ void DemoApplication::renderme()
void DemoApplication::clientResetScene() void DemoApplication::clientResetScene()
{ {
#ifdef SHOW_NUM_DEEP_PENETRATIONS
gNumDeepPenetrationChecks = 0;
gNumGjkChecks = 0;
#endif //SHOW_NUM_DEEP_PENETRATIONS
if (m_dynamicsWorld) if (m_dynamicsWorld)
{ {
m_dynamicsWorld->stepSimulation(1.f/60.f,0); m_dynamicsWorld->stepSimulation(1.f/60.f,0);

View File

@@ -38,7 +38,9 @@ struct btDispatcherInfo
DISPATCH_CONTINUOUS DISPATCH_CONTINUOUS
}; };
btDispatcherInfo() btDispatcherInfo()
:m_dispatchFunc(DISPATCH_DISCRETE), :m_timeStep(0.f),
m_stepCount(0),
m_dispatchFunc(DISPATCH_DISCRETE),
m_timeOfImpact(1.f), m_timeOfImpact(1.f),
m_useContinuous(false), m_useContinuous(false),
m_debugDraw(0), m_debugDraw(0),

View File

@@ -25,6 +25,9 @@ subject to the following restrictions:
//must be above the machine epsilon //must be above the machine epsilon
#define REL_ERROR2 1.0e-6f #define REL_ERROR2 1.0e-6f
//temp globals, to improve GJK/EPA/penetration calculations
int gNumDeepPenetrationChecks = 0;
int gNumGjkChecks = 0;
#ifdef __SPU__ #ifdef __SPU__
#include <spu_printf.h> #include <spu_printf.h>
@@ -39,7 +42,7 @@ m_minkowskiA(objectA),
m_minkowskiB(objectB), m_minkowskiB(objectB),
m_ignoreMargin(false), m_ignoreMargin(false),
m_lastUsedMethod(-1), 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 marginA = m_minkowskiA->getMargin();
float marginB = m_minkowskiB->getMargin(); float marginB = m_minkowskiB->getMargin();
gNumGjkChecks++;
//for CCD we don't use margins //for CCD we don't use margins
if (m_ignoreMargin) if (m_ignoreMargin)
{ {
@@ -71,7 +76,7 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result&
bool isValid = false; bool isValid = false;
bool checkSimplex = false; bool checkSimplex = false;
bool checkPenetration = true; bool checkPenetration = true;
m_degenerateSimplex = false; m_degenerateSimplex = 0;
m_lastUsedMethod = -1; 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 //exit 0: the new point is already in the simplex, or we didn't come any closer
if (m_simplexSolver->inSimplex(w)) if (m_simplexSolver->inSimplex(w))
{ {
m_degenerateSimplex = 1;
checkSimplex = true; checkSimplex = true;
break; break;
} }
@@ -116,14 +122,12 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result&
float f0 = squaredDistance - delta; float f0 = squaredDistance - delta;
float f1 = squaredDistance * REL_ERROR2; float f1 = squaredDistance * REL_ERROR2;
if (f0 <= 0.f) if (f0 <= f1)
{
m_degenerateSimplex = 2;
}
if (f0 >= 0.f && (f0 <= f1))
//if (f0 <= f1)
{ {
if (f0 <= 0.f)
{
m_degenerateSimplex = 2;
}
checkSimplex = true; checkSimplex = true;
break; break;
} }
@@ -133,7 +137,7 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result&
//calculate the closest point to the origin (update vector v) //calculate the closest point to the origin (update vector v)
if (!m_simplexSolver->closest(m_cachedSeparatingAxis)) if (!m_simplexSolver->closest(m_cachedSeparatingAxis))
{ {
m_degenerateSimplex = 1; m_degenerateSimplex = 3;
checkSimplex = true; checkSimplex = true;
break; break;
} }
@@ -188,7 +192,10 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result&
normalInB = pointOnA-pointOnB; normalInB = pointOnA-pointOnB;
float lenSqr = m_cachedSeparatingAxis.length2(); float lenSqr = m_cachedSeparatingAxis.length2();
//valid normal //valid normal
//if (lenSqr > (0.1f*margin)) //SIMD_EPSILON*SIMD_EPSILON)) if (lenSqr < 0.00001)
{
m_degenerateSimplex = 5;
}
if (lenSqr > SIMD_EPSILON*SIMD_EPSILON) if (lenSqr > SIMD_EPSILON*SIMD_EPSILON)
{ {
float rlen = 1.f / btSqrt(lenSqr ); float rlen = 1.f / btSqrt(lenSqr );
@@ -200,6 +207,7 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result&
pointOnB += m_cachedSeparatingAxis * (marginB / s); pointOnB += m_cachedSeparatingAxis * (marginB / s);
distance = ((1.f/rlen) - margin); distance = ((1.f/rlen) - margin);
isValid = true; isValid = true;
m_lastUsedMethod = 1; m_lastUsedMethod = 1;
} else } 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)
if (checkPenetration && (!isValid || (m_catchDegeneracies && m_penetrationDepthSolver && m_degenerateSimplex) )) if (checkPenetration && (!isValid || catchDegeneratePenetrationCase ))
{ {
//penetration case //penetration case
@@ -217,6 +228,9 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result&
{ {
// Penetration depth case. // Penetration depth case.
btVector3 tmpPointOnA,tmpPointOnB; btVector3 tmpPointOnA,tmpPointOnB;
gNumDeepPenetrationChecks++;
bool isValid2 = m_penetrationDepthSolver->calcPenDepth( bool isValid2 = m_penetrationDepthSolver->calcPenDepth(
*m_simplexSolver, *m_simplexSolver,
m_minkowskiA,m_minkowskiB, m_minkowskiA,m_minkowskiB,