diff --git a/.claude/skills/character-pipeline/references/separation.md b/.claude/skills/character-pipeline/references/separation.md index 46bbddb..77b85d7 100644 --- a/.claude/skills/character-pipeline/references/separation.md +++ b/.claude/skills/character-pipeline/references/separation.md @@ -97,6 +97,42 @@ guesses. tracks onto them (`keep_anim_armature`), the AnimationPlayer overwrites the spring solver every frame. +## Worked example: why the two shipped characters differ so much + +Both are in `assets/characters/skins/`. Compare their sidecars: + +| | Taila | Miku | +|---|---|---| +| source had a skeleton | yes | **no — 5 meshes, 0 joints** | +| `weights_authored` | true | **false** | +| cloth chains | 35 (127 bones) | **0** | +| twist bones | 8 | **0** | +| meshes shipped | 18 | **1** | + +Miku's source (`assets/characters/incoming/miku_test.glb`) is an unrigged mesh, +so she went through `autorig.py`: joined to one mesh, rebound by nearest-bone +weighting, no cloth chains. Her twin tails and skirt are dead geometry that +cannot move, and `SkinLegRepair` runs destructively on her every spawn. + +Nothing downstream can recover this. **The single highest-leverage decision in +this whole pipeline is choosing a source model that already has a skeleton with +skirt and hair bones.** Everything else is recoverable; this is not. + +A quick check on any candidate, without Blender: + +```python +import json, struct +with open(path,'rb') as f: + f.read(12); clen,_=struct.unpack('