GLTFLoader Animations = :-(

I am attempting to import an animated GLTF model. However, the animation is not fluid (like the original) but rather a stiff rocking motion.

Original

2019-07-10%2011_53_58

Our result

2019-07-10%2011_56_11

CODE

var mixer;
var clock = new THREE.Clock();

// model
gltfLoader = new THREE.GLTFLoader()
    gltfLoader.load( "shark.gltf", function ( model ) {
    mixer= new THREE.AnimationMixer(model.scene);
    model.animations.forEach((clip) => {mixer.clipAction(clip).play(); });
 scene.add(model.scene)}

// renderer
var delta = clock.getDelta();
mixer.update( delta )

Are you sure you want to playback all available animations at once? This could be the root cause for the strange behavior.

Playing only one animation yields the same result:

var action = mixer.clipAction( model.animations[ 0 ] );
action.play();

I’m attaching the model (shark.zip)
Dragging that folder to https://gltf-viewer.donmccurdy.com/ shows the animation working properly.

shark.zip (2.5 MB)

Sry, I’m not able to reproduce the issue on my machine. Full code:

var container, stats, controls, mixer, clock;
var camera, scene, renderer;

init();
animate();

function init() {

	container = document.createElement( 'div' );
	document.body.appendChild( container );

	camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.25, 20 );
	camera.position.set( - 1.8, 0.9, 2.7 );

	scene = new THREE.Scene();

	clock = new THREE.Clock();

	var ambientLight = new THREE.AmbientLight( 0xcccccc, 0.4 );
	scene.add( ambientLight );

	var pointLight = new THREE.PointLight( 0xffffff, 0.8 );
	camera.add( pointLight );
	scene.add( camera );

	var loader = new GLTFLoader().setPath( 'models/gltf/shark/' );
	loader.load( 'shark.gltf', function ( gltf ) {

		mixer = new THREE.AnimationMixer( gltf.scene );
		var action = mixer.clipAction( gltf.animations[ 0 ] );
		action.play();

		scene.add( gltf.scene );

	} );

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

	controls = new OrbitControls( camera, renderer.domElement );
	controls.target.set( 0, - 0.2, - 0.2 );
	controls.update();

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

	// stats
	stats = new Stats();
	container.appendChild( stats.dom );

}

function onWindowResize() {

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

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

}

//

function animate() {

	requestAnimationFrame( animate );

	var delta = clock.getDelta();

	if ( mixer ) mixer.update( delta );

	renderer.render( scene, camera );

	stats.update();

}

Ah, I found the problem.

In a different area of the code, I was setting the name of each child object in the model… removing this line fixed it.

model.scene.traverse( function ( child ) {child.name=no})

Thanks @Mugen87