Expose subsimplexcast max iterations/epsilon

Note that for best quality, always use BT_USE_DOUBLE_PRECISION
This fixes Issue 34
https://github.com/bulletphysics/bullet3/issues/34
This commit is contained in:
erwincoumans
2018-12-22 12:44:29 -08:00
parent 5e08808e69
commit d477d18ad6
2 changed files with 24 additions and 19 deletions

View File

@@ -22,6 +22,19 @@ subject to the following restrictions:
class btMinkowskiSumShape; class btMinkowskiSumShape;
#include "LinearMath/btIDebugDraw.h" #include "LinearMath/btIDebugDraw.h"
#ifdef BT_USE_DOUBLE_PRECISION
#define MAX_ITERATIONS 64
#define MAX_EPSILON (SIMD_EPSILON * 10)
#else
#define MAX_ITERATIONS 32
#define MAX_EPSILON btScalar(0.0001)
#endif
///Typically the conservative advancement reaches solution in a few iterations, clip it to 32 for degenerate cases.
///See discussion about this here http://continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=565
//will need to digg deeper to make the algorithm more robust
//since, a large epsilon can cause an early termination with false
//positive results (ray intersections that shouldn't be there)
/// btConvexCast is an interface for Casting /// btConvexCast is an interface for Casting
class btConvexCast class btConvexCast
{ {
@@ -44,7 +57,9 @@ public:
CastResult() CastResult()
: m_fraction(btScalar(BT_LARGE_FLOAT)), : m_fraction(btScalar(BT_LARGE_FLOAT)),
m_debugDrawer(0), m_debugDrawer(0),
m_allowedPenetration(btScalar(0)) m_allowedPenetration(btScalar(0)),
m_subSimplexCastMaxIterations(MAX_ITERATIONS),
m_subSimplexCastEpsilon(MAX_EPSILON)
{ {
} }
@@ -57,6 +72,10 @@ public:
btScalar m_fraction; //input and output btScalar m_fraction; //input and output
btIDebugDraw* m_debugDrawer; btIDebugDraw* m_debugDrawer;
btScalar m_allowedPenetration; btScalar m_allowedPenetration;
int m_subSimplexCastMaxIterations;
btScalar m_subSimplexCastEpsilon;
}; };
/// cast a convex against another convex object /// cast a convex against another convex object

View File

@@ -28,13 +28,7 @@ btSubsimplexConvexCast::btSubsimplexConvexCast(const btConvexShape* convexA, con
{ {
} }
///Typically the conservative advancement reaches solution in a few iterations, clip it to 32 for degenerate cases.
///See discussion about this here http://continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=565
#ifdef BT_USE_DOUBLE_PRECISION
#define MAX_ITERATIONS 64
#else
#define MAX_ITERATIONS 32
#endif
bool btSubsimplexConvexCast::calcTimeOfImpact( bool btSubsimplexConvexCast::calcTimeOfImpact(
const btTransform& fromA, const btTransform& fromA,
const btTransform& toA, const btTransform& toA,
@@ -60,7 +54,7 @@ bool btSubsimplexConvexCast::calcTimeOfImpact(
btVector3 supVertexA = fromA(m_convexA->localGetSupportingVertex(-r * fromA.getBasis())); btVector3 supVertexA = fromA(m_convexA->localGetSupportingVertex(-r * fromA.getBasis()));
btVector3 supVertexB = fromB(m_convexB->localGetSupportingVertex(r * fromB.getBasis())); btVector3 supVertexB = fromB(m_convexB->localGetSupportingVertex(r * fromB.getBasis()));
v = supVertexA - supVertexB; v = supVertexA - supVertexB;
int maxIter = MAX_ITERATIONS; int maxIter = result.m_subSimplexCastMaxIterations;
btVector3 n; btVector3 n;
n.setValue(btScalar(0.), btScalar(0.), btScalar(0.)); n.setValue(btScalar(0.), btScalar(0.), btScalar(0.));
@@ -69,20 +63,12 @@ bool btSubsimplexConvexCast::calcTimeOfImpact(
btScalar dist2 = v.length2(); btScalar dist2 = v.length2();
#ifdef BT_USE_DOUBLE_PRECISION
btScalar epsilon = SIMD_EPSILON * 10;
#else
//todo: epsilon kept for backward compatibility of unit tests.
//will need to digg deeper to make the algorithm more robust
//since, a large epsilon can cause an early termination with false
//positive results (ray intersections that shouldn't be there)
btScalar epsilon = btScalar(0.0001);
#endif //BT_USE_DOUBLE_PRECISION
btVector3 w, p; btVector3 w, p;
btScalar VdotR; btScalar VdotR;
while ((dist2 > epsilon) && maxIter--) while ((dist2 > result.m_subSimplexCastEpsilon) && maxIter--)
{ {
supVertexA = interpolatedTransA(m_convexA->localGetSupportingVertex(-v * interpolatedTransA.getBasis())); supVertexA = interpolatedTransA(m_convexA->localGetSupportingVertex(-v * interpolatedTransA.getBasis()));
supVertexB = interpolatedTransB(m_convexB->localGetSupportingVertex(v * interpolatedTransB.getBasis())); supVertexB = interpolatedTransB(m_convexB->localGetSupportingVertex(v * interpolatedTransB.getBasis()));