添加3d動畫到threejs并顯示在mapbox上

說實在的不知道為啥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、設定動作變化

寫的不好之處,請多見諒

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容