From f121167e52cd68466a052b9c8eaea45d38c1286f Mon Sep 17 00:00:00 2001 From: Zwitschi Date: Fri, 6 Nov 2026 09:52:13 +0100 Subject: [PATCH] =?UTF-8?q?Record=20the=20arm-down=20bake=20fix=20and=20th?= =?UTF-8?q?e=20remaining=20non-180=C2=B0=20rest=20pose-composition=20task?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TODO.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/TODO.md b/TODO.md index 5388a3d..9897330 100644 --- a/TODO.md +++ b/TODO.md @@ -768,16 +768,18 @@ blocked rig can no longer block the whole release. ### Rig and export correction -- [ ] Reproduce and record the failure: export the arm-down GLB, dump its `inverseBindMatrices`, - compare them with the Blender armature rest, and capture the Godot A-pose frame. -- [ ] Fix the arm-down bake so the exported skin matches the rest. Stop using - `armature_apply` + `export_apply=True`; either bake the pose into the armature rest and - export without apply, or re-add the modifier and verify the inverse bind matrices against - the rest. Do not ship a hybrid or hand-patched GLB. +- [x] Reproduce and record the failure: the `armature_apply` + `export_apply=True` bake wrote + wrong inverse bind matrices (Godot rendered A-pose while the rest was arm-down). Recorded + in `MEMORY.md`; `bake_armdown_clean.py` was the failing recipe. +- [x] Fix the arm-down bake so the exported skin matches the rest. `tmp/npc-research/bake_armdown_v2.py` + (pose-rotate → apply modifier → reset pose → edit-mode rotate arms → re-add modifier → + export `export_apply=False`) now yields a correct arm-down base: Blender deformed x ±0.221 + and the rest bone tail points down. Still local (`tmp/`), not shipped. - [ ] Re-derive the pose composition for a non-180° rest. Godot's `set_bone_pose_rotation` is - rest-relative, so `rest * Quaternion(axis, angle)` only reproduces the old rig by accident; - derive the correct composition (candidate: `rest.inverse() * target`) and prove it with - measured global bone transforms, not by reading the code. + rest-relative, so `rest * Quaternion(axis, angle)` only reproduces the old rig by accident + (the old rest is 180°, so `rest² = identity`); the Quaternius ~76° rest breaks it. Derive the + correct composition (candidate: `rest.inverse() * target`) and prove it with measured global + bone transforms or a mesh-deformation render, not by reading the code. - [ ] Add regression tests: a bone with a ~76° rest reaches a known global orientation; the Quaternius joint map resolves; the 13-core fallback poses exactly as it does today. - [ ] Verify Idle and Walk on the 62-joint rig: loop seam, foot contact, root motion and frame