Calculating collision force with AfterCollision/NormalImpulse is unreliable when IgnoreCCD = false?
Posted
by
Michael
on Game Development
See other posts from Game Development
or by Michael
Published on 2012-12-13T18:24:08Z
Indexed on
2012/12/13
23:21 UTC
Read the original article
Hit count: 342
box2d
|farseer-physics-engine
I'm using Farseer Physics Engine 3.3.1 in a very simple XNA 4 test game. (Note: I'm also tagging this Box2D, because Farseer is a direct port of Box2D and I will happily accept Box2D answers that solve this problem.)
In this game, I'm creating two bodies. The first body is created using BodyFactory.CreateCircle
and BodyType.Dynamic
. This body can be moved around using the keyboard (which sets Body.LinearVelocity). The second body is created using BodyFactory.CreateRectangle
and BodyType.Static
. This body is static and never moves.
Then I'm using this code to calculate the force of collision when the two bodies collide:
staticBody.FixtureList[0].AfterCollision += new AfterCollisionEventHandler(AfterCollision);
protected void AfterCollision(Fixture fixtureA, Fixture fixtureB, Contact contact)
{
float maxImpulse = 0f;
for (int i = 0; i < contact.Manifold.PointCount; i++)
maxImpulse = Math.Max(maxImpulse, contact.Manifold.Points[i].NormalImpulse);
// maxImpulse should contain the force of the collision
}
This code works great if both of these bodies are set to IgnoreCCD=true
. I can calculate the force of collision between them 100% reliably. Perfect.
But here's the problem: If I set the bodies to IgnoreCCD=false, that code becomes wildly unpredictable. AfterCollision is called reliably, but for some reason the NormalImpulse is 0 about 75% of the time, so only about one in four collisions is registered. Worse still, the NormalImpulse seems to be zero for completely random reasons. The dynamic body can collide with the static body 10 times in a row in virtually exactly the same way, and only 2 or 3 of the hits will register with a NormalImpulse greater than zero. Setting IgnoreCCD=true
on both bodies instantly solves the problem, but then I lose continuous physics detection.
Why is this happening and how can I fix it?
Here's a link to a simple XNA 4 solution that demonstrates this problem in action: http://www.mediafire.com/?a1w242q9sna54j4
© Game Development or respective owner