基本的three.js collada蒙皮动画

Posted

技术标签:

【中文标题】基本的three.js collada蒙皮动画【英文标题】:Basic three.js collada skinned animation 【发布时间】:2013-06-26 16:52:05 【问题描述】:

我正在尝试让一个非常基本的 Collada 模型在 three.js 中制作动画,但我遇到了一些问题。这两个示例(monster 和 pump)都可以在我的机器上运行,但是每当我替换我的模型时,它都会加载但不会动画。

我从示例中删除了很多额外的代码,并尝试制作一个非常基本的脚本。这是我的代码:

<!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>

它会加载模型,但不会设置动画。这可能是代码或模型的问题吗?谢谢。

【问题讨论】:

【参考方案1】:

据我从 kfAnimations 了解到,它们适用于 JSON 文件,您使用的是 DAE 文件,因此您只需使用 skin.influences 为模型设置动画的方式:

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();

【讨论】:

【参考方案2】:

我也面临同样的问题,但通过仔细比较我的 collada 文件和 pump.dae 样本,我可以推断出 THREE.ColladaLoader 无法加载使用 LINEAR 插值的动画。 pump.dae 示例实际上使用了 BEZIER 插值。 使用我的 collada 文件时,collada.animations 属性实际上返回一个空向量,就好像没有找到动画一样,而将它与 pump.dae 示例一起使用,您将获得文件中动画节点的确切数量。

【讨论】:

【参考方案3】:

你需要在你的负载中添加遍历函数来渲染动画

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();
         );

【讨论】:

【参考方案4】:

user674756 是对的,对于three.js 的Collada 加载器存在重要限制,而且看起来它们不会很快得到修复。限制的完整列表位于 https://github.com/mrdoob/three.js/issues/2963

不过,有一个工具会尝试加载 .dae 文件,对其进行简化并将其转换为 JSON,这应该证明更具延展性。您可以在此处内联使用它。 http://rmx.github.io/collada-converter/preview/examples/convert.html 还有一个预览,因此您可以检查您的动画是否通过。

【讨论】:

以上是关于基本的three.js collada蒙皮动画的主要内容,如果未能解决你的问题,请参考以下文章

Blender 导出器 (v70) 到 json three.js 蒙皮动画

在 Three.js 中使用来自 COLLADA 文件的解析数据的骨骼动画

三个 js - 你可以克隆从 collada 文件加载的动画吗?

Three.js - 头像动画

Three.js Collada - 在三个 js 中加载多个 Collada 对象

collada 模型看起来很奇怪(three.js)