3

I'm trying to get a really basic Collada model to animate in three.js but I'm having some issues. The two examples (the monster and pump) both work on my machine, but whenever I substitute my model then it will load but it won't animate.

I stripped out a lot of the extra code from the examples and tried to make a really basic script. Here's my code:

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>three.js webgl - collada</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    </head>
    <body>
        <script src="../build/three.min.js"></script>
        <script src="js/loaders/ColladaLoader.js"></script>
        <script src="js/Detector.js"></script>

        <script>

            if ( ! Detector.webgl ) Detector.addGetWebGLMessage();

            var container;
            var camera, scene, renderer, objects;
            var dae, skin, animation, kfAnimation;
            var clock = new THREE.Clock();
            var loader = new THREE.ColladaLoader();

            loader.load( './obj/Test1/TestSKINNED_Animation01.dae', function ( collada ) {

                dae = collada.scene;
                skin = collada.skins[ 0 ];
                animation = collada.animations[0];

                dae.scale.x = dae.scale.y = dae.scale.z = 1;

                init();
                animate();
            } );

            function init() {

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

                scene = new THREE.Scene();

                // Add the camera
                camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
                camera.position.set( 10, 2, 0 );
                camera.lookAt( scene.position );

                // Add the Collada
                scene.add( dae );

                var animHandler = THREE.AnimationHandler;
                animHandler.add( animation );

                kfAnimation = new THREE.KeyFrameAnimation( animation.node, animation.name );
                kfAnimation.timeScale = 1;
                kfAnimation.play( true, 0 );

                // Add the light
                var directionalLight = new THREE.DirectionalLight( 0xeeeeee );
                directionalLight.position.set(0.5, 0.5, 0.5);
                scene.add( directionalLight );

                renderer = new THREE.WebGLRenderer();
                renderer.setSize( window.innerWidth, window.innerHeight );

                container.appendChild( renderer.domElement );
            }

            function animate() {

                var delta = clock.getDelta();
                kfAnimation.update(delta);
                render();
                requestAnimationFrame( animate );
            }

            function render() {

                renderer.render( scene, camera );
            }

        </script>
    </body>
</html>

It loads the model but it doesn't animate. Is this likely a problem with the code or the model? Thanks.

user2533187
  • 31
  • 1
  • 3

4 Answers4

0

From what I understood from kfAnimations is that they work for JSON files, you're working with a DAE file so youll just have to use the skin.influences way of animating a model:

function animate() {
    var delta = clock.getDelta();
    if ( t > 1 ) t = 0;
        if ( skin ) {
            for ( var i = 0; i < skin.morphTargetInfluences.length; i++ ) {
                skin.morphTargetInfluences[ i ] = 0;
            }
            skin.morphTargetInfluences[ Math.floor( t * 30 ) ] = 1;
            t += delta;
         }  
    requestAnimationFrame(animate);
    render();
}
lloydimus
  • 109
  • 3
  • 13
0

I am also facing the same problem but by comparing closely my collada file and the pump.dae sample, I can deduce that the THREE.ColladaLoader can not load animation that uses the LINEAR interpolation. The pump.dae sample actually uses the BEZIER interpolation. When using my collada files the collada.animations property actually returns an empty vector as if no animation were found whereas using it with the pump.dae sample you get the exact number of animation node in the file.

0

you need yo add traverse function inside your load to render animations

loader.load( './obj/Test1/TestSKINNED_Animation01.dae', function ( collada ) {

            dae = collada.scene;
            skin = collada.skins[ 0 ];
            animation = collada.animations[0];

            dae.scale.x = dae.scale.y = dae.scale.z = 1;

  dae.traverse( function ( child ) {
   if ( child instanceof THREE.SkinnedMesh ) {
    var animation = new THREE.Animation( child, child.geometry.animation  );
    animation.play();
   }
  });

            init();
            animate();
        } );
Taurus
  • 157
  • 9
0

user674756 is right, there are important limitations in the Collada loader for three.js, and it looks like they won't get fixed soon. A full list of the limitations is at https://github.com/mrdoob/three.js/issues/2963

There is, though, a tool which tries to load a .dae file, simplify it and convert it into a JSON which should prove more malleable. You can use it inline here. http://rmx.github.io/collada-converter/preview/examples/convert.html There's also a preview, so you can check if your animation comes through.