After exporting an animated model (spaceship) and an animated camera as a .glb file from Blender using the gltfExporter, I successfully viewed them in the glTF viewer (gltf-viewer.donmccurdy.com), confirming that the issue does not lie with the model or Blender.
The problem arises when attempting to play both animations concurrently in my script. If I animate either the model or the camera individually, it works perfectly fine. However, when trying to animate both simultaneously, things go haywire. I suspect this might be due to my limited understanding of Animation Mixers. Could it be that I should only use one Mixer for the entire file? Here is a summary of what I am doing:
I have created two separate animation mixers, one for the spaceship and one for the camera:
gltfStore.mixer = new THREE.AnimationMixer(gltf.cameras[0]);
gltfStore.mixerShip = new THREE.AnimationMixer(gltf.scene.children[2]);
The animations are played using clipAction:
gltfStore.mixer.clipAction(gltfStore.animations[0]).play();
gltfStore.mixerShip.clipAction(gltfStore.animations[0]).play();
In my loop, I update and render the animations:
gltfStore.mixer.update(clock.getDelta());
gltfStore.mixerShip.update(clock.getDelta());
Individually, these animations function correctly, but together they do not synchronize properly. It seems that the imported animation data in the glTF animation object includes both the camera and model animations under gltf.animations[0]. For clarity, gltf.animations[0]
contains a tracks
array with 6
items corresponding to position, quaternion, and scale for each item. Is this correct?
For reference, here is the main javascript file:
var scene = new THREE.Scene();
var mixer, animationClip;
var clock = new THREE.Clock();
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
//LIGHTS
var light = new THREE.PointLight( 0xffffff, 1, 200 );
light.position.set( 10, -10, 0 );
scene.add( light )
//OBJECT TO STORE THE GLTF ASSETS WHEN LOADED
var gltfStore = {};
var loader = new THREE.GLTFLoader();
// LOAD GLTF ASSETS
var gltfCamera = loader.load(
'spaceship.glb',
function ( gltf ) {
scene.add( gltf.scene );
gltfStore.animations = gltf.animations;
gltfStore.ship = gltf.scene.children[2];
gltfStore.cam = gltf.cameras[0];
gltfStore.mixer = new THREE.AnimationMixer(gltf.cameras[0]);
gltfStore.mixerShip = new THREE.AnimationMixer(gltf.scene.children[2]);
gltfStore.mixer.clipAction(gltfStore.animations[0]).play();
gltfStore.mixerShip.clipAction(gltfStore.animations[0]).play();
}
);
function animate() {
requestAnimationFrame( animate );
if(gltfStore.mixer && gltfStore.cam){
//gltfStore.mixer.update(clock.getDelta());
gltfStore.mixerShip.update(clock.getDelta());
renderer.render(scene, gltfStore.cam);
}
};
animate();
Your insights or assistance would be greatly appreciated. Thank you!