說實在的不知道為啥threejs的內容出到了第3期。寫出來防止大家踩坑。
threejs可以添加我們所需要的3d動畫,因為單純的靠threejs本身的對象并不能真正滿足我們的動畫需求。所以threejs提供了許多的加載器來加載到threejs圖層上。方法都大同小異,只要掌握好一種差不多就都能掌握了。廢話不多說我們來看如何加載各種類型的文件:
1、FBX
fbx最大的用途是用在諸如在max、maya、softimage等軟件間進行模型、材質、動作和攝影機信息的互導,這樣就可以發(fā)揮max和maya等軟件的優(yōu)勢??梢哉f,fbx方案是最好的互導方案。所以先來看下FBX導入的辦法。
<!--FBX加載器-->
<script src="js/FBXLoader.js"></script>
<script src="js/inflate.min.js"></script>
這里我們需要添加2個fbx所需要的js文件其中。這些在threejs源碼里面都有。
之后我們添加THREE的FBX加載器。
var loader3 = new THREE.FBXLoader();//新建THREE的FBX加載器
//加載對象模型,是異步加載的,參數是模型的地址,回調函數,家在進度以錯誤處理,前兩個是必須的
loader3.load("fbx/Samba Dancing.fbx",function(object){//產生回調函數返回模型對象
object.mixer = new THREE.AnimationMixer(object);//添加該對象的動畫混合器
mixers3.push(object.mixer);//把動畫添加到數組中
object.rotation.copy(new THREE.Euler(1.5707964,0,0, "ZXY"));//選裝模型,因為mapbox坐標系與threejs坐標系不同
var action = object.mixer.clipAction(object.animations[0]);//獲取對象的第一個動畫
action.play();//啟動動畫
AddThreejs.addAtCoordinate(id,"9",object,"Samba",origin3);//把對象加到我們的mapbox地圖上
});
上述代碼中AnimationMixer是場景中特定對象的動畫播放器,當場景中有多個對象獨立播放動畫,那么每個對象對應一個動畫播放器。其中參數是該對象。
并且由于之前文章提到過mapbox的坐標是地理坐標系,而threejs的是xzy坐標系(左手坐標系),所以我們添加到地圖上時需要將模型進行旋轉,參數是一個歐拉角度(Euler)其參數是(x,y,z,order)分別是x,y,z軸角度(單位為弧度),然后是一個用來表示旋轉順序的字符串,默認為“XYZ”(必須是大寫)。最后mixer.clipAction返回一個可以控制動畫的AnimationAction對象,參數需要一個AnimationClip對象,最后啟動我們的動畫。
在threejs動畫幀渲染中加入我們的動畫
if ( mixers3.length > 0 ) {
for ( var i = 0; i < mixers3.length; i ++ ) {
mixers3[ i ].update( AddThreejs.clock.getDelta());
}
}
2、MMD
我們來試著添加V家的3d模型,添加所需的js文件
<!--MMD加載器-->
<script src="js/mmdparser.min.js"></script>
<script src="js/ammo.js"></script>
<script src="js/MMDLoader.js"></script>
<script src="js/MMDAnimationHelper.js"></script>
<script src="js/CCDIKSolver.js"></script>
<script src="js/MMDPhysics.js"></script>
添加好頭文件后,我們來添加加載的代碼
/////////////////////MMD
var MMDAnimationHelper = new THREE.MMDAnimationHelper({afterglow: 2.0});//添加MMD動畫管理器
var ikHelper,physicsHelper;//骨骼輔助以及物理輔助
var modelFile = 'mmd/miku/miku_v2.pmd';//添加mmd模型
var vmdFiles = [ 'mmd/vmds/wavefile_v2.vmd' ];//模型動作文件
var loader4 = new THREE.MMDLoader();//添加mmd加載器
loader4.loadWithAnimation(modelFile, vmdFiles, function ( mmd ){//加載模型和動作
var meshmiku = mmd.mesh;//獲取mmd的Mesh對象
meshmiku.rotation.copy(new THREE.Euler(1.5707964,0,0, "ZXY"));
meshmiku.scale.set(10,10,10);//設置尺寸
AddThreejs.addAtCoordinate(id,"10",meshmiku,"miku",origin3);//把他添加到mapbox地圖上0
MMDAnimationHelper.add(meshmiku,{//把對象以及動作傳到動畫管理器中
animation:mmd.animation,//添加mmd動畫
physics:true,//打開物理
});
//骨骼輔助顯示
ikHelper = MMDAnimationHelper.objects.get( meshmiku ).ikSolver.createHelper();
ikHelper.visible = false;//不顯示
AddThreejs.addAtCoordinate(id,"11",ikHelper,null,origin3);//添加到地圖
//物理剛體輔助顯示
physicsHelper = MMDAnimationHelper.objects.get( meshmiku ).physics.createHelper();
physicsHelper.visible = false;//不顯示
AddThreejs.addAtCoordinate(id,"12",physicsHelper,null,origin3);//添加到地圖
});
之后添加我們的動畫
MMDAnimationHelper.update(AddThreejs.clock.getDelta());
3、GLTF
GLTF是圖形語言交換格式。它是一種3D內容的格式標準。
首先先加載我們的js文件。
<!--GLTF加載器-->
<script src="js/GLTFLoader.js"></script>
接著添加模型以及動畫
var loader = new THREE.GLTFLoader();//GLTF加載器
loader.load("gltf/Horse.glb",function (gltf){//添加模型,并暴露接口
var meshHorse = gltf.scene.children[0];//獲取其中對象,對象放在scene下面
//meshHorse.position.set(100, 0, 100);
meshHorse.scale.set(0.5,0.5,0.5);//設定尺寸
meshHorse.rotation.copy(new THREE.Euler(1.5707964,0,0, "ZXY"));//模型旋轉
// AddThreejs.scene.add(meshHorse);
AddThreejs.addAtCoordinate(id,"6",meshHorse,"Horse",origin1);//添加對象到地圖中
mixer = new THREE.AnimationMixer(meshHorse);//添加動畫管理器
mixer.clipAction( gltf.animations[ 0 ] ).setDuration( 1 ).play();//設置對象動作
});
if ( mixer ) {
var time = Date.now();
mixer.update( ( time - prevTime ) * 0.001 );
prevTime = time;
}
4、Collada
COLLADA? 是面向交互式 3D 應用程序的基于 XML 的數字資產交換方案,使 3D 創(chuàng)作應用程序可以自由地交換數字資產而不損失信息 - 使多種DCC和3D處理可以組合成強大的工具鏈管道。
<!--Collada加載器-->
<script src="js/ColladaLoader.js"></script>
添加模型
var loader5 = new THREE.ColladaLoader();//添加Collada加載器
loader5.load("collada/stormtrooper/stormtrooper.dae", function ( collada ){//添加文件并獲取回調函數逇返回值
var meshavatar = collada.scene;//collada對象放在scene中
meshavatar.rotation.copy(new THREE.Euler(0.2,0,0, "XZY"));//旋轉對象
meshavatar.scale.set(30,30,30);//設置尺寸
meshavatar.traverse(function (node) {//獲取其中對象
if(node.isSkinnedMesh){
node.frustumCulled = false;
}
});
mixer4 = new THREE.AnimationMixer(meshavatar);//動作管理器
var action = mixer4.clipAction(collada.animations[0]);//設置動作
action.play();
AddThreejs.addAtCoordinate(id,"13",meshavatar,"stormtrooper",origin1);//添加對象
});
最后設定動作時間
if ( mixer4 !== undefined ) {
mixer4.update(clock1.getDelta() );
}
最后的效果圖:

我們仔細品味代碼可以發(fā)現,加載模型以及動畫的代碼都大同小異。
1、添加js頭文件
2、添加模型以及動作
2.1添加XX加載器
2.2設定URL,從回調函數中回去模型
2.3設置動作管理器
2.4配置動作以及執(zhí)行動作
2.5把模型加載到場景中
3、設定動作變化
寫的不好之處,請多見諒