解析外部模型變形動畫目標數據
本文是Three.js電子書的12.4節
本節課給大家展示兩個變形動畫的案例,一個是鳥的飛行變形動畫,一個是通過滾動條控制人體的變形案例。
加載查看模型變形動畫數據
加載完三維模型後,通過console.log(geometry.morphTargets)
可以在瀏覽器控制檯查看模型的變形數據。
// 通過加載器JSONLoader加載變形動畫模型文件./人/umich_ucs.json
var loader = new THREE.JSONLoader();
loader.load("./人/umich_ucs.json", function(geometry, materials) {
// console.log(geometry);
// console.log(materials);
// 通過平均面法線來計算頂點法線,效果更光滑
geometry.computeVertexNormals();
var 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
屬性賦予不同的值,測試人的胖瘦變化。
// 變胖
mesh.morphTargetInfluences[0] = 1;
// 變瘦
mesh.morphTargetInfluences[4] = 1;
滾動條調節人胖瘦
下面代碼中的滾動條<el-slider...></el-slider>
是通過vue的UI庫element-ui實現的,你也可以換別的方式,這都是前端的內容,不再多說。
<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>
下面代碼通過vuejs把網格模型Mesh的.morphTargetInfluences
屬性和滾動條進行綁定,只要滾動條改變就可以同步改變mesh.morphTargetInfluences
屬性值,mesh.morphTargetInfluences
屬性值改變,人的胖瘦自然跟着改變。
var loader = new THREE.JSONLoader(); //創建加載器
loader.load("./人/umich_ucs.json", function(geometry, materials) {
// 通過平均面法線來計算頂點法線,效果更光滑
geometry.computeVertexNormals();
var 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; // 變瘦
}
},
})
})
鳥飛行變形動畫
通過混合器AnimationMixer獲取模型中的變形動畫關鍵幀數據然後進行播放。
var loader = new THREE.JSONLoader(); //創建加載器
var mixer = null; //聲明一個混合器變量
loader.load("./鳥/flamingo.json", function(geometry) {
// console.log(geometry);
var material = new THREE.MeshPhongMaterial({
morphTargets: true,
vertexColors: THREE.FaceColors,
});
// 通過平均面法線來計算頂點法線,效果更光滑
geometry.computeVertexNormals();
var mesh = new THREE.Mesh(geometry, material);
scene.add(mesh); //插入到場景中
// 創建一個混合器,播放網格模型模型的變形動畫
mixer = new THREE.AnimationMixer(mesh);
// geometry.animations[0]:獲得剪輯對象clip
var AnimationAction=mixer.clipAction(geometry.animations[0]);
// AnimationAction.timeScale = 0.5; //默認1,可以調節播放速度
// AnimationAction.loop = THREE.LoopOnce; //不循環播放
// AnimationAction.clampWhenFinished=true;//暫停在最後一幀播放的狀態
AnimationAction.play();//播放動畫
})
在渲染函數中,通過時鐘類Clock獲得兩次渲染的時間間隔,然後執行mixer.update();
傳遞給混合器AnimationMixer
。
// 創建一個時鐘對象Clock
var clock = new THREE.Clock();
// 渲染函數
function render() {
renderer.render(scene, camera); //執行渲染操作
requestAnimationFrame(render); //請求再次執行渲染函數render,渲染下一幀
//clock.getDelta()方法獲得兩幀的時間間隔
// 更新混合器相關的時間
mixer.update(clock.getDelta());
}
render();