Three.js加載解析外部模型變形動畫

解析外部模型變形動畫目標數據

本文是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();
發佈了141 篇原創文章 · 獲贊 25 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章