1
Vote

Disabling Contact in PreSolve causes TOI issues with dynamic bodies

description

If your contact listener implements the PreSolve function and uses contact.SetEnabled(false); to disable contact during that time step, the TOI solver will ignore it. I've traced the problem to World.cs in SolveTOI(). The first block of the function resets all contacts to Enabled. This is logical because some contacts may be invalidated by the TOI engine, however it throws out the result of PreSolve which was found in the ContractManager.Collide() from the start of the timestep. Contact.Update() is called again in SolveTOI (which fixes the issue by calling PreSolve again) however this is only done for STATIC bodies because the ContactEdge loop filters out non-static bodies:
 
// Only perform correction with static bodies, so the
// body won't get pushed out of the world.
if (type != BodyType.Static)
{
  continue;
}
...
contact.Update(_contactManager.ContactListener);
 
The result is PreSolve is never called again for Dynamic bodies (such as bullets) and the TOI code freezes the body at the contact point (velocities and positions get kind of messed up at this point because the TOI solver is contradicting the regular Solver).
 
I'm sorry I don't have the line numbers. My Box2D.XNA is slightly modified and I was afraid they wouldn't be accurate.

comments