評論區發現的建議,最近沒空測試,先貼這數組
還有好多人說找不到插件的 https://pan.baidu.com/s/1Q5g0... 密碼:b43e 。 應該是他們如今只是維護blender,只有這個的插件,不如改用blender?函數
在本身作的一個小玩意中,發現要從3dMax中導出js文件供給threeJS使用,真是太多坑了!因此打算詳細記錄一下方法,好像開發會3dMax的比較少,可是至少能夠幫助開發與美工更好的溝通與交流。在文末,我會附上一個可加載的js模型,方便學習~
在《THREE.JS開發指南》2015年第一印初版中說起的支持的模型主要有一下幾種工具
圖中的確是一些常見格式,咱們能夠經過這個表格對常見格式作一些瞭解,可是咱們從Three.js的官方實例的Loaders包中能夠看到,發現他如今提供了各類加載器來支持文件加載,咱們能夠根據咱們的需求來選擇咱們須要的加載方式學習
與3dmax自帶的導出選擇相比較,能夠導出.FBX,Collada,STL,OBJ和MTL等文件,而後使用對應的Loader進行加載。咱們能夠選擇本身熟悉的工具,熟悉的格式進行模型的導出,可是也正是因爲他的多樣性,致使無從下手,在嘗試了Blender導出動做模型,與DDS素材轉換等等工具以後,最終決定採用,我較爲熟悉3dMax爲建模工具,來導出我最熟悉的js文件來完成模型的導出與加載測試
下面是我通過實驗後對一些常見格式的記錄與分析大體統計出的一些選型分析動畫
若是不須要作那麼多選型的話,直接導出js好了~各方面都比較合適。ui
.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
在程序中主要是這幾個步驟插件
下面是代碼的部分節選,其實官方的教程例子寫的很完整,以後把一個完整可運行的實例傳在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) } ); }); }
太長了,連接: https://pan.baidu.com/s/1boI98hL 密碼: ethr