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

Hi, I re-use your code to import my GLTF animation from Blender3D. I just combine translation and rotation on my model and I don’t understand why but my animation generate is diferent from the original.

Below a gif of my original animation :
coalcoalkernelL

My GLTF use sometimes scalable information instead of big rotation :
charbon.glb (119.8 KB)

I document me on three.js since yesterday. I’m not sure if it’s the best place to expose my issue and if it’s not the case could you tell me the best place to do it ?

I’ve tested your model with Sketchfab, Babylon.js Sandbox and the three.js based gltf-viewer. They all visualize the asset in the same way. The smaller cubes which appear and disappear are not visible. Maybe you are doing something wrong when exporting the model from Blender? If not, consider to report an issue at the repository of the Blender glTF importer/exporter: https://github.com/KhronosGroup/glTF-Blender-IO

Oh, sorry it’s my fault, the smaller cubes are generated particles from an other model inside the principal cube. I don’t include this because particles is’nt supported by glTF-Blender-IO.

coal

The issue is about the principal cube, I’ve tested with Babylon.js Sandbox and glTF viewer too.

  • In the first case I don’t have the shape deformations like in my browser but the rotations animation is incomplete.
  • In the second case that transformed my translations and rotations animation in shape modifications part like in my browser view.

Enregistrement%20%231_1

In any case, thank you for these tools and I will take the time to report my issue on github.

how we can play one by one Mr ? @Mugen87
did ypu know how gltf viewer play animation when i click play all


?
cuz it work on viewer but when i play animation in foreach on my code not work, thanks

This is an old thread – i’d suggest starting a new thread and including your code or a demo so others can help you debug it.

It’s an old thread, but just in case someone needs to know, to start animation one after another you must execute next animation once the current animation finishes

mixer = new THREE.AnimationMixer( model );
const clips = model.animations;
var t = 0;
$.each(clips, function(i, clip) {
    setTimeout(function() {
        mixer.clipAction( clip ).play();
    }, t);
    t = t + (clip.duration * 1000);
});