從3dMax導出供threeJS使用的帶動做模型與加載(認真修改詳盡版)

評論區發現的建議,最近沒空測試,先貼這數組

clipboard.png

還有好多人說找不到插件的 https://pan.baidu.com/s/1Q5g0... 密碼:b43e 。 應該是他們如今只是維護blender,只有這個的插件,不如改用blender?函數

在本身作的一個小玩意中,發現要從3dMax中導出js文件供給threeJS使用,真是太多坑了!因此打算詳細記錄一下方法,好像開發會3dMax的比較少,可是至少能夠幫助開發與美工更好的溝通與交流。在文末,我會附上一個可加載的js模型,方便學習~

圖片描述

導出文件類型選型

在《THREE.JS開發指南》2015年第一印初版中說起的支持的模型主要有一下幾種工具

clipboard.png

圖中的確是一些常見格式,咱們能夠經過這個表格對常見格式作一些瞭解,可是咱們從Three.js的官方實例的Loaders包中能夠看到,發現他如今提供了各類加載器來支持文件加載,咱們能夠根據咱們的需求來選擇咱們須要的加載方式學習

clipboard.png

與3dmax自帶的導出選擇相比較,能夠導出.FBX,Collada,STL,OBJ和MTL等文件,而後使用對應的Loader進行加載。咱們能夠選擇本身熟悉的工具,熟悉的格式進行模型的導出,可是也正是因爲他的多樣性,致使無從下手,在嘗試了Blender導出動做模型,與DDS素材轉換等等工具以後,最終決定採用,我較爲熟悉3dMax爲建模工具,來導出我最熟悉的js文件來完成模型的導出與加載測試

下面是我通過實驗後對一些常見格式的記錄與分析大體統計出的一些選型分析動畫

clipboard.png

clipboard.png

若是不須要作那麼多選型的話,直接導出js好了~各方面都比較合適。ui

如何導出動態模型的js文件

安裝3dMax導出插件

clipboard.png

.OBJ導出來的僅僅是模型,.MTL導出來的僅僅是材質,那動做呢?js在Three.js中支持的動做導出,在3dmax,maya,blender中並無直接導出js的方法,慶幸的是大牛已經給咱們開發了愈來愈豐富的插件了。在utils中的export中包含了這些插件(文件目錄.\three.js-master\three.js-master\utils\exporters\max),咱們須要將這些插件直接複製到3dmax的plugin文件夾中,若是都是須要導出包含動做的,只須要安裝ThreeJSAnimationExporter.ms這一個文件就夠了,重啓3dmax後打開就能夠看到這個插件了。(以下圖)spa

clipboard.png

如何獲取一個可加載模型(以一個簡單的圓柱體爲例)

clipboard.pngclipboard.png

  1. 首先你的模型必須是一個總體,好比你的模型是熊貓吃竹子,若是你的熊貓和竹子要一塊導出,那麼你的熊貓和竹子必須是一個總體
  2. 貼圖只能有一張,且貼圖是png格式
  3. 給bone(骨骼)認真命名,js導出後你可能會發現骨骼有點偏移與錯位,嚴格的命名有助於你在建模或者導出的時候進行修改,不過對開發來講這點會比較麻煩,這點也不是必須的。
  4. 模型的每個點都必須賦予權重,若是發生破面行爲,那麼很是有多是加了動做的模型卻有的店沒有權重
  5. 骨骼測試可用的有bone和CS骨骼,若是採用其餘骨骼最好進行測試
  6. 導出的時候你的模型必須是一個Mesh,很是重要!這就意味着你不能導出一個可編輯多邊形或者其餘形式,在咱們添加skin修改器的時候,先添加一個EditMesh修改器在咱們的物體上,若是你已是一個editable mesh,那這就不須要了。最好再使用Unwrap, UVW,中途出現warning點肯定就好。

clipboard.png

  1. 導出的時候選擇模型就好,不要選擇骨骼,若是把骨骼一塊兒選擇導出會出現以下錯誤

    clipboard.png

  2. 添加一個XForm修改器於你的模型當你開始導出以前,他會重置你物件的位置,轉向等等,將它變爲初始那樣,最小化在導出時可能遇到的問題

    clipboard.png

  3. 若是發生錯誤,修復完畢後須要從新啓動3dmax才能正常使用導出插件
  4. 能夠先驗證模型導出的數據量和點格式的正確與否再進行加載,通常導出文件的貼圖地址會與你的地址不一樣,須要打開導出文件(以下圖)修改貼圖對應地址

    clipboard.pngclipboard.png

  5. 加載過程當中你有可能看不見模型,那麼頗有多是你的模型過大或者太小,能夠直接在代碼中用scale函數進行調整測試
  6. 若是還有問題,建議在重複以上幾點查看一遍

代碼中如何加載動態模型

在程序中主要是這幾個步驟
clipboard.png插件

下面是代碼的部分節選,其實官方的教程例子寫的很完整,以後把一個完整可運行的實例傳在GIt上~3d

/**
 * @method animateModel
 * @description 
 *  一個建立帶動畫模型的方法
 * @param {object} object.g 幾何體 object.m 材質  object.name 名字
 */
var zz;
var animateModel = function(config) {
    var geometry = config.g;
    var materials = config.m;
    for (var i = 0; i < materials.length; i++) {
        var m = materials[i];
        m.skinning = true
    }

    // 建立材質,因爲材質是多面材質,由材質數組組成故要調用MultiMaterial方法來建立一個新的材質
    var material = new THREE.MultiMaterial(materials);
    //建立出一個骨骼帶蒙皮的網格對象
    var mesh = new THREE.SkinnedMesh(geometry, material);
    //給這個網格模型增長他的屬性
    mesh.name = config.name;
    // 初始化模型位置
    mesh.position.set(0, 0, 0);
    mesh.geometry.computeVertexNormals();

    //用你的網格模型去建立一個骨骼幫助器 
    var skeletonHelper = new THREE.SkeletonHelper(mesh)
    skeletonHelper.material.linewidth = 3;
    // 咱們能夠打開skeletonHelper,這樣能夠看到骨骼,便於調整
    skeletonHelper.visible = true;
    //將骨骼添加到場景
    scene.add(skeletonHelper);

    // AnimationMixer 動畫混合器 理解爲這個動畫各方面的一個管理者吧
    var mixer = new THREE.AnimationMixer(mesh);
    // 骨骼動畫的動做片斷保存在geometry中 下面是讀取第一個動畫的方式,因此animationFirst是一個AnimationClip
    var firstAnimation = geometry.animations[0];
    // AnimationAction是動做的schedule,之因此叫schedule是由於他能夠控制着動畫開始 結束 中止 這些流程
    var action = mixer.clipAction(firstAnimation);

    // 接下來能夠爲這個動畫配置一些細節了
    action.clampWhenFinished = false;
//  0會中止,這裏設置爲0默認中止,不停要注意其餘的地方是否有設置這個值,值越大越快
    action.setEffectiveTimeScale(0);
    action.play();
    mesh.mixer = mixer;
    mesh.action = action;
    mesh.skeletonHelper = skeletonHelper;
    return mesh;
}

//加載模型數據
var loader = new THREE.JSONLoader();
loader.load("static/img/model/czz3.js", function(geometry, materials) {
    var config = { name: "zz", g: geometry, m: materials };
                zz = animateModel(config);
                zz.status = 1;
                zz.action.time = 0;
                zz.action.setEffectiveTimeScale(0.7);
                zz.rotation.set(-26, 0, 0);
                zz.scale.set(7, 7, 7)
                zz.visible = true;
                scene.add(zz);
                addAnimateModel.animate();
                console.log(TWEEN.Tween)
                var zz_tween = new TWEEN.Tween(jichan.position).to({ z: 20 }, 10000)
                zz_tween.repeat(Infinity);
                zz_tween.start()
});
//主要理解render和animate這兩個函數,模型能載入,缺動不起來主要都是這個袁術
var clock = new THREE.Clock();
function render() {
    // if (animation) animation.update(delta);
    var r = Date.now() * 0.0005;
    var delta = clock.getDelta();
    zz.mixer.update(delta);
    zz.skeletonHelper.update();
    stats.update();
    renderer.render(scene, camera);
}
function animate() {
    render();
    requestAnimationFrame(animate);
    trackBallControl.update();
}

靜態模型的導出與加載

靜態模型的導出,對我而言用3dmax直接導出obj最簡單了,用導出OBJ和MTL格式,若是隻要選擇導出不帶貼圖的模型,那麼在Material這一欄的Create mat-library則不用勾選.

require('OBJLoader.js')
require('MTLLoader.js')

/**
 * 加載一個有貼圖模型
 */
const createMtlObj = argv => {

    THREE.Loader.Handlers.add(/\.dds$/i, new THREE.DDSLoader());
    //建立材質加載器
    let mtlLoader = new THREE.MTLLoader();
    // 設置材質加載路徑 (相對路徑)
    mtlLoader.setPath(argv.mtlPath);

    mtlLoader.load(argv.mtlFileName, function(materials) {
        materials.preload();
        let objLoader = new THREE.OBJLoader();
        objLoader.setMaterials(materials);
        objLoader.setPath(argv.objPath);
        objLoader.load(argv.objFileName, function(object) {
                // 加載模型完成後的回調函數
                if (typeof argv.completeCallback === 'function') {
                    argv.completeCallback(object);
                }
            },

            // 加載中
            function(xhr) {
                if (xhr.lengthComputable) {
                    var percentComplete = xhr.loaded / xhr.total * 100;
                    console.log(Math.round(percentComplete, 2) + '% downloaded');
                }
            },
            function(error) { console.log('error:' + error) }
        );
    });

}

一個js動態模型文件——一頭不嚇人的蜘蛛

太長了,連接: https://pan.baidu.com/s/1boI98hL 密碼: ethr

相關文章
相關標籤/搜索