attempts to improve degeneracies in GJK implementation

This commit is contained in:
erwin.coumans
2009-07-10 21:27:04 +00:00
parent 3538ac1162
commit d4b099236c

View File

@@ -184,23 +184,35 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result&
#ifdef DEBUG_SPU_COLLISION_DETECTION #ifdef DEBUG_SPU_COLLISION_DETECTION
spu_printf("addVertex 2\n"); spu_printf("addVertex 2\n");
#endif #endif
btVector3 newCachedSeparatingAxis;
//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(newCachedSeparatingAxis))
{ {
m_degenerateSimplex = 3; m_degenerateSimplex = 3;
checkSimplex = true; checkSimplex = true;
break; break;
} }
if(m_cachedSeparatingAxis.length2()<REL_ERROR2) if(newCachedSeparatingAxis.length2()<REL_ERROR2)
{ {
m_cachedSeparatingAxis = newCachedSeparatingAxis;
m_degenerateSimplex = 6; m_degenerateSimplex = 6;
checkSimplex = true; checkSimplex = true;
break; break;
} }
btScalar previousSquaredDistance = squaredDistance; btScalar previousSquaredDistance = squaredDistance;
squaredDistance = m_cachedSeparatingAxis.length2(); squaredDistance = newCachedSeparatingAxis.length2();
if (squaredDistance>previousSquaredDistance)
{
m_degenerateSimplex = 7;
squaredDistance = previousSquaredDistance;
checkSimplex = true;
break;
}
m_cachedSeparatingAxis = newCachedSeparatingAxis;
//redundant m_simplexSolver->compute_points(pointOnA, pointOnB); //redundant m_simplexSolver->compute_points(pointOnA, pointOnB);
@@ -303,11 +315,13 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result&
if (lenSqr > (SIMD_EPSILON*SIMD_EPSILON)) if (lenSqr > (SIMD_EPSILON*SIMD_EPSILON))
{ {
tmpNormalInB /= btSqrt(lenSqr); tmpNormalInB /= btSqrt(lenSqr);
btScalar distance2 = -(tmpPointOnA-tmpPointOnB).length(); btScalar distance2 = -(tmpPointOnA-tmpPointOnB).length()-margin;
//only replace valid penetrations when the result is deeper (check) //only replace valid penetrations when the result is deeper (check)
if (!isValid || (distance2 < distance)) if (!isValid || (distance2 < distance))
{ {
distance = distance2; distance = distance2;
pointOnA -= m_cachedSeparatingAxis * (marginA / distance);
pointOnB += m_cachedSeparatingAxis * (marginB / distance);
pointOnA = tmpPointOnA; pointOnA = tmpPointOnA;
pointOnB = tmpPointOnB; pointOnB = tmpPointOnB;
normalInB = tmpNormalInB; normalInB = tmpNormalInB;