Mixamo, Ready Player Me, VRoid, RootMotion: How Character Animations from Four Sources Coexist in One 3D World
Mixamo skeletonReady Player Me integrationVRoid exportRootMotion animationskeletal animation compatibilityanimation retargetingGLB bone fixThree.js character animationself-hosted 3D world characters
Characters in a 3D world come from everywhere: some animations are baked in Mixamo, some avatars are built with Ready Player Me, some models are exported from VRoid, and some animations carry RootMotion displacement. Each source works fine on its own — but put them in the same world and things break: T-posing, twisted limbs, characters drifting in place, wrong directions. The problems cluster around the skeleton, because every toolchain has its own bone naming, axis conventions, and animation conventions. This article describes a "translation layer" approach: no per-model manual fixing — normalization happens automatically in the loading pipeline, and every layer has a safety gate. When something is wrong, the layer refuses and raises an alarm rather than silently breaking the model.
One: Why the Problems Cluster Around the Skeleton
Whether a character can move depends on whether animation data can find its bones. The four sources differ exactly there:
- Different bone naming. The same arm bone goes by different names across toolchains; when an animation track can't find its target, it silently does nothing.
- Different axis conventions. Blender is Z-up; after export to GLB and conversion to Y-up, leftover container rotations often remain in the hierarchy — the model looks tilted, or the animation points the wrong way.
- Different animation baking conventions. Whether a compensation rotation is baked into the animation or stored in the skeleton's rest pose differs by toolchain; mixing them produces misalignment ranging from "slightly off" to "fully twisted."
- Export tools duplicate bone chains. Some export flows generate duplicate chains with an
_Nsuffix. When the animation binds to the duplicate and the skinning hangs on the main chain, the result is a model that tears itself apart in motion.
Two: The Four Layers of the Translation Layer
1. Axis and container-rotation normalization
animUpAxisFixer handles axis declarations; container-rotation sink normalization handles Blender Z-up export leftovers. Models land standing straight, and authors don't need to go back and re-export their source files.
2. Animation convention compensation
animConventionCompensator automatically compensates for convention differences: rotations that should have been sunk into the rest pose are normalized, so animations baked under different conventions hold consistent poses in the same world. One acceptance batch of 51-bone models (the Kipfel class) passed per-model compensation 10/10.
3. Duplicate bone chain rebinding
duplicateBoneChainFixer finds _N-suffixed duplicate chains, rebinds animation tracks back to the main chain, and synchronizes the inverse bind matrices (IBM). This step is gated by world-matrix checks — rebinding only executes when the main/duplicate world-matrix relationship is confirmed, so models with unclear hierarchies aren't made worse.
4. Word-boundary matching for bone identification
Bone identification uses word-boundary regex, avoiding substring false matches — objects whose names merely contain similar substrings are never mistaken for bones.
Three: Every Layer Has a Safety Gate
The risk of automatic normalization is fixing things into worse states. So every layer is allowed to say no:
- Rest pose still abnormal after compensation → refuse the compensation and raise an alarm; the model loads in its original state.
- IBM worse after rebinding → roll back immediately to the pre-rebind state.
The principle: prefer keeping the original and handing over a diagnostic report over silently "fixing" a model into breakage. A model that can't be fixed can still stand in the right place; a model broken by a fixer can do nothing.
Four: _diag — Let the Script Do the Judging
Every layer has a _diag diagnostic interface, usable both for self-checking after load and for plugging into automated acceptance. Which layers a model passed, which layer refused compensation, and why — it's all in the report. No need to open modeling software and inspect one by one; run the diagnostics once and you know which model broke at which layer.
Five: The Numbers
| Check | Result |
|---|---|
| Animation track hits (two batches) | 33/33, 312/318 |
| Kipfel-class 51-bone models, per-model compensation | 10/10 |
| Full skeleton-suite regression | 67/67 |
"Track hit" means: every track in the animation data found its corresponding bone on the target skeleton. The 6 misses in the 312/318 batch were non-standard tracks shipped inside individual models — following the safety-gate principle, they get reported, not forced.
Six: The Limits
- The translation layer treats convention differences, not content errors. A skeleton that's genuinely missing bones or animation data that's genuinely broken can only be reported, not repaired — source-file problems go back to the source.
- It assumes a correctly modeled source file: models with broken skinning or collapsed weights are outside the pipeline's scope.
- In federated cross-world scenarios, user characters migrate with skeleton mapping and animation retargeting — an extension of the same pipeline. The world changes; the character holds together.
FAQ
Q: Do player-uploaded characters go through this pipeline too?
A: Yes. Uploads enter the same loading pipeline; normalization and diagnostics run automatically, and uploaders need to know nothing about skeletons.
Q: Could it break a model the author already fixed?
A: Every layer has a safety gate: refuse on post-compensation anomalies, roll back on worse IBM, and a _diag report to inspect. "Fixing" here is refusable, revertible, and auditable — never a silent rewrite.
Q: What about toolchains beyond the four sources?
A: Models from other toolchains go through the same normalization pipeline; uncovered convention differences get reported by the diagnostics rather than shipped broken. Adaptation coverage expands as real sources are encountered.
Source & Repository
All three addresses host identical content; the first two are faster within mainland China. The repository includes deployment docs and the acceptance scripts.
- Gitee (faster in mainland China): https://gitee.com/miduoxinxijeji/miduo.git
- GitCode (mirror): https://gitcode.com/qq_35054471/virtual-world
- GitHub: https://github.com/miduo100/3d-virtual-world
About Genesis
Genesis is a self-hosted 3D virtual world system built on Three.js + WebGL, helping individuals and businesses build their own 3D spaces. Accessible directly from a browser, compatible with both PC and mobile, it supports multiplayer online, federated teleportation, a shop system, and Agent integration—where an AI can enter your world as an embodied character. Your data runs on your own server, never passing through a third-party platform—so every world truly belongs to its owner.
Want character models from any source to move the moment they enter your world? Genesis Virtual World CRM is a Three.js 3D virtual world foundation you deploy on your own server — the skeleton and animation compatibility "translation layer" is already built into the asset pipeline; you write the top layer. The official site (search "Genesis Virtual World CRM") has a demo world you can walk through.
About the name: Genesis in this article refers to Genesis Virtual World CRM — they are the same self-hosted 3D virtual world product. If "Genesis" doesn't turn us up in search, search "Genesis Virtual World CRM" instead.