Record the verified pose-capture recipe and the harness defect
Full build / Import + headless tests (push) Successful in 41s
Full build / Full desktop build + optional release (push) Skipped

This commit is contained in:
zwitschi committed 2026-11-03 11:44:55 +01:00
1 parent 1d4f718376
commit 88a0793bba
3 files changed
+32 -21

No files matched your search

+8 -6
View File
@@ -11,12 +11,14 @@ Session memory for durable decisions, state, and gotchas. Keep concise, remove o
direct `set_bone_pose_rotation` on HipL/KneeL/Spine/ShoulderL/ElbowL/Head changes rendered
pixels; a bone *position* offset moves the head; a standalone probe running the same
`_animate()` sequence renders the crouch. A staged in-game `film` frame also showed the arms
Standalone SceneTree probes (avatar under `root`, under a `Node3D` stage, and created
mid-`_process`) all render the seated crouch, so the rig and animation math are fine and the
harness capture path is the outlier. A headless test now locks the proxy→bone contract
(`test_pose_reaches_the_skeleton_bones`, suite 273). Next leads: reproduce the stage inside
`capture_npc_review.gd` (known-good captures) or capture via `SubViewport` +
`RenderingServer.force_draw()`.
Standalone SceneTree probes (avatar under `root`, under a `Node3D` stage, created
mid-`_process`) all render the seated crouch, and a `SubViewport` + `RenderingServer.force_draw()`
probe does too (window probes diff ~2,200-2,360; offscreen 602 at +2/+6/+12 frames, including a
re-created avatar). So the rig, the animation math and the offscreen path are sound; only
`capture_npc_pose.gd` still saves rest frames, which makes its phase/camera/force-draw ordering
the defect. A headless test locks the proxy→bone contract
(`test_pose_reaches_the_skeleton_bones`, suite 273). Rebuild the harness from the verified
recipe in `docs/3d-model-review.md` instead of iterating on the current phase machine.
- **3D review baseline (2026-11-03):** `docs/3d-model-review.md` records the first skill-guided
measurements: 46/46 assets clean, library 59,012 tris, characters 4,482–5,474 tris (68–69% of
the 8,000 caps), `npc_base` only 1,204/2,488, 24-NPC 6.94 ms, and authored texel density
+7 -6
View File
@@ -64,12 +64,13 @@ except the rebuilt assets themselves.
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".
- [ ] Finish the pose-capture diagnosis. Done so far: the pose reaches proxies and skeleton
bones (new headless test, 273/273), direct bone rotations deform the rendered mesh, and
three standalone probes render the seated crouch — only `capture_npc_pose.gd` saves the
rest pose. Remaining leads: reproduce the stage inside `capture_npc_review.gd` (known to
render) or capture via `SubViewport` + `RenderingServer.force_draw()`, then add a scene
test that a posed avatar renders differently from its rest frame.
- [ ] 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.
- [ ] 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.
+17 -9
View File
@@ -172,20 +172,28 @@ variants (full-body + shoulder views) and its output does not match the state it
| Check | Result |
| --- | --- |
| Pose reaches proxies | Seated pose logs `rig_y=-0.339`, `leg0=-1.357` |
| Pose reaches skeleton bones | `Skeleton3D.get_bone_pose_rotation(HipL/KneeL)` differs from rest; new headless test `test_pose_reaches_the_skeleton_bones` locks it (suite 273/273) |
| Pose reaches skeleton bones | `HipL`/`KneeL` bone rotations differ from rest; headless test `test_pose_reaches_the_skeleton_bones` locks it (suite 273/273) |
| Idle restores rest | Same test asserts the hip returns to its rest orientation |
| Skinning bound | One `Skeleton3D`, mesh bound to it (`same=true`); hiding `npc_base` removes the body |
| Bone rotations deform the mesh | Direct writes change rendered pixels: Spine 1,719 / HipL 1,052 / KneeL 810 / ElbowL 745 / Head 671 / ShoulderL 640 sampled pixels |
| Bone translation deforms the mesh | A +0.5 m Head offset moves the head in frame |
| Standalone probes render the pose | Three variants (avatar under `root`, under a `Node3D` stage, created mid-`_process`) all render the seated crouch (`posed` vs rest diff ≈ 2,200–2,360 samples) |
| The harness renders the pose | **No.** All 8 variants × 4 poses save the rest pose while the logged state and bone poses are posed |
| Standalone window probes render the pose | Three variants (avatar under `root`, under a `Node3D` stage, created mid-`_process`) render the seated crouch (diff ~2,200-2,360 samples) |
| 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 cause is therefore in the harness's capture path, not in the rig or the animation math. Two
leads are left and both are cheap: reproduce the stage inside a harness that is known to render
correctly (`capture_npc_review.gd` already produces 96 valid frames), or capture through a
`SubViewport` with `RenderingServer.force_draw()` so the frame cannot lag the state. Until a
scene test asserts that a posed avatar renders differently from its rest frame, do not treat pose
sheets as evidence and do not claim rig deformation in the review.
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.
Working recipe (verified by the probes; keep it when rebuilding):
1. Create a `SubViewport` (1280x720, `own_world_3d = true`, `UPDATE_ALWAYS`) in `_initialize`.
2. Build the studio (environment, key/fill light, ground, camera) and one avatar inside it.
3. Wait 2-3 frames so the skinned mesh binds.
4. Apply the pose with `_animate()` ticks, with the avatar's process/physics disabled.
5. Call `RenderingServer.force_draw()`, then `viewport.get_texture().get_image()`.
6. Free the avatar and repeat for the next pose; a re-created avatar also rendered correctly in a probe.
## Ranked candidate gaps