Apply Mixamo Animation to Ready Player Me Avatar Without Passing Character Through Blender/Mixamo

Hi All,

I’ve see the tutorials on how to download an RPM character, convert it to FBX in Blender, upload it to Mixamo and then animation the character in Babylon.js. While this process works well, I’m looking for a method of utilizing Mixamo animations with RPM characters directly - i.e. without the need to pass through Blender/Mixamo.

Using the RPM Animation Library (GitHub - readyplayerme/animation-library: Ready Player Me Animation Library) and converting these animations to GLB, they can then be directly imported into a BJS scene and applied to an RPM character with the following code (thanks GitHub - crazyramirez/babylonjs-ReadyPlayerMe-Animation-Combiner: Babylon JS -- Combining multiple animations to a ReadyPlayerMe Character for the example):

BABYLON.SceneLoader.ImportMeshAsync(null, "./resources/models/" + model, null, scene)
      .then((result) => {

        player = result.meshes[0];
        player.name = "Character";

        var modelTransformNodes = player.getChildTransformNodes();
        
        animationsGLB.forEach((animation) => {
          const modelAnimationGroup = animation.clone(model.replace(".glb", "_") + animation.name, (oldTarget) => {
            return modelTransformNodes.find((node) => node.name === oldTarget.name);
          });
          animation.dispose();
        });
        animationsGLB = [];
 
    });

If converting a Mixamo FBX to GLB using the same process and utilizing the above approach BJS throws an error:

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'getRestPose')
    at e._getOriginalValues (babylon.js:1:214926)

Is there a way to map these Mixamo animations to the RPM skeleton in Babylon.js directly without import/export through Blender/Mixamo?

IIRC @PirateJC and @thomlucc have done some tests with Mixamo

@PatrickRyan might have information about it too

I’ve identified how to do this. The Mixamo and RPM skeletons appear to be equivalent, with the exception that the Mixamo bones are prefixed with “mixamorig:”, thus the following modified code allows the Mixamo animations to be mapped to RPM skeletons without import/export through Blender/Mixamo.com:

BABYLON.SceneLoader.ImportMeshAsync(null, "./resources/models/" + model, null, scene)
      .then((result) => {

        player = result.meshes[0];
        player.name = "Character";

        var modelTransformNodes = player.getChildTransformNodes();
        
        animationsGLB.forEach((animation) => {
          const modelAnimationGroup = animation.clone(model.replace(".glb", "_") + animation.name, (oldTarget) => 
            {   if(animation.name == "mixamo.com")
                {   return modelTransformNodes.find((node) => "mixamorig:" + node.name === oldTarget.name);
                }
                else
                {   return modelTransformNodes.find((node) => node.name === oldTarget.name);
                }
            });
          animation.dispose();
        });
        animationsGLB = [];
3 Likes

This is an awesome trick !!! :slight_smile: cc @thomlucc to see if we can improve this part in our doc

1 Like

Thanks @Jason_Daly ! I’ll give it try and update the docs.

3 Likes