Penalty Collisions Using
Springs
by
Ben Kenwright
This is a great solution to the problem of physics....the solution is to use
springs for the collisions, so for example if an object is sitting on the floor,
you'd use springs to push the object out of the ground....so the spring will
keep the objects from penetrating each other. This method of using springs
to keep objects apart, sphere/boxes and other rigid bodies is known as the
penalty based method.
It can also be mixed with other collision detection methods to keep objects
from interpenetrating....so if objects gradually interpenetrate...instead of
just pushing them apart, you add in a spring so it gradually pushes them apart
and looks more natural and smooth.
The biggest problem of using springs is stability...for example, if you have
a fast moving object and it hits the ground, the spring necessary to prevent the
object going into the ground would need to be massive...and for very large
springs, and a limited size time step size, this can lead to unstable springs
and unrealistic values...and then objects just flying off into space.
You can of course clamp these things...and it can require lots of tweaking,
but you can get some nice results....I put together an object made up of lots of
cubes, in various configurations, stacking, different sizes, lengths etc, so you
could toggle between them and see what you thought. I've limited the
springs to some limited value, so as objects bounce around and interact it they
sort of look like jelly or rubber...interesting effect.
 |
You'll find if you implement this method that you get a lot
of bounciness, as objects that are stacked sort of jiggle because of the
springs...but with damping and reasonably stiff springs you can come up with
a pretty good demo.
The major disadvantage to using springs for collisions, is that it
usually requires lots of tweaking...and depending upon the collision can
lead to instability...always best to do lots of clamping checks to make sure
you don't get any build-up of extreme forces, like when objects are shot
from a cannon and hit a wall...don't want the spring return value causing
crazy large forces and just breaking the whole system.
The spring law which you'll find defined all on the net and in any
physics/mechanics book, is Hooks Law:
F = -kx |
Where F and x are Vectors, and k is a scaling scalar quantity. What is
x? Well x is the displacement error...so if our spring at rest, with no
force acting on it is x0, and then we stretch it to a length x1...then our x
value is (x1 - x0).....if that makes sense?
For our code, we will assume that x is our penetration depth...and its along
the penetration normal...and our k value will be our scaling value to make sure
our force is suitable to push the object appart...it has to be a suitably high
value to push the weight of the object out of penetration...and it has to have a
suitably high value to account for the object accelerating towards
penetration....just some trial and error and you'll find a value quiet easy.
// Each of the objects gets half the penetration
distance...this should be
// scaled by the mass radio's of the two objects
D3DXVECTOR3 p0 = hitPoint + hitNormal*penetrationDist*0.5f; // + direction
D3DXVECTOR3 p1 = hitPoint - hitNormal*penetrationDist*0.5f; // - direction
// Work out the displacement value
D3DXVECTOR3 x0 = p0 - hitPoint;
D3DXVECTOR3 x1 = p1 - hitPoint;
// Seems like a reasonably not to bouncy value
float k = 50.0f;
// Got hooks law
D3DXVECTOR3 force0 = x0 * k;
D3DXVECTOR3 force1 = x1 * k;
// Add the force to our cubes
cube0->m_force += force0;
cube1->m_force += force1;
One thing you'll definetly need to add is damping...as without it, theres not
end to the amount of bouncing going on....I found just adding a small damping
value to the object velocity worked quiet well.
// Add some damping
cube0->m_velocity *= 0.98f
But I'm sure a bit of trial and error and take it a long way...using the same
principle you can stick objects together with springs...build up bridges, car
wheels attached to frame, character bodys all stuck together with springs :D
To show how easy and effective a Penatly based system is I
threw together a simple 3D demo in DX 9.1 and using Cubes....the most
complicated part of the code is the collision detection for cubes...but I
think its a much more flexible demo...and doing it for sphere or making it
2D is really easy.
Source Code (DirectX 9.1 & Win32 & Visual Studio) [26k]
You can select various configurations and rotate around the shapes and
see lots of debug information to see what's happening...collision points,
penetration depth and pause/single step to watch it.
To the right are some screenshots with the various configurations.
|
|
If you have any problems or questions on the subject please dont hesitate to
email me....I only threw the demo together quickly, but I'm sure it really opens
your eyes to just how easily a penalty based world can be put together using
springs....and one of the best things is the performance hit isn't really that
big....again, the biggest part of the code was doing the Object Bounding Box
collision detection code, which was so I could have lots of boxes and it would
work out the exact collision points for each box...even the floor is a big box
:)
|