fix(animation): Convert animation rest pose for VRM 0.0 retargeting#136
Merged
arkavo-com merged 1 commit intomainfrom May 10, 2026
Merged
fix(animation): Convert animation rest pose for VRM 0.0 retargeting#136arkavo-com merged 1 commit intomainfrom
arkavo-com merged 1 commit intomainfrom
Conversation
VRMA + VRM 0.0 rendered upside-down once animations played because the delta-retargeting subtracted a converted per-frame rotation from an unconverted rest rotation, mixing coordinate frames. Apply the same convertForVRM0 transform to animationRestRotation/animationRestTranslation before computing deltas so both sides live in the model frame. Visually verified with VRMVideoRenderer + Idle.vrma: - AliciaSolid (VRM 0.0): now right-side-up (was upside-down) - VRM1_Constraint_Twist_Sample (VRM 1.0): unchanged All 1188 tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Screenshots
Before / after on the same VRM 0.0 + VRMA case (AliciaSolid + Idle.vrma, frame 0):
Regression checks — VRM 1.0 unchanged, and the fix composes with the silhouette feature in #137:
--silhouetteSummary
Applies the existing
convertForVRM0coordinate transform toanimationRestRotationandanimationRestTranslationinVRMAnimationLoader.swiftso the delta-retargeting computationdelta = inverse(rest) * rotationno longer mixes coordinate frames.The bug
For VRM 0.0 models with a VRMA animation, the avatar rendered upside-down once playback started — but rendered correctly when no animation played, and VRM 1.0 + VRMA was unaffected. Triangulating the symptoms pointed to the retargeting layer:
In
makeRotationSampler, the per-frame rotation was being converted into the model's coordinate frame viaconvertRotationForVRM0, but the rest rotation it was being subtracted against (rotationRest) was not converted. The delta was therefore expressed in a hybrid frame. For pure Y-axis rotations the conversion is a no-op (Y stays positive), so the bug was invisible there; X- and Z-axis rotations (which is what an idle-hips track contains) accumulated a residual frame rotation that, combined with the renderer'svrmVersionRotationat draw time, manifested as a 180° X flip.The fix
Symmetry: convert the rest rotation/translation with the same
convertForVRM0transform before computing deltas. Translation gets the same treatment (convertTranslationForVRM0applied toanimationRestTranslation).19 lines added / 2 removed across one file.
convertForVRM0=false(VRM 1.0) is bit-identical.Verification
--silhouetteswift test --parallelBackground — and what NOT to pull forward
There is a stale local branch (now
archive/animation-coordinate-fix-jan2026, exfeature/animation-coordinate-fix, Jan 19) that addressed a related symptom with a different mental model: it negated quaternion X+Y at the parser level on every glTF animation, framed as "RH→LH conversion." That premise doesn't match this codebase — the renderer doesn't flip handedness, and applying that conversion universally would break VRM 1.0 + VRMA renders. The salvageable part of that branch is the bone-name heuristic improvements (Mixamo, Blender, namespace prefixes), filed as #135.Test plan
swift buildcleanswift test --parallel --num-workers 14 -j 16 --disable-sandbox— 1188 tests, exit 0Notes
Branch is named
spike/because it was developed as a focused experimental fix; it is now verified and ready to land. If you'd prefer a renamed branch for tidiness happy to push to afix/name and update this PR.🤖 Generated with Claude Code