diff --git a/MEMORY.md b/MEMORY.md index 6ab58f0..20abfe2 100644 --- a/MEMORY.md +++ b/MEMORY.md @@ -705,6 +705,14 @@ Session memory for durable decisions, state, and gotchas. Keep concise, remove o (`smoke_props.gd`); the NPC FSM re-writes `rotation.y` every physics tick, so pose/portrait captures set the yaw after `set_physics_process(false)`; and `visible = false` does not keep the crowd out of a portrait frame (park the rest of the crowd away instead). +- Pose capture blocked — root cause narrowed (2026-11-03 re-attempt): rebuilding the harness with + the recipe (SubViewport + `RenderingServer.force_draw()` + `force_update_all_bone_transforms()` + + disabled avatar process/physics) still produced byte-identical rest frames. Decisive probe: + teleporting the **avatar** (CharacterBody3D) changes the render (diff 10), but moving the + **`Rig` child** (the GLB model's parent) does not (diff 0) — the skinned mesh does not follow the + `Rig` Node3D transform, so the rig lowering (`rig_y=-0.339`) never reaches the rendered model. + The failure is upstream of capture ordering. Do not re-attempt the recipe; next attempt must + answer why the skinned model ignores its `Rig` parent, or stage poses via `capture_npc_review.gd`. - Blender tooling: `bisect_plane` and thin bevels leave zero-area triangles (Godot warns "non-finite normal in LOD generation"); `_clean()` + a weld after bisect fix them and the audit rejects them. diff --git a/TODO.md b/TODO.md index f16238d..f1c3f65 100644 --- a/TODO.md +++ b/TODO.md @@ -110,13 +110,13 @@ licence-free zone only. frames still show the rest pose; direct bone writes deform the mesh, so this is a staging/ capture discrepancy that may also affect live venue frames. See `docs/3d-model-review.md` §"Pose evidence is blocked". -- [ ] Rebuild the pose harness from the verified recipe. Established: the pose reaches proxies - and bones (headless test, 273/273), direct bone rotations deform the mesh, and both window - probes and a `SubViewport` + `RenderingServer.force_draw()` probe render the crouch (offscreen - diff 602 at +2/+6/+12 frames, including a re-created avatar). The current harness still - saves rest frames, so its phase/camera/force-draw ordering is the remaining defect. Rebuild - one pose at a time using the recipe in `docs/3d-model-review.md`, verify each pose visually, - then wire the sheets and fill the weights/pose column. +- [ ] Rebuild the pose harness. **Re-attempt 2026-11-03 narrowed the root cause:** the recipe + (SubViewport + `force_draw()` + `force_update_all_bone_transforms()` + disabled process/physics) + still produced byte-identical rest frames. Decisive probe: teleporting the avatar renders + (diff 10) but moving the `Rig` child does not (diff 0) — the skinned mesh ignores its `Rig` + parent transform, so `rig_y=-0.339` never reaches the render. Next attempt must answer why + the skinned model ignores the `Rig` node, or stage poses via the known-good + `capture_npc_review.gd` fallback. - [ ] UV/texel density: measure the 256² slot maps; decide whether atlas, UDIM or a resolution change is justified. Do not change `CHAR_MAX_TRIS`/`CHAR_MAX_VERTS` without re-running the budget smoke and the Web/Compatibility path. diff --git a/docs/3d-model-review.md b/docs/3d-model-review.md index 26adb2a..275d713 100644 --- a/docs/3d-model-review.md +++ b/docs/3d-model-review.md @@ -181,10 +181,14 @@ variants (full-body + shoulder views) and its output does not match the state it | Offscreen capture renders the pose | A `SubViewport` + `RenderingServer.force_draw()` probe renders the crouch reliably (diff 602 at +2/+6/+12 frames), including a re-created second avatar | | The harness renders the pose | **No** in its current form: same stage, same pose, rest frames. One ordering (`_frame_view()` immediately before `force_draw()`) produced posed walk frames once, then regressed to rest/garbage on the next run | -The rig, the animation math and the offscreen render path are all sound. The remaining failure is -specific to the harness's frame/phase ordering around staging, camera framing and `force_draw()`. -Do not keep guessing: rebuild the harness from the working recipe below, one pose at a time, and -verify each pose before wiring up the sheets. +The rig, the animation math and the offscreen render path are all sound. A 2026-11-03 re-attempt +with the recipe (SubViewport + `force_draw()` + `force_update_all_bone_transforms()` + disabled +process/physics) still produced byte-identical rest frames, and a decisive probe narrowed the +failure further: teleporting the **avatar** changes the render (diff 10), but moving the **`Rig` +child** (the GLB model's parent) does not (diff 0). The skinned mesh therefore does not follow its +`Rig` Node3D transform, so the rig lowering never reaches the rendered model — the defect is +upstream of camera/`force_draw()` ordering. Next attempt must answer why the skinned model ignores +the `Rig` node, or stage poses via the known-good `capture_npc_review.gd` fallback. Working recipe (verified by the probes; keep it when rebuilding):