May 27, 2009 at 1:51 PM
Edited May 27, 2009 at 1:52 PM
I know this is not excatly information for new users of physics engines, but I'll try to explain the science behind the engine it as simple as I can.
Farseer Physics Engine is based on a physics engine design developed by the Box2D creator Erin Catto. It's called Sequential Impulses (with warm starting). Sequential Impulses mean that on each update of the physics engine, the engine finds a collision in
1. Find geometries close to each other. When a pair of geometries is close, create an Arbiter (A pair of geometries) - This is called the broadphase.
2. Iterate each Arbiter and check the two geometries for intersection. The points of intersection is marked with a Contact - This is called the narrowphase.
3. Iterate each Contact and calculate the force required to separate the two geometries (using their normals and restitution coefficient).
4. Here is some stuff to optimize performance and stability. - Mostly involving sorting and removing of contacts. (Controlled by MaxContactsToDetect and MaxContactsToResolve on the PhysicsSimulator object)
Now. here is where the Sequential Impulse stuff happens:
5. Iterate the Arbiters 5 times (the default is 5, controlled by Iterations on the PhysicsSimualtor object) and apply impulse to each of the geometry pairs, to make them seperate. This involves something Erin Catto invenved where you clamp
the acumelated impulse - this is done to improve stability.
I also mentioned "warm starting" before. This is also used to improve stability (of the physics simulation). It means that you save contacts from previus simulation as a startingpoint of the new impulse calculations. You basically give the engine
an idea of how the collision will occur, before the collision occurs. This give a more stable result.
Now to the reason why I wrote all this :)
The OnCollision event fires whenever an Arbiter has been created and the Contact(s) associated with it has been detected (by the narrowphase). This means that the engine has determined the point of intersection (collision) between two geometries, and then fires
the OnCollision event.
The OnSeparation event fires when all the contacts associated with an Arbiter has been removed. - Again, after the engine determines that the two geometries are no longer touching each other.
This is all great and world work really good - IF we had an infinite bit computer. :) Problem is that we don't.
Computers are not 100% accurate and thus we run into rounding errors that can accumulate to something that is completely wrong (error too big for a stable physics simulation). This is taken into account in the physics engine and we do our best to prevent it
from affecting the engine too much. But, even tho we hop though all the hoops to make it stable, the engine still overcompensates when a collision occurs, and move the geometries too far away from each other. Thus, removing all contacts and fire the OnSeparation
event. Then the whole thing happens all over again.
Conclusion is that this howto is needed to emulate the correct behavior of OnCollision and OnSeparation events. The engine fire them at the correct time, but computers are not precise enugh to make them fire only when we want.