Recently, I have been experimenting a bit with applying Mixamo motion captures to GLTF files loaded via Three.js. I reached a point however, where for convenience sake I wanted to be able to load the animation tracks as separate files, rather than having all the animations combined with the model in one GLTF / GLB file. For me this meant that I could simply download and add new animations to the model as required.
At the time of writing this article there were some notes available for this online however I found them to be a bit hard to wrap my head around.
Above is a relatively simple interactive demo in which the animations are loaded as separate GLB files using Three.js.
You’re probably best to open the demo and check out the source code, and if you’re generally familiar with Three.js and loading files etc, hopefully this code will all be fairly straightforward to you. The main thing is that I have created an array which I called ‘actions’ and every time I load an animation I simply push it into this array.
Quick disclaimer, even though I do heaps of work with code, I do not regard myself as a top level coder. (- I’m more of a front end kind of guy). So please keep me posted if you find issues with this code and or if you can offer me any suggestions for how to improve it. 😉
I should also probably mention that in my demo I included the Idle animation with the model as it seemed to work best to have a ‘default’ animation included with the model. I’m also in the habit of including my mixers in an array of mixers just so things are in place for scenes which require multiple mixers.
Otherwise here is an extract of the code showing the main functions for loading the model and the animations.
// Load GLTF
const gltf_loader = new GLTFLoader();
gltf_loader.load(
'./_glb/robot-idle.glb', function ( gltf ) {
console.log( "Robot model with idle animation loaded" );
const model = gltf.scene;
mixer_1 = new THREE.AnimationMixer( model );
mixers.push( mixer_1 );
action_1 = mixer_1.clipAction( gltf.animations[0]);
actions.push(action_1);
action_1.play();
currentAction = mixer_1.clipAction(gltf.animations[0]);
scene.add(model);
load_animations();
}
);
function load_animations() {
gltf_loader.load(
'./_glb/look-around.glb', function ( gltf ) {
console.log( "Look Around animation loaded" );
action_2 = mixer_1.clipAction(gltf.animations[0]);
actions.push(action_2);
}
);
// ...
In this example my animation blending is fairly basic and maybe a bit clumsy, but for the most part it seems to work. – I’m looking forward to developing a more advanced system for this to allow specific animations to finish before they are interrupted by the new animation etc. – You would need this for something like a jump animation.
At some point I’m also aiming to update this demo so the UI is not visible and accessible until the model and all the animations are loaded. – I realise this is a bit of a bug but in this case the robot and animation files are relatively small, so I’m not super worried about this just now.
If by chance you’re interested in the Robot model that I have used here, I made this available as a free resource Blender file which you can find over in my resources section.
If you would like to stay in the loop when I publish new content your best bet is to join my mailing list, as I don't tend to post my tutorials and articles to social media. Otherwise you can always follow my work on Youtube, Twitter, Instagram, Reddit, Artstation, LinkedIn, and Behance.