Making a simple Physics Engine: Episode 2
An impulse is a force that is applied in an instant. Whereas normal forces act over a perios of time, impulses change the momentum of an object immediately. They are therefore used for collisions and other such "instananeous" events.
They are literally as simple as saying:
momentum = momentum + impulse
Inter-body collision detection and response
Next we go on to actually use impulse forces for something - namely collision response. First though we need to detect collisions.
Currently I am assuming (and will likely carry on assuming) that all objects are spheres. This makes collisions detection a doddle and also prevents objects snagging on sharp edges. This is not such a bad way of handling things - it makes life simpler and still prodsuces believable results.
To detect a collisions we first see whether the two volumes/bodies involved overlap. If we use spheres this is easy; we simply compare the distance between the centre points with the combined radius of the spheres. Assuming that two objects are overlapping we then check whether they are moving towards each other. This is important. As the complexity of the engine grows there will be many situations where objects may frequently stay overlapping for several timesteps.
If we applied forces when objects overlapped - even when they were moving apart - we might get bizarre side effects. For example if we applied an impulse in the opposite direction to the objects momentum, then the objects would be pulled back in to the collision. Not good. If we always ensured that impulses were applied to push were applied to push objects apart, then we would get extra acceleration and objects would appear to fly apart.
Once we have have detected a collision we need to respond to it. First we calculate the total difference in momentum of the system. We then use this to calculate the impulses to apply to te objects:
// calculate impulse and apply to objects
// 0 < r < 1 = restituition
momentum_diff = momentum1 - momentum2
impulse = -(1 + r) * momentum_diff
object1.apply_impulse( impulse )
object2.apply_impulse( -impulse )
I will explain that a bit now. When the two objects collide the objects will typically reverse direction. To do this we first need at least the same amount of momentum, but in the reverse direction and second a bit more to not just remove the current momentum. That is what the -(1 + r) is for. The - is for reversing the direction. The 1 for at least equalling the size of the momentum and the r for actually reversing it. So if r, the constant of restituion, was zero then the objects would stop (assuming a few things). If it was 1 then the momentums would totally change direction.
Well that is roughly it for inter-object collisions. At the moment I merely compare all objects with all other objects, but later I shall probably introduce some cleverness (such as a quadtree) to reduce the number of collisions checks.
Next object scenery collisions.