From 68f49253fe9913d89cbd1afe7bfe3327b342271f Mon Sep 17 00:00:00 2001 From: Zwitschi Date: Fri, 6 Nov 2026 13:19:42 +0100 Subject: [PATCH] Record the Quaternius pilot fixes and remaining 0.9.9 work in MEMORY.md --- MEMORY.md | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/MEMORY.md b/MEMORY.md index 11f616b..e4da29c 100644 --- a/MEMORY.md +++ b/MEMORY.md @@ -119,10 +119,10 @@ canonical implemented-features list in `docs/development-status.md`. library with a sculpted realistic face, so the 0.9.9 gate is a product decision, not just an art check. Owner picks full swap / crowd-only / extra head detail. Do not lower character fidelity silently. -- **Pose composition is rest-relative (2026-11-05, hypothesis to verify at 0.9.9):** Godot's - `set_bone_pose_rotation` offsets from the bone rest, so `rest * Quaternion(axis, angle)` only - equals the target when the rest is ±identity (the old 180° rig). The candidate fix is - `rest.inverse() * target`, proven with measured global bone transforms. +- **Pose composition is rest-relative (resolved 2026-11-05):** Godot's `set_bone_pose_rotation` + offsets from the bone rest, so the correct swing around a world axis is + `rest * Quaternion(rest.inverse() * axis, angle)`. For the old 180° rest this reduces to the + legacy `rest * Quaternion(axis, angle)`, so the 13-core fallback is unchanged (commit `8b1bf73`). - **One character source, one fallback:** no new NPC source without an ADR. MPFB body work stays closed, the Stage-1 proportion warp is not reopened, and the procedural `npc_base` + MakeHuman head stay tested until the Quaternius base passes its gate. @@ -147,13 +147,19 @@ canonical implemented-features list in `docs/development-status.md`. out of a portrait frame (park the rest of the crowd away instead). - Blender: `bisect_plane` and thin bevels leave zero-area triangles (Godot "non-finite normal in LOD generation"); `_clean()` + a weld after bisect fixes them and the audit rejects them. -- Quaternius arm-down bake: pose-rotate `UpperArm.L/R` −90° local X → apply Armature modifier → - `armature_apply` → re-add modifier bakes the rest, but `export_apply=True` writes wrong inverse - bind matrices (Godot renders A-pose even though the rest is arm-down). The runtime `_pose_bone` - `rest * Quaternion(axis, angle)` only cancels when `rest² = identity` (old rig's 180° rest); the - Quaternius ~76° rest does not, so the pose formula must be re-derived for a non-180° rest. - Godot's bone pose rotation is relative to the bone rest, not absolute: treat - `rest.inverse() * target` as the candidate and verify with measured global bone transforms. +- Quaternius arm-down bake (working recipe, `tmp/npc-research/bake_armdown_v5.py`): pose-rotate + `UpperArm.L/R` −90° local X → read the pose matrices → apply the Armature modifier → **reset the + pose to identity** → set each arm bone's rest matrix from its pose matrix → re-add the modifier → + export `export_apply=False`. Missing the pose reset double-applies the arm-down (mesh ±0.53 + instead of ±0.23). `armature_apply` in Blender 5.2 is broken (deforms the mesh but does not bake + the rest). The canonical base must be **join-only** (`build_base_minimal.py`: no `remove_doubles` + weld, no scale/ground transform, keep the Armature modifiers) — the weld and the scale/ground + transform corrupt the skin weights (arm poses to ±0.51 instead of −0.23). +- Quaternius `NpcAvatar` wiring (commit `2a6f29f`): the Quaternius labels `L`/`R` opposite the + project, so the dot-suffixed bone names are looked up with a **swapped suffix** (proxy `L` → + `UpperLeg.R`/`UpperArm.R`, proxy `R` → `.L`). The arm/elbow swing axis is `Vector3.LEFT` (legs + stay `RIGHT`). The hand proxy position is `global_wrist − global_elbow` (subtracting the relative + `elbow.position` misplaces handheld gear). Old 13-core names fall back unchanged. - Image models have per-model size floors/caps (Seedream needs 1920+; `GEN_SIZE=2048`, do not lower; gpt-5-image-mini caps lower). `generate_image` applies model-specific sizing; concept generation defaults to `--request-size 1536`. @@ -242,12 +248,15 @@ realism asset pipeline (see `DONE.md` and `CHANGELOG.md`). The 12-character proc **Planning pivot (2026-11-05, owner):** the character and map work was re-sequenced into patches (`0.9.9`–`0.9.12`) with `0.10.0` as the public-readiness minor. The gap analysis and the three release roadmaps now live in `PLAN.md`; `TODO.md` is the executable task list. ADR-0017 -Stage 1 (proportion warp) is dead; ADR-0018 option 2 (62-joint runtime) is accepted. The -`quaternius_base.glb`, joint map, slot map and `NpcAvatar` name mapping exist, but the arm-down -skin export and the pose composition are still wrong — no Quaternius character has rendered -correctly in Godot yet, and no character GLB has been rebuilt since the pivot. +Stage 1 (proportion warp) is dead; ADR-0018 option 2 (62-joint runtime) is accepted. -Test counts as of 2026-11-05: Python 167/167 (last run), Godot 277/277 (last run before the -docs-only pivot), `check_docs` OK. +**Quaternius pilot (2026-11-05):** the arm-down skin export and pose composition are now fixed +(`bake_armdown_v5.py`, `2a6f29f`). The join-only `quaternius_base.glb` renders arm-down in Godot; +idle/sit/walk were vision-verified (coherent humanoid, seated arms on thighs, contralateral walk). +Remaining before 0.9.9: handheld-gear fitting (the 0.43 m camera reads shoulder-mounted on the +0.42 m arm), five-slot mapping + AO bake, the owner face/silhouette gate, then the rollout. +No character GLB has been rebuilt since the pivot. + +Test counts as of 2026-11-05: Python 167/167, Godot 277/277, `check_docs` OK.