Fix in some degenerate GJK configuration: once a degenerate GJK case is detected, without valid EPA penetration, use a second GJK run without margin.
Thanks to Jacob Langford for the report:http://code.google.com/p/bullet/issues/detail?id=250
This commit is contained in:
@@ -36,6 +36,8 @@ bool btGjkEpaPenetrationDepthSolver::calcPenDepth( btSimplexSolverInterface& sim
|
|||||||
|
|
||||||
btVector3 guessVector(transformA.getOrigin()-transformB.getOrigin());
|
btVector3 guessVector(transformA.getOrigin()-transformB.getOrigin());
|
||||||
btGjkEpaSolver2::sResults results;
|
btGjkEpaSolver2::sResults results;
|
||||||
|
|
||||||
|
|
||||||
if(btGjkEpaSolver2::Penetration(pConvexA,transformA,
|
if(btGjkEpaSolver2::Penetration(pConvexA,transformA,
|
||||||
pConvexB,transformB,
|
pConvexB,transformB,
|
||||||
guessVector,results))
|
guessVector,results))
|
||||||
@@ -46,7 +48,15 @@ bool btGjkEpaPenetrationDepthSolver::calcPenDepth( btSimplexSolverInterface& sim
|
|||||||
wWitnessOnA = results.witnesses[0];
|
wWitnessOnA = results.witnesses[0];
|
||||||
wWitnessOnB = results.witnesses[1];
|
wWitnessOnB = results.witnesses[1];
|
||||||
return true;
|
return true;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
if(btGjkEpaSolver2::Distance(pConvexA,transformA,pConvexB,transformB,guessVector,results))
|
||||||
|
{
|
||||||
|
wWitnessOnA = results.witnesses[0];
|
||||||
|
wWitnessOnB = results.witnesses[1];
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -324,6 +324,32 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result&
|
|||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
|
///this is another degenerate case, where the initial GJK calculation reports a degenerate case
|
||||||
|
///EPA reports no penetration, and the second GJK (using the supporting vector without margin)
|
||||||
|
///reports a valid positive distance. Use the results of the second GJK instead of failing.
|
||||||
|
///thanks to Jacob.Langford for the reproduction case
|
||||||
|
///http://code.google.com/p/bullet/issues/detail?id=250
|
||||||
|
|
||||||
|
btVector3 tmpNormalInB = tmpPointOnA - tmpPointOnB;
|
||||||
|
btScalar lenSqr = tmpNormalInB.length2();
|
||||||
|
if (lenSqr > (SIMD_EPSILON*SIMD_EPSILON))
|
||||||
|
{
|
||||||
|
tmpNormalInB /= btSqrt(lenSqr);
|
||||||
|
btScalar distance2 = (tmpPointOnA-tmpPointOnB).length();
|
||||||
|
//only replace valid distances when the distance is less
|
||||||
|
if (!isValid || (distance2 < distance))
|
||||||
|
{
|
||||||
|
distance = distance2;
|
||||||
|
pointOnA = tmpPointOnA;
|
||||||
|
pointOnB = tmpPointOnB;
|
||||||
|
normalInB = tmpNormalInB;
|
||||||
|
isValid = true;
|
||||||
|
m_lastUsedMethod = 6;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
m_lastUsedMethod = 5;
|
m_lastUsedMethod = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user