评论区发现的建议,最近没空测试,先贴这

还有好多人说找不到插件的 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好了~各方面都比较合适。

如何导出动态模型的js文件

安装3dMax导出插件

.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后打开就可以看到这个插件了。(如下图)

如何获取一个可加载模型(以一个简单的圆柱体为例)

  1. 首先你的模型必须是一个整体,比如你的模型是熊猫吃竹子,如果你的熊猫和竹子要一块导出,那么你的熊猫和竹子必须是一个整体
  2. 贴图只能有一张,且贴图是png格式
  3. 给bone(骨骼)认真命名,js导出后你可能会发现骨骼有点偏移与错位,严格的命名有助于你在建模或者导出的时候进行修改,不过对开发来说这点会比较麻烦,这点也不是必须的。
  4. 模型的每一个点都必须赋予权重,如果发生破面行为,那么非常有可能是加了动作的模型却有的店没有权重
  5. 骨骼测试可用的有bone和CS骨骼,如果采用其他骨骼最好进行测试
  6. 导出的时候你的模型必须是一个Mesh,非常重要!这就意味着你不能导出一个可编辑多边形或者其他形式,在我们添加skin修改器的时候,先添加一个EditMesh修改器在我们的物体上,如果你已经是一个editable mesh,那这就不需要了。最好再使用Unwrap, UVW,中途出现warning点确定就好。

导出的时候选择模型就好,不要选择骨骼,如果把骨骼一起选择导出会出现如下错误

添加一个XForm修改器于你的模型当你开始导出之前,他会重置你物件的位置,转向等等,将它变为初始那样,最小化在导出时可能遇到的问题

  1. 如果发生错误,修复完毕后需要重新启动3dmax才能正常使用导出插件
  2. 可以先验证模型导出的数据量和点格式的正确与否再进行加载,一般导出文件的贴图地址会与你的地址不同,需要打开导出文件(如下图)修改贴图对应地址

  1. 加载过程中你有可能看不见模型,那么很有可能是你的模型过大或者过小,可以直接在代码中用scale函数进行调整测试
  2. 如果还有问题,建议在重复以上几点查看一遍

代码中如何加载动态模型

在程序中主要是这几个步骤

下面是代码的部分节选,其实官方的教程例子写的很完整,之后把一个完整可运行的实例传在GIt上~

/**
* @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

从3dMax导出供threeJS使用的带动作模型与加载的更多相关文章

  1. visual studio 2010 自带reporting报表本地加载的使用

    原文:visual studio 2010 自带reporting报表本地加载的使用 在这家公司时间不长,接触都是之前没玩过的东东,先是工作流引擎和各种邮件短信的审核信息,后又是部署reporting ...

  2. Python+selenium 自动化-启用带插件的chrome浏览器,调用浏览器带插件,浏览器加载配置信息。

    Python+selenium 自动化-启用带插件的chrome浏览器,调用浏览器带插件,浏览器加载配置信息.   本文链接:https://blog.csdn.net/qq_38161040/art ...

  3. winform 数据库资料导出Excel方法(适用于资料数据较多加载慢,不用呈现至DatagridView)

    Private Sub savefile(ByVal dgv2 As DataTable) Dim app As Object = CreateObject("Excel.Applicati ...

  4. java中带继承类的加载顺序详解及实战

    一.背景: 在面试中,在java基础方面,类的加载顺序经常被问及,很多时候我们是搞不清楚到底类的加载顺序是怎么样的,那么今天我们就来看看带有继承的类的加载顺序到底是怎么一回事?在此记下也方便以后复习巩 ...

  5. VS2015开发Android,自带模拟器无法调试、加载程序,算是坑吗

    VS2015出来后,确定变化很大,什么android.ios的,不在话下.对于我这样传统型的人,也第一时间试用了一下(vs2003->vs2008->vs2012->vs2015). ...

  6. 3dmax导出到blend或者vs中

    使用3dmax将模型导成obj格式的时候,可以导出材质或者不导出. 1.如果不导出,则按下图不勾选导出材质和创建材质库选项.这样生成的obj是可以直接再blend或者vs中打开的. 2.如果导出,不仅 ...

  7. Java 用Freemarker完美导出word文档(带图片)

    Java  用Freemarker完美导出word文档(带图片) 前言 最近在项目中,因客户要求,将页面内容(如合同协议)导出成word,在网上翻了好多,感觉太乱了,不过最后还是较好解决了这个问题. ...

  8. 【Java】用Freemarker完美导出word文档(带图片)

    Java  用Freemarker完美导出word文档(带图片) 前言 最近在项目中,因客户要求,将页面内容(如合同协议)导出成word,在网上翻了好多,感觉太乱了,不过最后还是较好解决了这个问题. ...

  9. 使用three.js加载3dmax资源,以及实现场景中的阴影效果

    使用three.js可以方便的让我们在网页中做出各种不同的3D效果.如果希望2D绘图内容,建议使用canvas来进行.但很多小伙伴不清楚到底如何为我们绘制和导入的图形添加阴影效果,更是不清楚到底如何导 ...

随机推荐

  1. SpringBoot怎么自动部署到内置的Tomcat的?

    先看看SpringBoot的主配置类的main方法: main方法运行了一个run()方法,进去run方法看一下: /** * 静态帮助程序,可用于从中运行{@link SpringApplicati ...

  2. JS HEX十六进制与RGB, HSL颜色的相互转换【转载】

    Mark[转载] https://www.zhangxinxu.com/wordpress/2010/03/javascript-hex-rgb-hsl-color-convert/

  3. git 分支的创建与合并

    首先我们需要先创建一个新的dev分支,然后切换到dev分支: $ git checkout -b dev //命令语句 Switched to a new branch 'dev' //成功执行输出语 ...

  4. effective-java学习笔记---使用实例属性替代序数35

    永远不要从枚举的序号中得出与它相关的值; 请将其保存在实例属性中: public enum Ensemble { SOLO(1), DUET(2), TRIO(3), QUARTET(4), QUIN ...

  5. UVA11987 Almost Union-Find 并查集的节点删除

    题意: 第一行给出一个n,m,表示 n个集合,里面的元素为1~n,下面有m种操作,第一个数为 1 时,输入a,b 表示a,b 两个集合合并到一起,第一个数为 2 时,输入a,b表示将 a 从他原来的集 ...

  6. macro

    Hello, 宏定义魔法世界 宏只是在预处理器里进行文本替换,没有类型,不做任何类型检查,编译器可以对相同的字符串进行优化.只保存一份到 .rodata 段.甚至有相同后缀的字符串也可以优化,你可以用 ...

  7. Codeforces #614 div.2 (A-E)

    A  ConneR and the A.R.C. Markland-N #include <bits/stdc++.h> using namespace std; #define ll l ...

  8. SQL 实习

    一. tem表 group by 分组后,有三个编号,找出最下的订单时间,比较选出时间段内的数据.注意group by 和 having的用法. group by 的用法 不用聚合函数的时候,每类出现 ...

  9. 用c#每日更换“必应背景图片”为“桌面壁纸”

    必应每天都会更换背景图片,都非常漂亮,有的时候还十分惊艳,同时还会根据每个地区的特色不同应用不同的图片. 下面用c#抓取必应每天的背景图片,并实现桌面壁纸的每天自动切换 实现思路 1.通过获取&quo ...

  10. 新基建新机遇!100页PPT

    "新基建"是与传统的"铁公基"相对应,结合新一轮科技革命和产业变革特征,面向国家战略需求,为经济社会的创新.协调.绿色.开放.共享发展提供底层支撑的具有乘数效应 ...