feat(body): pose the arms down, add a front-angle shot
The character now stands with its arms at its sides instead of in a bind A-pose,
and there is a second camera to prove it: the third-person shot only ever showed
the pawn's back, so a front-facing pose defect was invisible in review.
demo-third-person-front camera on the road, ~6 m in front, looking back north
at the pawn; embedded in Screenshots/README.md as shot 7.
The pose work itself is a chain of measured findings, all recorded in TODO.md:
- clip data is exported relative to the REST pose, so arms-down offsets held only in
the keys arrived as a ±20 degree swing around an A bind;
- a rest-pose bake alone does not move the mesh: the MPFB mesh has shape keys, the
armature modifier cannot be applied while they exist, and the vertices stayed in
the A shape (X span unchanged at 1.051 m). Clearing the shape keys, baking the
deformation into the vertices and re-binding is what made bind and clips agree.
Not settled, and left as an open item rather than a claim: the base pose uses
inverted signs to compensate for the FBX axis mapping, the upper arms clip into the
torso, and the fingers splay. An aim-based pose module was written and then removed
- applied without the vertex bake it produced arms raised in a V, and a half-working
shared module is worse than none. The proper solve is 0.2.2: apply the standing pose
at character creation, then author clips against that bind.
This commit is contained in:
1 parent
a1f5989cbb
commit
8993fd83c4
39 files changed
+81
-47
No files matched your search
@@ -17,7 +17,8 @@ Actionable task list for this project. This file is the single, central place fo
|
||||
- [x] Import character into Unreal; validate skeleton, scale, and materials. Done: `/Game/Test/Character` — `SkeletalMesh` (138 bones), `Skeleton`, warm `M_Character_Export` material with baked `T_Character_Diffuse`.
|
||||
- [x] Promote the character asset into a reusable NPC prefab (visible body, collision capsule, idle pose) ready for pedestrians (`0.5.0`) once the third-person body lands. Done 2026-11-07: `AGigLineNPCPerson` (see the 0.1.0 Character-development item); `0.5.0` reuses it as the pedestrian base.
|
||||
- [x] Create basic idle/walk animation set. Done 2026-11-09: `Tools/character_anim_build.py` authors `GigLine_Idle` (60 f) and `GigLine_Walk` (30 f) at 30 fps from parametric cycles, and `Tools/ue_character_anim_import.py` imports them. Both AnimSequences verified in `/Game/Test/Character`: Idle 1.967 s, Walk 0.967 s. Limb axes were **measured** on the rig, not assumed — the probe rotated `upperleg01.L` 0.5 rad per axis and read `foot.L`, which showed X is the fore/aft swing (Y twists, Z abducts).
|
||||
- [~] Verify animation plays correctly on the imported rig. **Fixed 2026-11-09**: the clip now drives the body — shot 6 shows the arms hanging at the sides instead of an A-pose. Two causes, both proven by measurement rather than guessed: (1) `PlayAnimation` needs the component in `AnimationSingleNode` with a live single-node instance, and the body is hidden at construction, so the first call could land before the component was ready and never retry; the code now sets the mode, calls `SetAnimation` + `Play`, and re-asserts while the instance is missing. (2) the arms-down offsets were carried only in the clip keys, which the exporter writes relative to the rest pose — so they arrived as a ±20° swing around an A-posed bind; they are now baked into the rest pose before the clips are authored (`apply_base_pose`). **Still open:** the idle pose reads awkwardly (arms hang forward, hands splay) because the base is applied with inverted signs to compensate for the FBX axis flip, and the walk clip has never been captured in motion. Earlier evidence: the pawn's mesh is bound, both clips resolve, and the run logs `GigLine: playing body clip Character_AnimHuman_rig_GigLine_Idle`, but shot 5 still renders the body in bind pose (arms out). So `PlayAnimation` is called and the pose is not applied — next step is to check whether the imported clip carries bone curves at all (the FBX bake may be sampling only keyed bones) or whether the component needs `SetAnimationMode(AnimationSingleNode)` before `SetAnimation`/`Play`.
|
||||
- [~] Verify animation plays correctly on the imported rig. **Playback works since 2026-11-09**: the clip drives the body and the arms hang at the sides (shots 6 and 7). Three defects were found and fixed, each by measuring rather than guessing: (1) `PlayAnimation` on a hidden component never took effect, so the code now sets `AnimationSingleNode`, calls `SetAnimation` + `Play`, and re-asserts while the single-node instance is missing; (2) the arms-down offsets lived only in the clip keys and the exporter writes clip data relative to the rest pose, so they arrived as a ±20° swing around an A-posed bind — they are baked into the rest pose before the clips are authored; (3) a rest-pose bake alone does **not** move the mesh, because the MPFB mesh carries shape keys, the armature modifier cannot be applied while they exist, and the vertices stayed in the A shape (measured: X span unchanged at 1.051 m) — baking the deformation into the vertices, clearing the shape keys and re-binding is what made the bind match the clips. **Still open — the pose is not settled:** the base pose is applied with inverted signs to compensate for the FBX axis mapping, the upper arms clip into the torso, and the fingers splay. An aim-based pose module (`Tools/character_pose.py`) was attempted and removed: applied without the vertex bake it produced arms raised in a V, and a half-working shared module is worse than none. The proper solve belongs to `0.2.2`: build the character with the standing pose applied at creation (the `mpfb_character_export.py --pose idle` path), then author clips against that bind.
|
||||
- [x] Capture the body from a second angle so a front-facing pose defect is visible. `demo-third-person-front` added to the shot list and to `Screenshots/README.md`; the third-person shot alone only showed the pawn's back.
|
||||
|
||||
### Camera and controls
|
||||
|
||||
|
||||
Reference in new issue
Block a user