| Simple Rigid Body Physics by 
Ben Kenwright   Lots of bouncy of Cubes and Balls....well thats how it should begin....and 
you'll find that 90% of all your game physics can be approximated with these 
objects....for example, if we where going to do a racing car...we'd approximate 
it as a box!....for a character, we'd approximate all his box parts using lots 
of spheres...its simple and effective!...always keep it simple :)   Some things we've got to look at: Work out the collision, and for each collision point we work out its 
position, collision normal and its penetration distance.... We've got to add in 
static and dynamic friction.... Then theres the added complexity of stacking 
...I mean anyone can bounce a single cube around...but put 2 or 3 of them on top 
of each other and just watch them go funny ...either sinking of jiggling out of 
control with a life of there own!   Keep it simple!   The best code is the simplest...we'll use the 
basics that work and add in some extra tweeks to account for problems that we 
notice.   Impulse based game physics are simple, math is quiet easy to understand and 
implement and its usually very robust.   The two areas that usually cause problems is making objects not jiggle and 
bounce making them stack and slide (friction).   Sleeping is one way to fix some things...To-Do   The algorithm at its simples is:   
      Collision Detection (Store all the contact points)    AddForces (i.e. Gravity)    Update Velocitys (Angular & Linear)    Apply Impulses    Update Position & Rotation    Loop   For the Collision Detection examples I've used Object Bounding Boxes (OBB's) 
...since its much more realistic and useful than dealing with spheres....as we 
can have multiple contact points for a single shape.  The collision 
detection code can be a bit messy, but for each collision point you need to 
determine its position, normal and penetration depth....this was done using 
Seperating Axis Test and a mixture of plane clipping.     
  
    |  | The two main parts of a collision impulse are the Normal 
    impulse, which basically pushes the objects appart...without this, we've got 
    problems...they'd just penetrate each other.  Next we have the Friction 
    impulse, which would stop our object from sliding, we in effect set a 
    friction threshold, so an object sitting on a steep slope wouldn't just 
    jiggle down the slop, alternatively it would just sit still...unless its 
    throw with some force to cause it to slide along the tangent slope.   One thing to notice is that the Impulse along the normal should be 
    pushing the objects away from each other...hence it must be >0.....else it 
    would be pulling them together!!! |      Relative velocity - it allows us to determine the state of each collision 
point...very important when we have multiple collision points, as you'll see, we 
iterate over our collision data a few times for each update to remove jitter and 
stablise our values, and we can determine when and which collision points need 
further updating :)     
  
    | Once we know the relative velocity for a collision point 
    tells us the objects are approaching each other, we can apply a suitable 
    collision pulse which will push them apart.     |  |      Working out the normal impulse, so that the collision points velocity is 
reduced to zero is just as easy as:       One great bit of extra code you'll need, is a bit of biasing code that 
prevents our objects sinking!  Its such a simple bit of extra code, but it 
makes things so much more stable.   
  
    | It uses the following facts: 
      Proportional to the penetration depthAllow some penetration (also sometimes called slop)Impulse is along the normalSmall!   One thing you'll be able to notice with the bias factor, is that for 
    single objects on the floor it takes a long time before sinking can 
    happen...and maybe for a couple of objects....but once you start stacking 
    cubes and having a lot more interaction, you'll notice the objects sinking 
    into each other more....try toggling it on and off and see :)   |  |    
  
    |  | Added bias not makes our objects more stable...and leads to 
    a more robust system.   Onions!....one thing to look into is different penetration depths causing 
    different responses...as some of the comercial engines take do different 
    htings in different cases...for example, if the penetration was over a 
    certain threshold, you'd actually push the position of the object back along 
    that direction...would cause a jump of the object...but if it reached that 
    threshold it would be going to far into the other object..maybe even passing 
    through it...but you get the idea.     |      Friction!...you don't want your cubes to slide!.  Using the basic 
impulse above, this works great and is all thats needed for simple flat 
worlds...but if you stack a couple of cubes, or put a cube/ball or some other 
object on a slope...then it will just slide off the edge!.  As we dont have 
any friction!  We can do this by taking the tangental direction part of the 
collision and working out how much along that direction is happening...then 
we'll clamp it, so it's not allowed to move along that direction unless its over 
a certain threshold :)   
  
    | The tangent impulse Pt, is tricky to see at 
    first!...basically its an impulse which will STOP any movement along the 
    tangent direction.  So between a minimum and maximum range, there will 
    be no slipping!....hence Pt will counteract the tangent force to keep the 
    object from slipping.   The threshold is determined to be proportional to the normal impulse, so 
    once it passes as certain magnitude, we let it slide. |  |    The basic equations for impulses all rely on the principle of a single 
collision point....but we're interested in Multiple collision points...for 
example, a chair sitting on the floor would have an impulse for each leg...and a 
cube on a plane, we'd have an impulse for the four corners.  The problem is 
applying an impulse to one corner rotates and shifts the object so that when we 
apply it to the other corners the object is no longer correct.    Secret to making it work, it so continue to apply impulses multiple times to 
our object collision points until it settles down.   
  
    |  | 
      Apply an impulse at each contact pointContinue applying impulses for fixed number of iterations   |      So the heart of the program code looks like this...and produces some 
reasonably stable rigid body results:   
  
    | Code Snippet: |  
    | ... 
    void 
    Step( float dt ) 
    { 
         
    // Integrate Forces 
         
    for (int i=0; 
    i<g_numCubes; i++) 
          { 
                
    g_cubes[i].UpdateVel(dt); 
          } 
      
         
    // Update a few times to take into account 
    stacking and multiple 
         
    // contact points - applys impulse to each contact 
    point on the cube 
         
    for (int i=0; 
    i<g_numIterations; i++) 
          { 
                
    ApplyImpulses(dt); 
          } 
      
         
    // Finally update the new position of our cube 
         
    for (int i=0; 
    i<g_numCubes; i++) 
          { 
                
    g_cubes[i].UpdatePos( dt ); 
          } 
    } 
    ... |            
  
    | I put together a simple demo that demonstrates various test 
    senarious using cubes...either on a plane or stacked...the performance in 
    release stays around 60fps with 20 boxes stacked so its not to bad...but you 
    can easily make it more efficient...most of the code has been kept simple so 
    you can follow it.   Everything in the demo is 3D Cubes....even the ground is a large thin 
    cube which is imovable...but it would be so easy to add in other shapes once 
    you get to grips with the basics...Sphere-sphere, sphere-box, convex poly's 
    etc.   Download Source Code 
    (30k)   On the right you can see some screenshots of some test cases. |  |      Sleeping! Now we can make things more stable and happy by not updating objects when 
there kinetic energy level falls below a certain threshold....we meet some 
certain criteria so it wakes up under certain conditions.  So how do we 
determine the kinetic energy of an object?....well its really quiet smart.  
The energy for kinetic energy is:   
  
    |    | We have access to all the values to calculate the kinetic 
    energy...but we can make it a lot more simple...as things like mass and the 
    moment of inertia are constant!....also, the 0.5 is constant...so we can in 
    effect simplify it down to:     This means that the code to caculate our rigid body motion simply 
    becomes:   
            float 
    motion =  Dot(m_linVelocity, m_linVelocity) +  
    
                            Dot(m_angVelocity, m_angVelocity);     |    But if you use this motion value as is, you'll find its still inefficient, 
because the linear/angular velocities can jump arround a lot and are quiet 
irratic at times due to the objecta all bouncing around like crazy beans.... so 
we'll include some linear interpolation between the current value and the next 
one...so depending upon some scalar value we pass in, depends how fast it 
converges to its new value....This is sometimes called RWA - Recently Weighted 
Average...but I usually just think of it as lerping.   
           
float motion =  Dot(m_linVelocity, m_linVelocity) 
+  
                            Dot(m_angVelocity, m_angVelocity); 
  
           
float bias = 0.96f; 
            m_rwaMotion = bias*m_rwaMotion + (1-bias)*motion;   The closer the bias is to 1.0f the slower it goes to the new value....so if 
its 1.0f, then it would never go to the new motion value and would remain at the 
old value...if we make it 0.0f, then it would immediately go the new value....  
We call this function in our main update loop so its updated each frame.   Now to determine when our object sleeps or wakes up, we test the motion value 
against some test epsion value:   
       
   if (m_rwaMotion < g_sleepEpsilon) 
           { 
              m_awake 
= false; 
              m_linVelocity 
= D3DXVECTOR3(0,0,0); 
              m_angVelocity 
= D3DXVECTOR3(0,0,0); 
           } 
       
   else if 
(m_rwaMotion > 10 * g_sleepEpsilon) 
           { 
              m_rwaMotion 
= 10 * g_sleepEpsilon; 
              m_awake 
= true; 
           }   If our motion is less than the epsilon value...I found 0.05 a good 
value...but a bit of trial and error is good.....once an object falls alseep...it 
takes a larger value to wake it up...so an object isn't sleeping and waking up 
all the time...so to fix this, a wake up value of 10 times sleepEpsilon is 
required.   Some additional rules need to be obeyed to keep the system working correctly 
as well:   
  The sleeping object must be in a collision with another sleeping object or 
  in collision with an object with infinite mass.If the sleeping object is in a collision with another object who's motion 
  energy is over 2 times sleepEpsilon then our object must wake up.The objects motion energy must be below sleepEpison to go to sleep. (Also 
  it must remain below this threshold for a certain time)   As a side not, I've added in the demo whether we want to start our objects 
asleep or awake...for example if we start them awake, we start with an initial 
motion value greater than sleepEpsilon...then it would take 5-6 frames for the 
objects to settle down and go to sleep.  But I found if your doing walls 
and other stacked objects it was reasonable to assume the objects starting 
asleep, since there all resting on each other.....its a bit tricker if your 
objects start all mashed together in the sky...as you'd have to add an extra 
check to check if groups of sleeping objects are actually in contact with a 
infinite mass object...such as the ground.   
  
    |  | Adding in sleeping, and a few more complicated test 
    configurations, such as domino's and stack of tables and a some random cubes 
    thrown around the place.   You can start with sleep enabled or disabled when the cubes start...has 
    the added benefit of not having to wait for stacked cubes to settle.   So you can actually notice the objects go to sleep, I've done it so that 
    for debug when an object goes to sleep, its alpha is set at 50%.   Using 20-30 boxes the frame rate remained pretty stable...even when the 
    20 objects where all asleep so wern't being updated, the limiting factor is 
    the collision detection...so with a lot of collision detection optimisation 
    you could dramatically increase the number of objects to the hundreds.   Download 
    Source Code (31k)   Compile with Visual Studio 2005 and Directx9.1     |          Other things to add later on, which are for later tutorials are: Contact point caching...so new contacts are added to a list, and we can keep 
track of how old/new a contact point is Optimize the code for multiple iterations - certain things we do when we 
iterate over the impulse code can be taken out of the loop as there values 
remain the same. Better Sleep code - hundreds or thousands of rigid bodies in a world, but 
only update those which aren't sleeping.   Further Reading                                       |