GLB model animation not working

I’m trying to load a model with animations and camera animations inside a skydome. I’m a noob in three.js, so I’m facing a few issues with my code. My model loads perfectly in GLTF viewer and I want to implement it in my code just as in the viewer. My model is loading but the animation is not playing as in viewer. And I also don’t know how to load camera animations.

Here’s the model ship.glb (2.2 MB)
Here are the files files.zip (416.8 KB)

let camera, scene, renderer, mixer;
init();
animate();
var clock = new THREE.Clock();

function init() {

camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 20000);
camera.position.z = 27;
camera.position.x = 0;
camera.position.y = 10;

scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);
const loader = new THREE.TextureLoader();
//loader.load('stars.jpg' , function(texture)
//			{
//			 scene.background = texture;  
//			});

const loadingManager = new THREE.LoadingManager(() => {

	const loadingScreen = document.getElementById('loading-screen');
	loadingScreen.classList.add('fade-out');

	// optional: remove loader from DOM via event listener
	loadingScreen.addEventListener('transitionend', onTransitionEnd);

});

// gltf

const gltfLoader = new THREE.GLTFLoader(loadingManager);
gltfLoader.load('ship.glb', (gltf) => {
	const model = gltf.scene;
	mixer = new THREE.AnimationMixer(model);
	mixer.clipAction(gltf.animations[0]).play();
	scene.add(model);
});



// Galaxy
let galaxyGeometry = new THREE.SphereGeometry(1000, 32, 32);
let galaxyMaterial = new THREE.MeshBasicMaterial({
	side: THREE.BackSide
});
let galaxy = new THREE.Mesh(galaxyGeometry, galaxyMaterial);

// Load Galaxy Textures
loader.crossOrigin = true;
loader.load(
	'stars.jpg',
	function (texture) {
		galaxyMaterial.map = texture;
		scene.add(galaxy);
	}
);

let hemiLight = new THREE.HemisphereLight(0xffffff, 0xffffff, 0.61);
hemiLight.position.set(0, 50, 0);
// Add hemisphere light to scene
scene.add(hemiLight);


let dirLight = new THREE.DirectionalLight(0xffffff, 0.54);
// Add directional Light to scene
scene.add(dirLight);

//

renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

//

const controls = new THREE.OrbitControls(camera, renderer.domElement);

controls.update();

//

window.addEventListener('resize', onWindowResize, false);

}

function onWindowResize() {

camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();

renderer.setSize(window.innerWidth, window.innerHeight);

}

function animate() {

requestAnimationFrame(animate);


render();

}

 function render() {


renderer.render(scene, camera);

 }

 function onTransitionEnd(event) {

event.target.remove();

}

You have a runtime error in your code. Move var clock = new THREE.Clock(); before you call init() and animate().

Okay! I fixed it but the animation is still not playing and I still haven’t figured out how to use gltf camera instead of perspective camera.

Strange. I just fixed this bit locally and the animation worked. It seems that your code section and the code in the zip file are different.

In any event, you have to update the mixer in your animation loop like so.

if ( mixer ) mixer.update( clock.getDelta() );

That bit also explains why you need an instance of THREE.Clock in your scene.

1 Like

You are amazing! It worked.Thank you so much!

1 Like