Three.js加载动画模型并控制播放

Three.js支持多种3D模型格式的文件加载。本例中我们以fbx文件为例。

首先当然是加载模型了。

    loader.load("fbx/Naruto.fbx", function (mesh) {
        scene.add(mesh);
    }

以上代码为加载模型并添加到场景中。

这是一个多动画的模型。那么首先我们先获取它到底有多少个动作动画。

        //  AnimationMixer 动画混合器是用于场景中特定对象的动画的播放器。当场景中的多个对象独立动画时,每个对象都可以使用同一个动画混合器。
        mixer = new THREE.AnimationMixer( mesh );
        console.log(mesh.animations.length);

这里输出的是28.那么就是说这个模型有28个动画动作。

现在我们来播放第一个动作动画

        //  clipAction 返回所传入的剪辑参数的AnimationAction, 根对象参数可选,默认值为混合器的默认根对象。
        //  第一个参数可以是动画剪辑(AnimationClip)对象或者动画剪辑的名称。
        mixer.clipAction( mesh.animations[ 0] ).play();

当你兴高采烈的localhost测试的时候发现。我擦。好像并没有出现想像中的画面。

那么这是为什么呢。

因为要在你的循环中 加入

    if (mixer) {
        //推进混合器时间并更新动画 
        mixer.update(time);

    }

这样你的模型才会动。好啦。下面是整个案例的代码。

index.html




    
    
    
    
    
    
    
    
    Document


    

Main.js


var scene,camera,renderer,mixer;
var WIDTH,HEIGHT,controls;
var clock = new THREE.Clock();
//  创建渲染器
function initRenderer(){
    WIDTH = window.innerWidth;
    HEIGHT = window.innerHeight;
    renderer = new THREE.WebGLRenderer({animation:true});
    renderer.setSize(WIDTH,HEIGHT);
    renderer.setPixelRatio(WIDTH/HEIGHT);
    renderer.setClearColor(0xeeeeee);
    document.getElementById('canvas-frame').appendChild(renderer.domElement);
}
//  创建场景
function initScene(){
    scene = new THREE.Scene();
}
//  创建相机
function initCamera(){
    camera = new THREE.PerspectiveCamera(50,WIDTH/HEIGHT,1,10000);
    camera.position.set(0,300,350);
    camera.lookAt(0,0,0);
    //  创建控制器
    controls = new THREE.OrbitControls( camera );
}
//  创建灯光
function initLight(){
    //  环境光
    var light = new THREE.AmbientLight( 0x404040 ); // soft white light
    scene.add( light );
    //  平行光
    light = new THREE.DirectionalLight(0xffffff);
    scene.add(light);
}

function initObject(){

    // 地板
    var mesh = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2000, 2000 ), new THREE.MeshPhongMaterial( { color: 0xffffff, depthWrite: false } ) );
    mesh.rotation.x = - Math.PI / 2;
    mesh.receiveShadow = true;
    scene.add( mesh );

    //添加地板割线
    var grid = new THREE.GridHelper( 2000, 20, 0x000000, 0x000000 );
    grid.material.opacity = 0.2;
    grid.material.transparent = true;
    scene.add( grid );
}
//  加载模型并播放第一个动画
function initLoad(){
    var loader = new THREE.FBXLoader();
    loader.load("fbx/Naruto.fbx", function (mesh) {
        scene.add(mesh);
        //  AnimationMixer 动画混合器是用于场景中特定对象的动画的播放器。当场景中的多个对象独立动画时,每个对象都可以使用同一个动画混合器。
        mixer = new THREE.AnimationMixer( mesh );
        console.log(mesh.animations.length);
        for(var i = 0 ; i < mesh.animations.length; i++){
            var action = mixer.clipAction( mesh.animations[ i ] );
            action.stop();
        }
        //  clipAction 返回所传入的剪辑参数的AnimationAction, 根对象参数可选,默认值为混合器的默认根对象。
        //  第一个参数可以是动画剪辑(AnimationClip)对象或者动画剪辑的名称。
        mixer.clipAction( mesh.animations[ 0 ] ).play();

    });
}

function initThree(){
    initRenderer();
    initScene();
    initCamera();
    initLight();
    initObject();
    initLoad();
    animation();
}

function animation(){
    requestAnimationFrame(animation);
    renderer.render(scene,camera);
    controls.update();

    var time = clock.getDelta();
    // update 推进混合器时间并更新动画 
    if (mixer) {

        mixer.update(time);

    }
}

 

你可能感兴趣的:(three.js)