从3dMax导出供threeJS使用的带动作模型与加载
评论区发现的建议,最近没空测试,先贴这

还有好多人说找不到插件的 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后打开就可以看到这个插件了。(如下图)
如何获取一个可加载模型(以一个简单的圆柱体为例)

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

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

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

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

- 加载过程中你有可能看不见模型,那么很有可能是你的模型过大或者过小,可以直接在代码中用scale函数进行调整测试
- 如果还有问题,建议在重复以上几点查看一遍
代码中如何加载动态模型
在程序中主要是这几个步骤

下面是代码的部分节选,其实官方的教程例子写的很完整,之后把一个完整可运行的实例传在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使用的带动作模型与加载的更多相关文章
- visual studio 2010 自带reporting报表本地加载的使用
原文:visual studio 2010 自带reporting报表本地加载的使用 在这家公司时间不长,接触都是之前没玩过的东东,先是工作流引擎和各种邮件短信的审核信息,后又是部署reporting ...
- Python+selenium 自动化-启用带插件的chrome浏览器,调用浏览器带插件,浏览器加载配置信息。
Python+selenium 自动化-启用带插件的chrome浏览器,调用浏览器带插件,浏览器加载配置信息. 本文链接:https://blog.csdn.net/qq_38161040/art ...
- winform 数据库资料导出Excel方法(适用于资料数据较多加载慢,不用呈现至DatagridView)
Private Sub savefile(ByVal dgv2 As DataTable) Dim app As Object = CreateObject("Excel.Applicati ...
- java中带继承类的加载顺序详解及实战
一.背景: 在面试中,在java基础方面,类的加载顺序经常被问及,很多时候我们是搞不清楚到底类的加载顺序是怎么样的,那么今天我们就来看看带有继承的类的加载顺序到底是怎么一回事?在此记下也方便以后复习巩 ...
- VS2015开发Android,自带模拟器无法调试、加载程序,算是坑吗
VS2015出来后,确定变化很大,什么android.ios的,不在话下.对于我这样传统型的人,也第一时间试用了一下(vs2003->vs2008->vs2012->vs2015). ...
- 3dmax导出到blend或者vs中
使用3dmax将模型导成obj格式的时候,可以导出材质或者不导出. 1.如果不导出,则按下图不勾选导出材质和创建材质库选项.这样生成的obj是可以直接再blend或者vs中打开的. 2.如果导出,不仅 ...
- Java 用Freemarker完美导出word文档(带图片)
Java 用Freemarker完美导出word文档(带图片) 前言 最近在项目中,因客户要求,将页面内容(如合同协议)导出成word,在网上翻了好多,感觉太乱了,不过最后还是较好解决了这个问题. ...
- 【Java】用Freemarker完美导出word文档(带图片)
Java 用Freemarker完美导出word文档(带图片) 前言 最近在项目中,因客户要求,将页面内容(如合同协议)导出成word,在网上翻了好多,感觉太乱了,不过最后还是较好解决了这个问题. ...
- 使用three.js加载3dmax资源,以及实现场景中的阴影效果
使用three.js可以方便的让我们在网页中做出各种不同的3D效果.如果希望2D绘图内容,建议使用canvas来进行.但很多小伙伴不清楚到底如何为我们绘制和导入的图形添加阴影效果,更是不清楚到底如何导 ...
随机推荐
- 【codeforces】Codeforces Round #612 (Div. 2) C. Garland——DP
题目链接 贪心模拟了半天,最后放弃了 题意 给你一串从1−n1-n1−n的序列,其中部分未知(表示为0),补全序列使得相邻数值奇偶性相反的数量最少 相邻数值的奇偶性相反:两个相邻的两个数值,其中一个为 ...
- 死磕Lambda表达式(五):Comparator复合
给岁月以文明,而不是给文明以岁月.--<三体> 在上一篇文章(传送门)中介绍了JDK为我们提供的常用函数式接口,JDK不仅提供的这些函数式接口,其中一些接口还为我们提供了实用的默认方法,这 ...
- [JVM教程与调优] 了解JVM 堆内存溢出以及非堆内存溢出
在上一章中我们介绍了JVM运行时参数以及jstat指令相关内容:[JVM教程与调优] 什么是JVM运行时参数?.下面我们来介绍一下jmap+MAT内存溢出. 首先我们来介绍一下下JVM的内存结构. J ...
- OpenCV-Python 轮廓特征 | 二十二
目标 在本文中,我们将学习 如何找到轮廓的不同特征,例如面积,周长,质心,边界框等. 您将看到大量与轮廓有关的功能. 1. 特征矩 特征矩可以帮助您计算一些特征,例如物体的质心,物体的面积等.请查看特 ...
- c++中的多态机制
目录 1 背景介绍 2 多态介绍 2-1 什么是多态 2-2 多态的分类 2-3 动态多态成立的条件 2-4 静态联编和动态联编 2-5 动态多态的实现原理 2-6 虚析构函数 ...
- ASP.NET Core单文件和多文件上传并保存到服务端
前言: 在我们日常开发中,关于图片,视频,音频,文档等相关文件上传并保存到服务端中是非常常见的一个功能,今天主要是把自己在开发中常用的两种方式记录下来方便一下直接使用,并且希望能够帮助到有需要的同学! ...
- 详谈XSS防御方法
1.HttpOnly 严格的说,httponly并非为了对抗XSS,它解决的是XSS后的Cookie劫持攻击.Cookie设置了httponly之后,JavaScript读不到该cookie的值. ...
- E 比赛评分
时间限制 : - MS 空间限制 : - KB 评测说明 : 1s,128m 问题描述 Lj最近参加一个选秀比赛,有N个评委参加了这次评分,N是奇数.评委编号为1到N.每位评委给Lj的分数是 ...
- 从春节送祝福谈谈 IO 模型(二)
上期结合程序员小猿用温奶器给孩子热奶的故事,把面试中常聊的“同步.异步与阻塞.非阻塞有啥区别”简单进行普及. 不过,恰逢春节即将到来,应个景,不妨就通过实现新春送祝福的需求,深入了解一下 Java I ...
- 查看手机wifi密码
方法一 手机共享wifi,获得二维码,之后解码获得密码. 二维码解吗工具: https://jiema.wwei.cn/ 方法二 手机扫描wifi共享的二维码后,会有提示信息,其中会显示出密码.