I agree that moving out of penetration is hard. However, ignoring other penetrations to move out of a single penetration doesn’t seem ideal. Imagine a sphere that has been pushed into an overlapping condition with both walls in a right-angle corner. Summing the overlaps will at least give you the correct direction to move, even if the magnitude is slightly less than the full pullback required. Similarly, if a sphere gets sandwiched between two parallel walls, you don’t want to pick one wall and move the sphere into the other. You’d want to move into the middle to minimize the maximum penetration. Summing the overlaps would give you this behavior.

This is the UE4 engine code inside FBodyInstance::OverlapPhysX_AssumesLocked() which performs the PhysX calls. You can see that it’s returning only one overlap (whichever overlap happens to be first in the list. It’s not even the first overlap that occurs in time). I agree it could be a performance vs. accuracy problem, however, there should at least be an option to sum the overlaps if desired. As it stands, I can’t even use the routine because it straight up fails to remove simple overlaps about 5% of the time. I had to write my own version using PhysX directly (It’s not a PhysX problem - the Physx routine just does a geometry overlap test for which the algorithms are well documented in most real-time graphics books.)

```
// Iterate over each shape
for(int32 ShapeIdx=0; ShapeIdx<NumShapes; ++ShapeIdx)
{
const PxShape* PShape = PShapes[ShapeIdx];
check(PShape);
if (IsShapeBoundToBody(PShape) == true)
{
PxVec3 POutDirection;
float OutDistance;
if(OutMTD)
{
if (PxGeometryQuery::computePenetration(POutDirection, OutDistance, PGeom, ShapePose, PShape->getGeometry().any(), GetPxTransform_AssumesLocked(PShape, RigidBody)))
{
//TODO: there are some edge cases that give us nan results. In these cases we skip
if (!POutDirection.isFinite())
{
POutDirection.x = 0.f;
POutDirection.y = 0.f;
POutDirection.z = 0.f;
}
OutMTD->Direction = P2UVector(POutDirection);
OutMTD->Distance = FMath::Abs(OutDistance);
if (GHillClimbError)
{
LogHillClimbError(this, PGeom, ShapePose);
}
return true; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< This is the early return that simply returns one overlap result.
}
}
else
{
if(PxGeometryQuery::overlap(PGeom, ShapePose, PShape->getGeometry().any(), GetPxTransform_AssumesLocked(PShape, RigidBody)))
{
return true;
}
}
}
}
```