vidar.games

Procedural dribble + IK

2026-11-05 · Discuss on X

Same ball, same bounces on both sides.
Left: one hand animation, looped. Right: the hand is placed by code every bounce, so it meets the ball at any height and tempo.

The problem

A dribble is usually a looped animation with the ball baked into it. That holds as long as nothing changes. Speed the dribble up or drop it lower and the clip has no answer: the hand pats the air while the ball is already on its way back up.

How it works

  1. The ball is pure physics. Pushed down from hand height, it falls, bounces with a restitution of 0.78 and rises again. All of that is solved ahead, so the code knows when and where the ball will reach the hand before it gets there.
  2. The hand rides the ball. During contact the hand stays on the ball's top: it slows the ball at 22 m/s² and pushes it back down at the next push speed.
  3. Between contacts, the hand follows a smooth curve from the release point to the predicted catch point.
  4. Inverse kinematics bends the shoulder, elbow and wrist so the fingertips land on that point. The knees bend with the dribble height.

Shooting uses the same idea. Pick a release angle, then solve the speed that sends the ball through the rim centre: from 4.0 m at 55° that's 6.94 m/s; from 6.8 m at 51°, 8.66 m/s.

What I hit

A low dribble at 0.62 m was out of reach: the arm is too short unless the body drops. The low dribble is now 0.72 m, and the hips sink and lean forward as the hand goes down.

My first stills looked like the hand never touched the ball. The IK was fine; the camera hid the arm behind the body. A side view shows it.

The shots first cut away before the ball reached the rim. Flight times are 1.01 to 1.25 s, so each shot now gets its own length.

My build

three.js (dev branch, r187): CCDIKSolver on the right arm (3 links, 12 iterations per frame, elbow and wrist limits), used unchanged. The character is my own: boxes skinned to a 23-bone skeleton built in code. Ball physics, hand timing, knee bend, shot solver and court are mine.

Tempo in the video: 1.7 bounces per second at 0.98 m, then 2.4 at 0.72 m, then 1.8 at 0.88 m. The loop on the left is the first one, repeated.

Trade-offs

When to use it

Sports games, ball tricks, juggling and any hand that has to meet a moving object on time.

New breakdowns go out on X first: @vidar_0208. If this one helped, you can buy me a coffee.

Source and credits

Repo: github.com/mrdoob/three.js (MIT license), branch dev, commit fa01dd6. CCDIKSolver (examples/jsm/animation) used unchanged, set up like examples/webgl_animation_skinning_ik.html. three.js by @mrdoob and contributors.

My own code: the procedural character (boxes skinned to a 23-bone skeleton), ball bounce physics, hand timing, knee bend, shot speed solver and court. No external models or animation.

Topic credit: @alightinastorm's procedural basketball character in three.js, https://x.com/alightinastorm/status/2117437967946182697. None of their code, character or scene is used.