ATTENTION READERS! Lucky's VB Gaming Site is no longer active. For updated game programming information and tutorials, please visit The Game Programming Wiki!
Doing it the other way 'round: Inverse Kinematics by Thomas 'ThamasTah' van Dijk
Please note, that it is recommended that you read my Skeletal Modelling tutorial.
Introduction
In this tutorial, we'll have a look at applying a force to the bones. Later
on, this involves some Inverse Kinematics, I think... ;)
This tutorial just discusses the theory behind it. No code :(
Theory
Okay, here we go then!
Applying Force
Forces: we describe them using a vector -- angle and length (which in this
case is power). New in this version of the Skeletal Modelling system is cVelocity,
which is the angular velocity. In other words: how much we need to increment
the angle each time unit.
We'll start with just one bone. (I only account for forces applied to the ending
point of a bone.)
I'll use the following: F(u) is the force applied by the user and cVel is the
angular velocity added to the bone. We'll treat bone as a vector.
cVel = the component of F(u) perpendicular to bone. Sounds confusing? It actually
makes sense (to me ;). I'll illustrate the application of a force using three
examples:
That's all there's to it. (I say that a lot, don't I...)
Influencing the Parent
The above should be correct. Here is where the experimentation comes in. As
a first try: if a force is applied to a bone, it applies it to its parent (which
applies it to its parent, etc.) This is illustrated below with two bones.
Note:
radius of the green circle = | F(u) |,
| F(u) | = | F(bone1) |,
F(u) is parallel to F(bone1).
I haven't tried this, but I imagine this is not how it's supposed
to be: the parent would be equally influenced. No good!
A possible solution is to use a fraction of the length of F(u),
e.g.
| F(bone1) | = 0.5 * | F(u) |
or, better:
| F(bone1) | = stiffness * | F(u) |
where stiffness is a Single/Double between 0 and 1.
This is getting better, but still not quite it...
The angle between bone1 (parent) and bone2 (child) also influences the magnitude
of the force applied to bone1. If bone1 and bone2 are perpendicular, the force
on bone1 is at its max, whereas it is at its minimum when they are parallel.
Well, we'll just add another fraction.
We calculate the bone1-component of bone2 (a projection of bone2 on bone1) and
devide that by the length of bone2. That will give us a value between 0 and
1. It will be 1 when b1 and b2 are parallel, which is the wrong way 'round.
Fixing that, we get:
,
or perhaps it should be
,
so we won't multiply by 0 if they are parallel, but by 0.5: the parent always
gets a force, just not as big as the child.
You may want to experiment with other values for '0.5', it's just a value I
chose. Go with what looks best.
Note that the above formula can prolly be optimized a lot if you use goneometrics:
calculate the angle between b1 and b2 (you already know that in the Skeletal
Modelling example) and then use the absolute value of the [sine or cosine, haven't
thought about it yet] of that angle. That should give the same result, shouldn't
it?
As a final note: this will probably conflict with any animation code. Anybody
got ideas on a fix for that?
That's all, folks: happy kinemation!
Conclusion
I haven't the time to code this stuff, but I suppose it will work.
Thomas 'ThamasTah' van Dijk
paxdev@hotmail.com
dec 3 2000