fix: use shortest-path rotation interpolation in playback

Switch viewer playback from Magnum Math::slerp() to Math::slerpShortestPath() when interpolating adjacent OpenSim frame orientations.

Why:

- Adjacent OpenSim quaternions can cross sign while representing nearly identical orientations.

- Non-shortest-path interpolation can create artificial long-arc spins between valid sampled poses.

- That makes playback exaggerate or invent visible bone flips that are not present in the sampled frame states.

What changed:

- Updated playback interpolation in src/ViewerApp.cpp to use shortest-path quaternion slerp.

- Added docs/motion-troubleshooting.md documenting the distinction between viewer interpolation artifacts and upstream IK discontinuities.

- Added a README pointer to the troubleshooting note.

Investigation log:

- Verified the viewer loads .mot through OpenSim state storage and renders PhysicalFrame transforms directly.

- Reproduced the target Sports2D/Pose2Sim/OpenSim clip and confirmed the .mot already contains large coordinate discontinuities and limit clamping, indicating upstream IK failure.

- Confirmed the viewer also had a separate interpolation issue due to non-shortest-path quaternion slerp.

Validation:

- Rebuilt with: cmake --build build -j

- Relaunched the viewer successfully against the problematic .osim/.mot pair after the fix.
This commit is contained in:
2026-03-11 11:54:41 +08:00
parent 3e7ef53799
commit ab728c7e9a
3 changed files with 53 additions and 1 deletions
+45
View File
@@ -0,0 +1,45 @@
# Motion Troubleshooting
## Bone Flips During Playback
The viewer loads the `.mot` file through OpenSim, converts it to model states,
and renders each body using `PhysicalFrame::getTransformInGround()`. It does
not solve IK, rebuild bones from markers, or apply any custom joint logic.
Because of that, a visible flip can come from two different places:
1. The upstream motion data already contains a discontinuity.
2. Playback interpolation between two valid sampled poses introduces an
artificial long-arc rotation.
## Viewer Behavior
Playback now uses shortest-path quaternion interpolation between sampled OpenSim
poses. This avoids false in-between spins when adjacent quaternions have
opposite signs but represent nearly the same orientation.
If a flip is still visible after this fix, the sampled OpenSim motion itself is
already discontinuous.
## Upstream IK Failures
For Sports2D / Pose2Sim / OpenSim pipelines, broken IK usually shows up as one
or more of the following:
- sudden large frame-to-frame jumps in joint coordinates
- joint values snapping to model limits
- marker RMS staying low while anatomically implausible body orientations appear
- left/right ambiguity or bad depth reconstruction in the source TRC
Sports2D ultimately delegates IK generation to Pose2Sim, which then calls
`opensim.InverseKinematicsTool(...)`. If the generated `_ik.mot` already
contains large discontinuities, the viewer is only displaying that failure.
## Practical Check
To separate viewer issues from upstream IK issues:
1. Load the `.osim` and `.mot` in the viewer.
2. Scrub near the suspicious frame while paused.
3. If the sampled pose itself is wrong, the IK output is broken upstream.
4. If only the in-between motion looks wrong, interpolation is the likely cause.