Three.js加載FBX並解析骨骼動畫

加載FBX並解析骨骼動畫

本文是Three.js電子書的14.4節

通過Threejs先加載一個.FBX格式的三維模型文件,然後解析該文件中的骨骼動畫信息。

在這裏插入圖片描述

加載器FBXLoader.js

引入FBX加載器相關文件

<!-- 引入fbx模型加載庫FBXLoader -->
<script src="http://www.yanhuangxueyuan.com/versions/threejsR92/examples/js/loaders/FBXLoader.js"></script>
<!-- 輔助文件 -->
<script src="http://www.yanhuangxueyuan.com/versions/threejsR92/examples/js/libs/inflate.min.js"></script>

加載fbx模型文件

加載模型文件,加載完成後,如果模型顯示位置不符合要求,可以讓3D美術修改,也可以通過Threejs程序進行平移、縮放等操作。

var loader = new THREE.FBXLoader();//創建一個FBX加載器
loader.load("SambaDancing.fbx", function(obj) {
  // console.log(obj);//查看加載後返回的模型對象
  scene.add(obj)
  // 適當平移fbx模型位置
  obj.translateY(-80);
})

查看FBX模型幀動畫數據

stl、obj都是靜態模型,不可以包含動畫,fbx除了包含幾何、材質信息,可以存儲骨骼動畫等數據。

解析之前可以先在瀏覽器控制檯查看動畫相關的數據是如何存儲的。你可以看到obj.animations屬性的數組包含兩個剪輯對象AnimationClipobj.animations[0]對應剪輯對象AnimationClip包含多組關鍵幀KeyframeTrack數據,obj.animations[1]對應的剪輯對象AnimationClip沒有關鍵幀數據,也就是說沒有關鍵幀動畫。具體的開發中,可能美術提供的模型有很多包含關鍵幀動畫的剪輯對象AnimationClip,你可以根據自己的需要解析某個剪輯對象AnimationClip對應的動畫。

var loader = new THREE.FBXLoader();//創建一個FBX加載器
loader.load("SambaDancing.fbx", function(obj) {
  ...
  // 可以在控制檯打印obj對象,找到animations屬性
  console.log(obj)
  // 查看動畫數據  2個剪輯對象AnimationClip,一個有關鍵幀動畫,一個沒有
  console.log(obj.animations)

})

解析fbx模型骨骼動畫

var mixer=null;//聲明一個混合器變量
var loader = new THREE.FBXLoader();//創建一個FBX加載器
loader.load("SambaDancing.fbx", function(obj) {
  // console.log(obj)
  scene.add(obj)
  obj.translateY(-80);
  // obj作爲參數創建一個混合器,解析播放obj及其子對象包含的動畫數據
  mixer = new THREE.AnimationMixer(obj);
  // 查看動畫數據
  console.log(obj.animations)
  // obj.animations[0]:獲得剪輯對象clip
  var AnimationAction=mixer.clipAction(obj.animations[0]);
  // AnimationAction.timeScale = 1; //默認1,可以調節播放速度
  // AnimationAction.loop = THREE.LoopOnce; //不循環播放
  // AnimationAction.clampWhenFinished=true;//暫停在最後一幀播放的狀態
  AnimationAction.play();//播放動畫
})
// 創建一個時鐘對象Clock
var clock = new THREE.Clock();
// 渲染函數
function render() {
  renderer.render(scene, camera); //執行渲染操作
  requestAnimationFrame(render); //請求再次執行渲染函數render,渲染下一幀

  if (mixer !== null) {
    //clock.getDelta()方法獲得兩幀的時間間隔
    // 更新混合器相關的時間
    mixer.update(clock.getDelta());
  }
}
render();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章