学习Three.js——动画(Animation)

Tween

用法:

var tween = new TWEEN.Tween({x:10}).to({x:3},10000).easing(TWEEN.Easing.Elastic.InOut).OnUpdate(function(){
    
})

Tween(…).to(…,time)是从一个状态变化到另一个状态,time是变化需要的时间(毫秒)

easing是变化的方式,OnUpdate是变化过程的需要更新的一些变化

		var posSrc = {pos: 1};//初始状态
        var tween = new TWEEN.Tween(posSrc).to({pos: 0}, 5000);
        tween.easing(TWEEN.Easing.Sinusoidal.InOut);

        var tweenBack = new TWEEN.Tween(posSrc).to({pos: 1}, 5000);
        tweenBack.easing(TWEEN.Easing.Sinusoidal.InOut);

        tween.chain(tweenBack);//将两个tween连接在一起
        tweenBack.chain(tween);


        var onUpdate = function () {
            var count = 0;
            var pos = this.pos;

            loadedGeometry.vertices.forEach(function (e) {
                var newY = ((e.y + 3.22544) * pos) - 3.22544;
                pointCloud.geometry.vertices[count++].set(e.x, newY, e.z);
            });

            pointCloud.sortParticles = true;
        };

        tween.onUpdate(onUpdate);
        tweenBack.onUpdate(onUpdate);

变形动画

变形动画简单地说就是把一堆顶点移动到一个新的位置

使用MorphAnimMesh创建动画

使用外部模型创建动画

			var loader = new THREE.JSONLoader();
        	loader.load('../assets/models/horse.js', function (geometry, mat) {

            var mat = new THREE.MeshLambertMaterial(
                    {
                        morphTargets: true,//使用变形动画时,此值要设置为true
                        vertexColors: THREE.FaceColors//材质颜色设置为几何体的面的颜色
                    });

            morphColorsToFaceColors(geometry);

            geometry.computeFaceNormals();//计算各个面的法向量,这样才能有效计算出各个面的变化

            meshAnim = new THREE.MorphAnimMesh(geometry, mat);
            scene.add(meshAnim);

        }, '../assets/models');
		//这个函数的作用是将每个面形变后的颜色传给当前的颜色
		function morphColorsToFaceColors(geometry) {
			//形变动画形变的各个面的颜色都存储在geometry.morphColors中,将其提取出来赋给几何体的面即可
            if (geometry.morphColors && geometry.morphColors.length) {

                var colorMap = geometry.morphColors[0];
                for (var i = 0; i < colorMap.colors.length; i++) {
                    geometry.faces[i].color = colorMap.colors[i];
                    geometry.faces[i].color.offsetHSL(0, 0.3, 0);
                }
            }
        }

		function render() {
            stats.update();
			//使用clock更新
            var delta = clock.getDelta();
            webGLRenderer.clear();
            if (meshAnim) {
                meshAnim.updateAnimation(delta * 1000);
                meshAnim.rotation.y += 0.01;
            }
            // render using requestAnimationFrame

            requestAnimationFrame(render);
            webGLRenderer.render(scene, camera);
        }

使用morphTargetInfluence创建自定义的动画

很简单,先使用cubeGeometry.morphTargets[]指定变化后的几何体,再使用cube.morphTargetInfluences指定这个几何体的影响程度,注意可以指定多个几何体

// create a cube
        var cubeGeometry = new THREE.BoxGeometry(4, 4, 4);
        var cubeMaterial = new THREE.MeshLambertMaterial({morphTargets: true, color: 0xff0000});

        // define morphtargets, we'll use the vertices from these geometries
        var cubeTarget1 = new THREE.BoxGeometry(2, 10, 2);
        var cubeTarget2 = new THREE.BoxGeometry(8, 2, 8);

        // define morphtargets and compute the morphnormal
        cubeGeometry.morphTargets[0] = {name: 't1', vertices: cubeTarget2.vertices};
        cubeGeometry.morphTargets[1] = {name: 't2', vertices: cubeTarget1.vertices};
        cubeGeometry.computeMorphNormals();

        var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);

		var controls = new function () {
            this.influence1 = 0.01;
            this.influence2 = 0.01;

            this.update = function () {
                cube.morphTargetInfluences[0] = controls.influence1;
                cube.morphTargetInfluences[1] = controls.influence2;
            };
        };

骨骼动画

比变形动画复杂一些,一组顶点作为一块骨头,一般一块骨头动整组定点都会跟着动,而且负责一些动作(旋转,扭动等)的点一般都是关节点,一般从外部模型导入。

使用THREE.SkinnedMesh创建网格

使用自定义的动作创建骨骼动画

一般SkinnedMesh和Tween配合使用

		var loader = new THREE.JSONLoader();
        loader.load('../assets/models/hand-1.js', function (geometry, mat) {
            //使用骨骼动画要将skinning设置为true
            var mat = new THREE.MeshLambertMaterial({color: 0xF0C8C9, skinning: true});
            mesh = new THREE.SkinnedMesh(geometry, mat);

            // rotate the complete hand
            mesh.rotation.x = 0.5 * Math.PI;
            mesh.rotation.z = 0.7 * Math.PI;

            // add the mesh
            scene.add(mesh);

            // and start the animation
            tween.start();

        }, '../assets/models');
		//设置骨架的动作
        var onUpdate = function () {
            var pos = this.pos;

            console.log(mesh.skeleton);

            // rotate the fingers
            mesh.skeleton.bones[5].rotation.set(0, 0, pos);
            mesh.skeleton.bones[6].rotation.set(0, 0, pos);
            mesh.skeleton.bones[10].rotation.set(0, 0, pos);
            mesh.skeleton.bones[11].rotation.set(0, 0, pos);
            mesh.skeleton.bones[15].rotation.set(0, 0, pos);
            mesh.skeleton.bones[16].rotation.set(0, 0, pos);
            mesh.skeleton.bones[20].rotation.set(0, 0, pos);
            mesh.skeleton.bones[21].rotation.set(0, 0, pos);

            // rotate the wrist
            mesh.skeleton.bones[1].rotation.set(pos, 0, 0);
        };

        var tween = new TWEEN.Tween({pos: -1})
                .to({pos: 0}, 3000)
                .easing(TWEEN.Easing.Cubic.InOut)
                .yoyo(true)//一个动作完毕后,使用相反的动作变回初始状态
                .repeat(Infinity)//无限循环
                .onUpdate(onUpdate);

        render();

使用外部模型创建骨骼动画

因为动作在外部模型中已经定义好了,只需要闯将一个Animation对象,调用其play()方法即可

var loader = new THREE.JSONLoader();
        loader.load('../assets/models/hand-2.js', function (model, mat) {

            var mat = new THREE.MeshLambertMaterial({color: 0xF0C8C9, skinning: true});
            mesh = new THREE.SkinnedMesh(model, mat);
			//在geometry中已经定义好了动画
            var animation = new THREE.Animation(mesh, model.animation);

            mesh.rotation.x = 0.5 * Math.PI;
            mesh.rotation.z = 0.7 * Math.PI;
            scene.add(mesh);
			//能够看到线框
            helper = new THREE.SkeletonHelper(mesh);
            helper.material.linewidth = 2;
            helper.visible = false;
            scene.add(helper);

            // start the animation
            animation.play();

        }, '../assets/models');


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