docs(skill): record why Miku has no cloth — the source had no skeleton
The two shipped characters are a controlled comparison: Taila's source arrived rigged (35 cloth chains, 8 twist bones, 18 meshes, artist weights), Miku's did not (5 meshes, 0 joints), so Miku was auto-rigged into one mesh with nearest-bone weights and no cloth chains at all. Her twin tails and skirt are dead geometry and the destructive load-time weight repair runs on her every spawn. None of that is recoverable downstream, which makes picking a source that already has skirt and hair bones the highest-leverage decision in the pipeline. Added the no-Blender check for vetting a candidate. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5
parent
daf9627ece
commit
4559a1adc3
@@ -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('<II',f.read(8))
|
||||
j=json.loads(f.read(clen))
|
||||
nodes=[n.get('name','') for n in j['nodes']]
|
||||
joints=[nodes[i] for s in j.get('skins',[]) for i in s['joints']]
|
||||
print(len(j['meshes']), 'meshes', len(joints), 'joints')
|
||||
print([n for n in joints if any(t in n.lower() for t in ('hair','skirt','tail','ribbon'))])
|
||||
```
|
||||
|
||||
Several meshes, 50+ joints, and a non-empty cosmetic list means a good source.
|
||||
|
||||
## Checking a source model before importing
|
||||
|
||||
```bash
|
||||
|
||||
Reference in New Issue
Block a user