16.关键帧动画

 关键帧动画

创建关键帧动画

// 时间数组
const timeArr = [0, 3, 6, 9];
// 位置数组,3组为一个位置
const positionArr = [0, 0, 0, 100, 0, 0, 0, 0, 100, 0, 0, 0];
// 创建位置关键帧
const posKF = new THREE.KeyframeTrack('Box.position', timeArr, positionArr);
// 创建颜色关键帧
const colorKF = new THREE.KeyframeTrack('Box.material.color', [0, 3, 6, 9], [0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0]);
// 创建动画
const clip = new THREE.AnimationClip('test', 9, [posKF, colorKF]);
// 创建动画播放器AnimationMixer,设置要播放的物体为mesh
const mixer = new THREE.AnimationMixer(mesh);
// 定义播放器所播放的动画
const clipAction = mixer.clipAction(clip);
// 开始播放动画,play默认为循环播放
clipAction.play();

// 创建时钟对象
const clock = new THREE.Clock();
function loop () {
    requestAnimationFrame(loop);
    // 获取loop()执行间隔时间
    const frameT = clock.getDelta();
    // 更新播放器时间数据
    mixer.update(frameT);
}
loop();
 

 关键帧动画(暂停、倍速、循环)

执行动画播放器AnimationMixer的clipAction()方法会返回一个AnimationAction对象。AnimationAction对象的功能就是用来控制如何播放关键帧动画,比如是否播放、几倍速播放、是否循环播放、是否暂停播放等等

// 设置动画不循环播放
clipAction.loop = THREE.LoopOnce; 

// 设置物体状态停留在动画结束的时候(默认情况下物体状态会停留在动画播放前)
clipAction.clampWhenFinished = true;

// 设置动画停止结束,回到开始状态
clipAction.stop();

// 设置动画为暂停播放状态
clipAction.paused = true;

// 设置动画2倍速播放
clipAction.timeScale = 2;

// 通过GUI对象动态调节播放倍速
const gui = new GUI();   //创建GUI对象
gui.add(clipAction, 'timeScale', 0, 6);  // 0~6倍速之间调节

动画播放(任意时间播放状态)

// 设置开始播放时间
clipAction.time = 1; 
// 设置播放结束时间
clipAction.duration = 5;

// 设置拖动条控制播放动画
import {GUI} from 'three/addons/libs/lil-gui.module.min.js';
const gui = new GUI(); //创建GUI对象
gui.add(clipAction, 'time', 0, 6);
gui.add(clipAction, 'time', 0, 6).step(0.1);

解析外部模型关键帧动画

在开发过程中,有时候会用三维建模软件设置动画,一起跟随模型导出文件,这时候,只需要播放文件中的动画即可

loader.load("../士兵.glb", function (gltf) {
    // console.log('动画数据', gltf.animations);
    model.add(gltf.scene);
    
    // 创建动画播放器
    const mixer = new THREE.AnimationMixer(gltf.scene);
    // 添加文件中的动画
    const clipAction = mixer.clipAction(gltf.animations[3]);
    // 开始播放
    clipAction.play();

    const clock = new THREE.Clock();
    function loop () {
        requestAnimationFrame(loop);
        //clock.getDelta()方法获得loop()两次执行时间间隔
        const frameT = clock.getDelta();
        // 更新播放器相关的时间
        mixer.update(frameT);
    }
    loop();
})

变形动画

使用BufferGeometry的morphAttributes属性设置几何体目标顶点变形数据,Mesh的morphTargetInfluences属性控制变形的权重系数

const geometry = new THREE.BoxGeometry(50, 50, 50);
const target1 = new THREE.BoxGeometry(50, 200, 50).attributes.position;
const target2 = new THREE.BoxGeometry(10, 50, 10).attributes.position;

// 设置morphAttributes变形属性为target1和target2
geometry.morphAttributes.position = [target1, target2]
const material = new THREE.MeshLambertMaterial({
    color: 0x00ffff
});
const mesh = new THREE.Mesh(geometry, material);

mesh.name = 'Box';
// 将变形属性创建成关键帧动画
const KF1 = new THREE.KeyframeTrack('Box.morphTargetInfluences[0]', [0, 5], [0, 1]);
const KF2 = new THREE.KeyframeTrack('Box.morphTargetInfluences[1]', [5, 10], [0, 1]);
const clip = new THREE.AnimationClip("test", 10, [KF1, KF2]);

// 播放变形动画
const mixer = new THREE.AnimationMixer(mesh);
const clipAction = mixer.clipAction(clip);
clipAction.play();
clipAction.loop = THREE.LoopOnce; //不循环播放
clipAction.clampWhenFinished = true // 物体状态停留在动画结束的时候

const clock = new THREE.Clock();

function loop () {
    requestAnimationFrame(loop);
    const frameT = clock.getDelta();
    // 更新播放器时间
    mixer.update(frameT);
}
loop();
export default mesh;

初始骨骼Bone

Bone骨骼是threejs的一个类,用来模拟人或动物的骨骼,他的父节点是Object3D,继承了位置属性position、旋转属性rotation等等

// 创建骨骼
const Bone1 = new THREE.Bone();
const Bone2 = new THREE.Bone();
const Bone3 = new THREE.Bone();
// 设置骨骼父子关系,将骨骼关联起来
Bone1.add(Bone2);
Bone2.add(Bone3);
Bone1.position.set(50, 0, 50);
Bone2.position.y = 60;
Bone3.position.y = 30;

// 将骨骼添加至组对象中
const group = new THREE.Group();
group.add(Bone1);

// 创建骨骼处理器,显示我们创建的骨骼对象
const SkeletonHelper = new THREE.SkeletonHelper(group);
group.add(SkeletonHelper);

// GUI动态控制骨骼旋转
const gui = new GUI();
gui.add(Bone1.rotation, 'x', 0, Math.PI / 2).name('骨骼1');
gui.add(Bone2.rotation, 'x', 0, Math.PI / 2).name('骨骼2');

猜你喜欢

转载自blog.csdn.net/weixin_60645637/article/details/131506184