提问者:小点点

用three.js中的three.gltfloader导入和播放多个动画


从Blender中,我使用gltfExporter导出了一个动画模型(spaceship)和一个动画相机作为.glb,当我将.glb文件放入glTF查看器(gltf-viewer.donmccurdy.com)时,一切正常,所以我知道问题不在模型/Blender。

问题是当我尝试和播放我的脚本中的动画。我可以让模型完美地动画,也可以让相机完美地动画,但当我尝试做相机和模型都疯狂。我想这可能是我对动画混合器缺乏了解?也许我只需要为一个文件使用一个混合器?总之,我要做的是:

我创建了两个单独的动画混合器,一个用于宇宙飞船,一个用于摄像机:

gltfStore.mixer = new THREE.AnimationMixer(gltf.cameras[0]);
gltfStore.mixerShip = new THREE.AnimationMixer(gltf.scene.children[2]);

我使用ClipAction播放动画:

gltfStore.mixer.clipAction(gltfStore.animations[0]).play(); 
gltfStore.mixerShip.clipAction(gltfStore.animations[0]).play();

在我的循环中,我呈现动画:

gltfStore.mixer.update(clock.getDelta());
gltfStore.mixerShip.update(clock.getDelta());

它们单独工作,但合在一起就不行了。我注意到,导入到glTF动画对象中的动画数据包括glTF.animations[0]下的camera和model的动画。我的意思是gltf.animations[0]有一个tracks数组,它包含6项,每个项的位置、四元数和比例。对吗?

为方便起见,这里是主要的js文件:

var scene = new THREE.Scene();      
var mixer, animationClip;
var clock = new THREE.Clock();

var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

//LIGHTS
var light = new THREE.PointLight( 0xffffff, 1, 200 );
light.position.set( 10, -10, 0 );
scene.add( light )

//OBJECT TO STORE THE GLTF ASSETS WHEN LOADED
var gltfStore = {};

var loader = new THREE.GLTFLoader();

// LOAD GLTF ASSETS
var gltfCamera = loader.load(
    'spaceship.glb',
    function ( gltf ) {

        scene.add( gltf.scene );
        gltfStore.animations =  gltf.animations;
        gltfStore.ship = gltf.scene.children[2];
        gltfStore.cam =  gltf.cameras[0];

        gltfStore.mixer = new THREE.AnimationMixer(gltf.cameras[0]);
        gltfStore.mixerShip = new THREE.AnimationMixer(gltf.scene.children[2]);

        gltfStore.mixer.clipAction(gltfStore.animations[0]).play();
        gltfStore.mixerShip.clipAction(gltfStore.animations[0]).play();
        }
);


function animate() {
    requestAnimationFrame( animate );
    if(gltfStore.mixer && gltfStore.cam){
        //gltfStore.mixer.update(clock.getDelta());
        gltfStore.mixerShip.update(clock.getDelta());
          renderer.render(scene, gltfStore.cam);
    }      
};

animate();

谢谢你的任何帮助/点子!


共1个答案

匿名用户

所以,在进一步研究了一些例子之后,我找到了答案。

简单地说,不需要单独提取和尝试动画模型和相机,所需要的只是从场景本身创建一个animatiomixer:

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

上面完美的动画化了所有的元素。