加載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
屬性的數組包含兩個剪輯對象AnimationClip,obj.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();