Lesson 3

Inverse kinematics

Animation says how joints turn; gameplay says where a hand or foot must be. Two-bone IK solves an arm or a leg exactly; CCD and FABRIK iterate along longer chains; a look-at spreads a turn down the spine; foot placement puts animation made on flat floors onto real ground.

Forward kinematics goes from joint angles to where things end up. Games constantly need the reverse: put this hand on the ledge, this foot on the step, these eyes on the player. Inverse kinematics (IK) finds joint angles that put the end of a chain on a target. It almost always runs after the animation, as a correction on top of it.

Two bones: an exact answer

Arms and legs are two bones (upper and lower), and two bones have a closed-form solution. With bone lengths a and b and distance d from the root (shoulder, hip) to the target, the law of cosines gives the angle at the root between the first bone and the line to the target:

cos A = (a² + d² − b²) / (2ad)

and the bend at the middle joint the same way. Clamp d between |a − b| and a + b first, so an out-of-reach target gives a straight limb pointing at it instead of a NaN.

There are always two answers, mirrored across the root–target line: elbow up or down, knee forward or back. A pole (Unreal calls it a joint target, Maya a pole vector) picks the side: the middle joint goes on the same side as the pole.

// 2D for clarity; in 3D the pole defines the plane the limb bends in.
TwoBone solve_two_bone(Vec2 root, float a, float b, Vec2 target, Vec2 pole) {
    Vec2  to   = target - root;
    float d    = std::clamp(length(to), std::abs(a - b) + 1e-5f, a + b - 1e-5f);
    float A    = std::acos(std::clamp((a*a + d*d - b*b) / (2*a*d), -1.0f, 1.0f));
    float side = cross(to, pole - root) >= 0 ? 1.0f : -1.0f;     // which side of the line is the pole?
    float a1   = std::atan2(to.y, to.x) + side * A;
    Vec2  mid  = root + a * Vec2{std::cos(a1), std::sin(a1)};
    Vec2  end  = root + normalize(to) * d;                        // on the target when reachable
    return { mid, end };
}

It’s exact, costs one acos and a couple of atan2s, and has no iterations, which is why nearly every engine’s arm and leg IK is this. The lab’s clips use it too: each locomotion clip is built by moving the feet along paths and solving the legs with it.

Drag a two-bone arm and its pole in the animation lab →

Longer chains: CCD and FABRIK

Past two bones there’s no closed form, so solvers iterate. The two classic ones:

  • CCD, cyclic coordinate descent (Wang and Chen, 1991): go through the joints from the end inwards, rotating each so the end effector lies on the line from that joint to the target. Repeat. Simple, and joint limits are easy to apply, one joint at a time. But it moves the joints near the end most, and can curl the chain up on the way.
  • FABRIK, forward and backward reaching IK (Aristidou and Lasenby, 2011): work on positions, not angles. Put the end on the target and walk back to the root, placing each joint on the line to the next at the bone’s length; then pin the root and walk out again. No angles, no matrices, and an unreachable target is answered in one pass by laying the chain straight towards it.
void fabrik_iteration(Vec2* p, const float* len, int n, Vec2 root, Vec2 target) {
    p[n] = target;                                                  // forward reaching: from the end in
    for (int i = n - 1; i >= 0; --i) p[i] = p[i+1] + normalize(p[i] - p[i+1]) * len[i];
    p[0] = root;                                                    // backward reaching: from the root out
    for (int i = 0; i < n; ++i)      p[i+1] = p[i] + normalize(p[i+1] - p[i]) * len[i];
}

Loading…

The same six-bone chain and target on both sides, each solved from the straight chain to within 1 mm. On this target CCD needs 7 iterations and FABRIK 1, and CCD’s answer bends through 431° in total against FABRIK’s 154°: CCD has turned the joints near the tip hard, which reads as a curl. Tick show every iteration to watch CCD sweep the chain round, then drag the target behind the base.

Over many targets the gap holds. On 500 random reachable targets for this 6-bone chain, CCD takes 30.1 iterations on average and misses 1 mm within 100 iterations on 56 of them; FABRIK takes 7.2 and never misses. The FABRIK paper reports the same direction on its own tests.

In a game the target moves a little each frame, so solve from last frame’s answer. Pick Last answer and drag: on a target moving 6 mm a frame, either solver needs at most 2 iterations. That warm start matters more than the choice of solver.

Looking at things: spread the turn

A look-at turns the head to face a target. Turn only the head and it looks like a head on a swivel, and runs out of range fast. Instead, spread the turn down the chain, a share per joint, each clamped to its own limit, with what a clamped joint can’t take passed to the joints still free. Here the spine takes 15%, the chest 20%, the neck 25% and the head the rest (40%), each up to its limit (15°, 20°, 35° and 50°). With these limits the head alone turns 50°; spread down the spine, 120°. Past that the character should turn its feet, which is the state machine’s job, not the look-at’s.

Compare the spread look-at with head only in the animation lab →

Feet on uneven ground

Animations are made on flat floors. On a step one foot floats or sinks: standing with one foot on each side of a 15 cm step, the lower foot hangs 15.0 cm in the air.

Loading…

It starts with foot IK off on that step. Move the character along the ramp and steps (drag the ground or use the slider), then tick foot IK.

Foot placement runs after the animation each frame:

  1. Trace the ground under each foot (a ray or shape cast from above the ankle).
  2. Move each foot that is planted in the animation (near the floor) up or down by the ground’s height there; leave swinging feet alone, fading the correction by height so feet don’t snap.
  3. Lower the pelvis by the most any foot has to go down, so the legs can reach. Never raise it: the higher foot just bends its knee more.
  4. Re-solve each leg with two-bone IK, knee forward (the pole), and tilt each foot to the ground’s slope.

On the step the pelvis drops the full step height and both feet land. Walking over rough ground with root motion, the deepest a foot goes into the ground drops from 13.7 cm without foot placement to 2.6 cm with it; what remains is the walk-to-run blend itself, which sinks a foot that far on flat ground too.

Takeaways

  • IK finds joint angles for a target; in games it’s a correction after the animation.
  • Two-bone IK is exact: the law of cosines plus a pole to pick the side the middle joint bends.
  • Longer chains iterate. FABRIK converges in far fewer iterations than CCD and doesn’t curl; CCD makes per-joint limits easy. Warm-start from last frame either way.
  • Spread a look-at down the spine, each joint clamped, to get a natural range.
  • Foot placement: trace the ground, move planted feet, lower the pelvis, re-solve the legs.

In the lab

The lab’s IK view has all four: the two-bone arm with its pole, CCD and FABRIK with any number of bones, the look-at spread or head-only, and foot placement while walking over a level.

Open CCD and FABRIK in the animation lab →

Further reading