Miku shipped with 0 cloth chains against Taila's 35, so her twin tails hung off her skull like a helmet. Nothing downstream could fix it: the spring solver simulates cloth BONES, and a garment with none is welded to whatever body bone it was weighted to. Every auto-rigged model is in that state, and her source was an unrigged mesh. tools/cloth_bones.py builds them, which is the job a technical artist does by hand on a model like this. It finds the geometry by MATERIAL SLOT — the artist already answered which surface is hair, and on a joined mesh (what the auto-rig leaves behind) the slot is the only separation left. Hair is split into connected islands, because a strand is a connected piece of surface and clustering by position would merge two ponytails passing near each other. A skirt is split into radial wedges instead, because a skirt is ONE connected surface and islands would return the whole thing as a single piece — the bell-shaped failure. Each clump gets a polyline fitted down its middle by binning vertices by distance and taking centroids, so the chain follows the piece's own curve rather than cutting the corner on a bend, and vertices are re-weighted onto it while the first 22% keeps its original body weight so the scalp stays on the skull. On Miku: 19 chains, 57 bones from one `hair` slot. Sidecar 0 -> 19 chains. Idle stability 0.007-0.018 deg/frame. Mesh intact, verified by render. Opt-in, via `pipeline.py --grow-cloth`, and run before the retarget so describe_rig() finds the chains by name exactly as it would an artist's. Known limits, recorded in the skill: it cannot find a garment sharing a material with the body (Miku's skirt is on her `body` slot, so she got hair and no skirt), and grown chains are a fallback — an artist's chains carry intent that no geometric fit recovers. Co-Authored-By: Claude Opus 5 <[email protected]>
3.5 KiB
Growing cloth bones on a model that has none
tools/cloth_bones.py, opt-in via pipeline.py --grow-cloth.
When you need it
The spring solver simulates cloth bones. A garment with none is welded to whatever body bone it was weighted to, and no runtime setting changes that. Every auto-rigged model is in this state, and so is many a "rigged" download whose skeleton is body-only.
Check before importing (no Blender needed — see separation.md): if the joint
list has nothing matching hair|skirt|tail|ribbon, the costume will not move.
What it does
Runs on the rigged model, before the retarget.
- Finds the geometry by material slot. A slot called
hairis hair. The artist already answered the question, and on a joined mesh — which is what the auto-rig leaves behind — the material slot is the only separation left. - Splits it into clumps.
- Hair: connected islands over the mesh's own edges. A strand is a connected piece of surface; clustering by position would merge two ponytails passing near each other and split one that bends.
- Skirt: radial wedges around the body's up axis. A skirt is ONE connected surface, so islands would return the whole thing as a single piece — which is the bell-shaped failure. Wedges are the ZZZ-convention panel grid.
- Fits a polyline down each clump by binning vertices by distance from the anchored end and taking each bin's centroid, so the chain follows the piece's own curve. A straight root-to-tip line cuts the corner on a bent ponytail and every vertex on the outside of that bend ends up on a bone travelling the wrong way.
- Builds a bone chain along the polyline, parented to the body bone that was already holding that geometry.
- Re-weights each vertex onto the two bones either side of where it projects,
blended by how far between them it lands — while keeping the ORIGINAL body
weight over the first
ROOT_BLEND(22%) of the chain, so the scalp stays on the skull and the waistband stays on the hips.
Then retarget.py::describe_rig finds the chains by name exactly as it would an
artist's, and writes tips, hulls and neighbours to the sidecar.
Tuning
--hair-segments 3 bones per hair strand
--skirt-segments 4 bones per skirt panel
--skirt-panels 12 radial panels; more = opens around a leg more smoothly
--classes hair,skirt which material names to look for
MIN_STRAND_LENGTH (60 mm) and MIN_STRAND_VERTS (12) drop fringe and
ornaments. Simulating those costs the same as a ponytail and only ever produces
jitter around the face.
Worked result: Miku
19 chains, 57 bones grown from one `hair` material slot
sidecar: 0 cloth chains -> 19
idle stability: 0.007-0.018 deg/frame (quiet)
mesh intact, no tearing (debug/character_look_capture.gd)
Limits
- It cannot find a garment that shares a material with the body. Miku's skirt
is on her
bodyslot, so she got hair chains and no skirt. Splitting by geometry rather than by material would be the next step. - It does not set
weights_authored. An auto-rigged model still gets the destructive load-timeSkinLegRepair. That repair only touches cross-leg vertices, so it leaves hair alone, but it is worth knowing. - Grown chains are a fallback, not a substitute for a rigged source. They follow the geometry, but an artist's chains carry intent — where a panel should split, which strands move together — that no fit recovers.