Hive Assault: Impulse Physics



Dynamic Animation Calculations in Hive Assault
Real-time Calculation of Bone Impulse Reactions from Weapons
Chris Oubre, 2001. Email: chris_oubre@hotmail.com


Balistic Kinematics

What happens when a person is shot with a bullet in real life? Well of course there is masive damage and much pain but..... do they "take it like a man"? Heck no! They recoile from the impact and otherwise get knocked around. So in Hive Assault we HAD to have our players show some sign that they'd been hit. Now we could have just put up a blood spray and some pre-canned animations....

but why not use our great skellital animation system to create on the fly unique animations "true" to physics, where each and every bullet bends the skelletton as a single collider? Well that's where I came in. As a grad student in Physics, I am in the best position to implement these cool effects.

Now this is no easy task. There are there major obsticals to overcome.
1) How does the physics work? How do you propigate the impact force down, and up the limbs? What about friction?
2) How do we know which bone was hit?
3) Every limb is in a different coordinate space from every other limb, AND the bullet is in another space entierly!

Solving the Physics: a compromise with morals.

As the title sugests, the physics isn't entierly true to life; however it does provide nice numbers though. :) I considered what would happen to a lamp if it were hit with an impulse force. The lamp would feel a torque from the part of the force that is tangential to the segment being hit. The parrent segment, the segment before the one hit, would feel the parallel part of the force along the direction of the inital segment hit plus a frictional componant. This frinctional componant reflects the fact that if a joint has alot of friction it will propgate most of the force up the tree. This frcitional componant has very little physics in its compuation. We just used what we thought was a reasonable guess for the magnitude.

Now to figure out the change in angle, I had to compromise with my morals. I assume that all impacts will come at the end of segments AND that these segemnts are simply thin rods. It doesn't end there :( I had to guesstimate the amount of force a bullet would apply. I then used an impulse formula which I derived that takes a force and a time over which it is applied, and calculates the change in angle. My shame does not end here because I had to include friction in the equation. So I just divided the change in angle by some "friction" to achive this. The "friction" is just a number that was played with until it gave numbers that we liked.

And to at last bear my shame :) to all of you, here is the forumal that I used.

A = ((( F * t) / I) ^2 )/ friction

A = change in angle
F = force
t = time over which it is applied
I = moment of inertial for a thin rod
friction = jiggery-pokery

Jumping from space to space: not another Star Trek clone

Now that we know the Physics, how do we apply it to the result? Well the Physics assumes that the vector for the bullet and all of the limbs are in the same coordinate space. This we know is NOT the case. The bullet is in world coordinates, and each limb is in its own set of coordinates. So now that we know the problems, lets look for a solution...

1) Finding the Bone that was hit.

We will need both the bone's and the bullet's vectors in the same space to do intersection detection. We are then presented with three choices: convert the bullet to bone space, convert the bone to world space, or convert both to some other space. We chose to convert the bone to world space for a number of reasons. The bullet's vector will be needed for all comparisons, where as each bone's vector will be used on average only once. So to avoid the storage of an unrotated bullet vector and the unrotation of the bullet vector, we simply rotate the limb to world space.

Well we now know what space to do the collision dection in but how do we get there? The skelletal system works off of default positions. The default vectors of each bone are stored in root bone space. Then to get to the current locations of a given bone, we rotate that vector. Well when the collison occurs, it is most probably NOT in the default position, so we need a rotation that will take us from the bent space to the default . So we store a quaternion for each bone that will rotate from the bent position to the default position. This allows us (through conjugation)to go back and forth from Bent space to Root space. Quaternions alow us a very easy and fast way of inverting the rotation matrix.

Well we have rotations but not trasnlations. In our skelletal system a bone's displacement, is the bone's displacement from its parent in its PARENTS space. So we multiply the bone's displacement by the Quaternerion to the Root space of the parent bone, to put the bone's displacement in Root space.

Now that we have a means of translation and rotation, we can check for a bone collision.

A) Get Bone Displacement
B) Rotate displacement to Root space
C) Rotate Bone's impact vetor to its bent position in Root Space
D) Scale the impact vector to a unti sphere
E) Do a unit sphere intersection

Using all of this: a deeper excersion into the insencible

Ok so we now have the bone that was hit. What do we do? Well we apply the Physics! After calculating the change in angle, when have to rotate the limb. The axis of rotation is given by the cross product between the bone's forward vector and the bullets vector. Using the rotation angle and axis, we construct a quaternian for this rotation. The resulting rotation matrix is then decomposed for the x, y, and z rotations. This infromation is passed to a bending routine which bends the bone and creates a new quaternion to Root space to be stored in the bone.

Now the bone directly hit is NOT the only bone directly affected! We have to propogate the "left over" force up the bone tree, i.e. to the parent bone. This is repeated until the remaining force is negliagble. The left over force has a magnitude equal to the dot product of the force and the bone's forward vector PLUS a frictional componant. The left over force points along the direction of the hit bone.

We could have stoped here, and it would have looked just fine, but we went a step further. We added a reverse force. This reverse force represents the fact that if you are hit in the chest, your chest will go back while your arms will fly forward. This some times gives interesting effects but mostly just muddies up the action.

Looking at what we've done Lastly we need to make sure the animation engine displays the perturbed frames. After every hit with a bullet, we make sure the time to next frame os some constant number so that the bent skeleton is visible.
The results

The ability to look at each and every bullet impact alows GREAT looking animattions from guns like the machine gun and the shotgun, but the reverse force tends to hide a muddy this. Also there was a problem with matching the impact skeleton with the "drawn" skeleton