SuperAPI AI Directory

anymove-rig

Design & creation

View repository

Updated 11-04 16:17

About this skill

anymove-rig: one creature, ready to film

Everything for creature <c> lives in assets/<c>/: model.glb (the mesh), creature.json (framing, paint, words for the prompt), rig.json (the skeleton). Copy a close example to start: assets/wolf (quadruped), assets/dragon (quadruped with wings), assets/spider (eight legs), assets/demon (biped with wings and tail).

1. The mesh

  • Any textured GLB works. anymove's examples are Tripo H3.1 (tripo3d/h3.1/image-to-3d on fal, $0.40 with HD texture) from one FLUX 3 concept image: a plain 3/4 view of the creature on a neutral background, whole body in frame, limbs apart and clearly separate.
  • Prefer a design where every limb reads separately. Fire, smoke, capes, weapons and long hair hide joints from the reader later; leave them to game VFX.

2. Face it, scale it, stand it on the ground

Fill in creature.json → "prep": {"length_m": ..., "rotz_deg": ..., "axis": "y"}: the real size along axis (y is nose to tail; x for creatures wider than long, like a spider's leg span; z for tall bipeds), and the turn about Z that makes it face -Y. Then:

tools/prep.sh <c>        # assets/<c>/prep/static.blend, verts.npy, and views.png (side, front, top, 10 cm grid)

Check assets/<c>/prep/views.png: in the side view the head is on the right, the feet sit on z = 0, and both feet of a pair are level in the front view. Tripo's align_image orientation can leave a creature turned a few degrees; fix rotz_deg until the feet are level (the demon needed -73, not -90). If unsure which way it faces, run blender -b -P blender/inspect_mesh.py -- assets/<c>/model.glb runs/<c>/inspect and look at the four views.

3. The skeleton: rig.json

Metres in the prepped mesh's frame: the creature faces -Y, its left is +X, Z is up, the ground is z = 0.

{
  "joints": {"hips": [0, 0.32, 0.86], "spine1": [0, 0.05, 0.95], "shoulder_L": [0.21, -0.55, 1.02]},
  "bones": [["pelvis", "hips", "spine1", null], ["upperarm_L", "shoulder_L", "elbow_L", "chest"]],
  "limits_deg": {"pelvis": [[-30, 30], [-20, 20], [-30, 30]], "upperarm": [[-70, 50], [-10, 10], [-25, 25]]}
}
  • joints: name to [x, y, z]. Every _L joint is mirrored to _R (x negated) unless you give the _R joint yourself; give both for asymmetric meshes (the dragon's wings).
  • bones: [name, head joint, tail joint, parent]. The first bone is the root (free to turn and move). _L bones are mirrored too. Joints at bone ends are what the reader learns to find, so put one at every place the video should control: paw tips, wing tips, tail segments (6 for a long tail), jaw if the mouth opens.
  • limits_deg: per bone name, or per stem without _L/_R: [[x lo, x hi], [y lo, y hi], [z lo, z hi]] in degrees. Local X is the bending axis (world X for bones in the body's plane), Y runs along the bone (twist: small for spine and legs, ±8-20; arms can need ±40), Z swings sideways. Limits shape the training poses as well as the fit: too wide and the reader learns impossible poses, too narrow and it can't read the move.

Place joints from the grid views. After each edit:

tools/prep.sh <c>               # redraws views.png with the joints and bones on the grid
tools/rig.sh <c> preview        # joints over an x-ray of the mesh: assets/<c>/prep/preview/joints_{side,front,top}.png

Joints belong inside the limb, at the pivot: the elbow at the bend, not on the skin. For legs, take the centre line from the side and front views; for wings, put the wrist and finger tips on the membrane's edge.

4. Build, skin, paint, render the reference

Fill in creature.json → "paint": one group per limb with a colour and the bones it covers, left and right in different colours, all colours far apart (pink #F53CD1, blue #2F6BFF, yellow #FFD21F, cyan #19D3E0, orange #FF7A1A, green #2BD94A, purple #9B4DFF, red #FF2B2B). Set "feet" to the paw or foot joints (the sync score uses them).

tools/rig.sh <c>     # assets/<c>/rigged/{rigged.blend, rig_info.json, testpose_*.png}, runs/<c>/ref/ref.png

build_rig.py merges the seam vertices first (Tripo splits the mesh at every texture seam; skipping this tears the thighs open when a joint bends), skins with Blender's automatic weights, smooths them and keeps 4 bones per vertex. Check testpose_front.png and testpose_side.png: the bent limbs stay whole and only the painted part moves.

5. The two-camera framing: creature.json "layout"

{"W_FRONT": 640, "W_SIDE": 640, "M_PER_PX": 0.006875, "GROUND_V": 630}: widths of the two views in pixels (they sum to 1280; 420 + 860 suits a long, narrow quadruped, 640 + 640 a wide one), metres per pixel, and the ground's pixel row in the 720-row frame. The creature in its biggest pose must fit both views with margin: height under about GROUND_V × M_PER_PX × 0.85, width under W_FRONT × M_PER_PX, length under W_SIDE × M_PER_PX. A dragon rearing with wings up needs more headroom than one standing. Re-run tools/rig.sh <c> after changing it and look at runs/<c>/ref/ref.png: the whole creature, both views, a dark divider between them, nothing touching an edge.

6. Words for the prompt

Also in creature.json: name ("spider"), noun ("giant spider"), describe ("a black armoured giant spider with bone-coloured markings"), colour_code ("first left leg pink, first right leg blue; ..."), count ("Exactly eight legs, two fangs, one body, one round abdomen."), flank ("flank" or "side") and limbs ("legs" or "limbs"). tools/make_prompt.py builds every prompt from these (anymove-film).

Last, "camera": {"cam": "-5.4,-6.0,1.4", "target": "0,-0.3,1.5", "lens": 32} is the 3/4 view that tools/capture.sh renders each move from (anymove-capture says how to frame it). Without it, the wolf's applies.

Failure modes seen

  • Torn or gaping thighs when a leg bends: seam vertices weren't merged (a mesh from a tool other than build_rig.py), or a joint sits outside the limb.
  • A limb half painted: the paint group misses a bone, or the weights spill onto the body; move the joint, rebuild.
  • The rig bends the wrong way: the bone's local X isn't the bending axis. Keep bones of a limb in one plane.
  • Automatic rigging (UniRig) can replace hand placement; its install pulls prebuilt flash-attn wheels from GitHub.