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

+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