一、 解析外部模型变形动画目标数据
1. 加载查看模型变形动画数据
- 加载完三维模型后,通过
console.log(geometry.morphTargets)
可以在浏览器控制台查看模型的变形数据。
javascript
// 通过加载器JSONLoader加载变形动画模型文件./人/umich_ucs.json
const loader = new THREE.JSONLoader();
loader.load("./人/umich_ucs.json", function(geometry, materials) {
// console.log(geometry);
// console.log(materials);
// 通过平均面法线来计算顶点法线,效果更光滑
geometry.computeVertexNormals();
const mesh = new THREE.Mesh(geometry, materials[0]);
// 材质对象开启渲染目标
mesh.material.morphTargets = true
mesh.rotateX(-Math.PI / 2);
mesh.position.y = -50;
scene.add(mesh); //插入到场景中
// 查看变形目标数据
console.log(geometry.morphTargets);
})
- 可以在代码中给网格模型的
.morphTargetInfluences
属性赋予不同的值,测试人的胖瘦变化。javascript// 变胖 mesh.morphTargetInfluences[0] = 1;
javascript// 变瘦 mesh.morphTargetInfluences[4] = 1;
2. 滚动条调节人胖瘦
vue
<div id="app">
<div class="block" style="display:inline;width:500px">
<el-slider v-model="time" show-input :max=1 :step=0.01></el-slider>
</div>
</div>
- 通过
vue.js
把网格模型Mesh
的.morphTargetInfluences
属性和滚动条进行绑定, 只要滚动条改变就可以同步改变mesh.morphTargetInfluences
属性值,mesh.morphTargetInfluences
属性值改变,人的胖瘦自然跟着改变。javascriptconst loader = new THREE.JSONLoader(); //创建加载器 loader.load("./人/umich_ucs.json", function(geometry, materials) { // 通过平均面法线来计算顶点法线,效果更光滑 geometry.computeVertexNormals(); const mesh = new THREE.Mesh(geometry, materials[0]); // 材质对象开启渲染目标 mesh.material.morphTargets = true mesh.rotateX(-Math.PI / 2); mesh.position.y = -50; scene.add(mesh); //插入到场景中 //实例化vue vm = new Vue({ el: "#app", data: { time: 0, }, watch: { time: function(value) { mesh.morphTargetInfluences[0] = value; // 变胖 // mesh.morphTargetInfluences[4] = value; // 变瘦 } }, }) })
3. 鸟飞行变形动画
- 通过混合器
AnimationMixer
获取模型中的变形动画关键帧数据然后进行播放。
javascript
const loader = new THREE.JSONLoader(); //创建加载器
const mixer = null; //声明一个混合器变量
loader.load("./鸟/flamingo.json", function(geometry) {
// console.log(geometry);
const material = new THREE.MeshPhongMaterial({
morphTargets: true,
vertexColors: THREE.FaceColors,
});
// 通过平均面法线来计算顶点法线,效果更光滑
geometry.computeVertexNormals();
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh); //插入到场景中
// 创建一个混合器,播放网格模型模型的变形动画
mixer = new THREE.AnimationMixer(mesh);
// geometry.animations[0]:获得剪辑对象clip
const AnimationAction=mixer.clipAction(geometry.animations[0]);
// AnimationAction.timeScale = 0.5; //默认1,可以调节播放速度
// AnimationAction.loop = THREE.LoopOnce; //不循环播放
// AnimationAction.clampWhenFinished=true;//暂停在最后一帧播放的状态
AnimationAction.play();//播放动画
})
- 在渲染函数中,通过时钟类
Clock
获得两次渲染的时间间隔, 然后执行mixer.update();
传递给混合器AnimationMixer
。javascript// 创建一个时钟对象Clock const clock = new THREE.Clock(); // 渲染函数 function render() { renderer.render(scene, camera); //执行渲染操作 requestAnimationFrame(render); //请求再次执行渲染函数render,渲染下一帧 //clock.getDelta()方法获得两帧的时间间隔 // 更新混合器相关的时间 mixer.update(clock.getDelta()); } render();