Tuesday April 16, 2024

 Physics.... Bouncing Objects, Springs, Balls, Rigid Bodies...

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.

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.

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 :)