design: t965u orientation/animation corrections
@@ -432,3 +432,15 @@ Alpha is always kept (scaled to the bit depth). Distance = near + t·(far − ne
432
432
- Robustness acceptance is an automated, deterministic mutation suite (`tests/robustness.rs`): corrupt/truncated/mutated glTF/GLB, FBX, OBJ bodies, .ppe presets, .ppd manifests and .ppda files must yield an error or a valid result, never a panic or a non-finite body.
433
433
- glTF loading rejects non-finite positions/normals/weights, mismatched attribute lengths and out-of-range indices; panics inside the gltf parser are caught and reported as load errors (editor import overview included).
434
434
- Not covered (no automated gate possible here): accessibility, real OS file pickers and non-Linux platforms; these stay manual acceptance items.
435
436
## Decision 2026-11-07 (Tim t965u): orientation and animation corrections on source bodies
437
Findings on Tim's placeholders (maleb/femaleb.glb, Blender glTF export), verified independently in Python against the glTF spec. The renderer's joint maths matched the spec exactly, so the faults are in the source data:
438
1. The meshes face +Z (toes in front of the ankles, nose/chest at +Z; the glTF default), while the renderer assumes −Z, so y000 showed the back.
439
2. The foot chains (footControl → footArch/footIK/footToes) hang under the root (an IK rig) and carry only constant keys, so the feet stay planted while thigh and calf rotate. The legs stretch into strange shapes.
440
3. The baked thigh/calf/arm motion bends the knees backwards relative to the mesh's own front (32/32 and 40/40 measured poses) and swings the attack arm behind the body. The motion is front/back mirrored relative to the mesh.
441
442
Decision: automatic per-body detection at load (`orient::detect`), applied in one place (`preview::posed_worlds`) so live, still, production and equipment agree:
443
- Forward from the feet shape (lowest 4% vs 6–10% of height, ≥1000 vertices, ≥1% of height difference). +Z ⇒ turn the body 180° about Y. Static bodies get their geometry turned directly.
444
- A static (non-animated, at-rest) joint chain whose rest origin lies on the bone axis at the end of an animated leaf bone follows that bone rigidly.
445
- Knee-direction check over all clips at 24 samples/s: at least 4 wrong poses and more than 3× as many wrong as right ⇒ mirror the motion front/back. Per-joint world delta D = W·W0⁻¹ becomes S·D·S (S = diag(1,1,−1)), so the rest pose is unchanged.
446
- The notes are shown in the editor. There is no manual override yet; the synthetic test bodies are guarded to stay uncorrected.
@@ -432,3 +432,15 @@ Alpha is always kept (scaled to the bit depth). Distance = near + t·(far − ne432
- Robustness acceptance is an automated, deterministic mutation suite (`tests/robustness.rs`): corrupt/truncated/mutated glTF/GLB, FBX, OBJ bodies, .ppe presets, .ppd manifests and .ppda files must yield an error or a valid result, never a panic or a non-finite body.432
- Robustness acceptance is an automated, deterministic mutation suite (`tests/robustness.rs`): corrupt/truncated/mutated glTF/GLB, FBX, OBJ bodies, .ppe presets, .ppd manifests and .ppda files must yield an error or a valid result, never a panic or a non-finite body.433
- glTF loading rejects non-finite positions/normals/weights, mismatched attribute lengths and out-of-range indices; panics inside the gltf parser are caught and reported as load errors (editor import overview included).433
- glTF loading rejects non-finite positions/normals/weights, mismatched attribute lengths and out-of-range indices; panics inside the gltf parser are caught and reported as load errors (editor import overview included).434
- Not covered (no automated gate possible here): accessibility, real OS file pickers and non-Linux platforms; these stay manual acceptance items.434
- Not covered (no automated gate possible here): accessibility, real OS file pickers and non-Linux platforms; these stay manual acceptance items.435
436
## Decision 2026-11-07 (Tim t965u): orientation and animation corrections on source bodies437
Findings on Tim's placeholders (maleb/femaleb.glb, Blender glTF export), verified independently in Python against the glTF spec. The renderer's joint maths matched the spec exactly, so the faults are in the source data:438
1. The meshes face +Z (toes in front of the ankles, nose/chest at +Z; the glTF default), while the renderer assumes −Z, so y000 showed the back.439
2. The foot chains (footControl → footArch/footIK/footToes) hang under the root (an IK rig) and carry only constant keys, so the feet stay planted while thigh and calf rotate. The legs stretch into strange shapes.440
3. The baked thigh/calf/arm motion bends the knees backwards relative to the mesh's own front (32/32 and 40/40 measured poses) and swings the attack arm behind the body. The motion is front/back mirrored relative to the mesh.441
442
Decision: automatic per-body detection at load (`orient::detect`), applied in one place (`preview::posed_worlds`) so live, still, production and equipment agree:443
- Forward from the feet shape (lowest 4% vs 6–10% of height, ≥1000 vertices, ≥1% of height difference). +Z ⇒ turn the body 180° about Y. Static bodies get their geometry turned directly.444
- A static (non-animated, at-rest) joint chain whose rest origin lies on the bone axis at the end of an animated leaf bone follows that bone rigidly.445
- Knee-direction check over all clips at 24 samples/s: at least 4 wrong poses and more than 3× as many wrong as right ⇒ mirror the motion front/back. Per-joint world delta D = W·W0⁻¹ becomes S·D·S (S = diag(1,1,−1)), so the rest pose is unchanged.446
- The notes are shown in the editor. There is no manual override yet; the synthetic test bodies are guarded to stay uncorrected.