阿赵的MaxScript学习笔记分享十二《获取和导出各种数据》
创始人
2024-05-28 20:42:17
0

大家好,我是阿赵,周日的早上继续分享MaxScript学习笔记,这是第十二篇,获取和导出各种数据

1、导出数据的目的

使用3DsMax建立3D模型后,很多时候需要输出模型到别的引擎去使用,常用的格式有Obj、FBX、SLT等。有时候,这些通用的格式里面的数据不够,比如obj里面就没有带顶点颜色。有时候是因为某些格式的解析比较复杂,比如FBX,之类,我们会需要根据自己的需要来导出各种的数据。
一般来说,导出模型数据会包括以下这些:
顶点坐标
UV
UV2
顶点颜色
顶点法线
面的索引信息
蒙皮信息
材质贴图
动画关键帧

首先要明白一个概念,比如一个box,他是由8个顶点、6个四角面组成的。但在导出到引擎使用的时候,其实他是24个点,12个面的,因为游戏引擎绘制的一般是三角面,所以一个四角面会拆分成2个三角面。然后从UV和法线的角度,同一个顶点,有可能是被多个面同时使用的,所以顶点在属于不同的面的时候,顶点的UV坐标和法线方向也是不一样的。
所以,在导出数据的时候,可以使用自己的方式去处理数据。其中一个方法是可以参数obj格式,他把重复的顶点、UV坐标、法线方向进行合并,每个数据有一个索引index,然后在记录面数据的时候,比如一个box有12个面,他会记录12个面的信息,每个面有3个顶点,每个顶点包含了顶点索引、法线索引和uv索引的数据。这样操作下来,存储的数据量最少,也不会丢失任何数据。当然如果想把顶点颜色的数据也加进去,也可以再增加一个顶点颜色的索引,把它带在面的顶点数据里面导出。
下面还是以一个box为思考的参考,列出了获取各种信息的方法,结合着之前讲过的字符串操作方法,和文件读写方法,就可以根据自己的需要取导出自己的模型格式了

2、各种数据的获取方式举例

--获得网格顶点数
GetNumVerts boxt1.mesh
8
--获得某个通道的顶点数据数量,1通道代表UV通道,
--这里我能用1通道,是因为我已经展过UV了,如果没有展过UV,会报错
polyop.getNumMapVerts boxt1 1
24
--获得实际的三角面数
GetNumFaces boxt1.mesh
12
--获得第一个顶点的坐标
getVert boxt1.mesh 1
[-12.5,-12.5,0]
--获得第12个面使用了哪几个顶点,对应网格顶点数的索引
getface boxt1.mesh 12
[3,1,5]
--获得第12个面的法线方向
GetFaceNormal boxt1.mesh 12
[-1,0,0]
--获得第12个面引用的UV索引,对应UV坐标索引
GetTVFace boxt1.mesh 12
[9,10,11]
--获得第9个UV索引点的UV坐标
getTVert boxt1.mesh 9
[0.0005,0.0005,0]

特别说一下法线的获取方式和设置方式

法线的获取和赋值比较特殊一点,需要注意以下几点:

1.如果不通过Edit_Normals修改器来获取,法线的数据是不正确的

box02 = box()
$Box:Box003 @ [0.000000,0.000000,0.000000]converttopoly box02
$Editable_Poly:Box003 @ [0.000000,0.000000,0.000000]faceNum = polyop.getnumfaces box02
6
for i in 1 to faceNum do
(
local faceNormal = polyop.getfacenormal box02 i
print faceNormal
)
[0,0,-1]
[0,0,1]
[0,-1,0]
[1,0,0]
[0,1,0]
[-1,0,0]
OKvertNum = box02.numverts
8
for i in 1 to vertNum do
(local vertNormal = getNormal box02.mesh iprint vertNormal
)
[0,0,-1.5708]
[0,0,-1.5708]
[0,0,-1.5708]
[0,0,-1.5708]
[0,0,1.5708]
[0,0,1.5708]
[0,0,1.5708]
[0,0,1.5708]
OK

通过以上的代码,似乎可以通过polyop来获取某个面的法线方向,然后也可以用点的index通过getNormal的方法来获取到mesh里面某个点的法线方向。
但其实这个获取的方法是有问题的
(1)首先来说这个面的法线,这个面的发现方向,从一个box的4个面的角度看,是正确的,但如果我们通过添加Edit_Normals编辑器,修改其中一个面的法线,然后再次打印6个面的法线方向,会发现结果根本没有变化。所以我个人感觉,这个从polyop里面获取的面法线方向,并不是通过4个顶点的法线方向计算出来的值,只是通过4个顶点的坐标位置,算出来的一个法线方向。如果在不修改顶点法线的情况下,应该是可以用的,但我们谈论的获取法线方向,一般是指顶点的法线方向,所以这个面的法线方向其实没什么意义
(2)再来看通过getNormal方法获得的顶点法线,会发现这个值有点莫名其妙,首先,8个点只有2种法线方向,然后,这个法线也没有归一化,长度并不是1的,所以这个获取的结果,我觉得也是并没有什么用途的。实际上,一个顶点有可能不止一个法线方向的,下面会继续分析。

2.一个顶点具体包含多少个法线,要看具体的平滑组设置

在这里插入图片描述

box03 = box()
$Box:Box003 @ [0.000000,0.000000,0.000000]
converttopoly box03
$Editable_Poly:Box003 @ [0.000000,0.000000,0.000000]
select box03
OK
modPanel.addModToSelection (Edit_Normals()) ui:on
OK

通过一段代码,创建一个box,然后添加了一个Edit_Normals的修改器,这时候我们可以看到场景里面的box每个顶点上面伸出了3条线,这些线,其实就是法线了。由于一个box有8个顶点,所以这个时候,应该有24条法线。
为什么会有24条这么多呢?那是因为这个box每个面的光滑组都不一样,所以面与面之间,是硬转角,而虽然我们看来这个box只有8个顶点,但每个顶点同时被3个面共用,所以一个顶点需要3个法线方向来分别代表组成不同面时,该顶点的法线方向。
在这里插入图片描述

这时候,做一下修改,返回Editable Poly,选择所有面,把它们的光滑组都改成1
在这里插入图片描述

再回到Edit_Normals,这时候,可以看到每个顶点只有1根法线了。这究竟是真的一个顶点变成1根法线,还是由于同一个顶点的法线都重叠在一起了呢?我们可以通过代码去验证一下。

local myVerts = #{1,2,3,4,5,6,7,8}
local myNormals = #{}
local modN = box03.modifiers[1]
modN.ConvertVertexSelection &myVerts&myNormals
print myNormals

这里有一段代码,由于现在box03的第一个修改器就是Edit_Normals,所以modN获取了这个Edit_Normals修改器,然后通过ConvertVertexSelection ,获取指定的myVerts的8个顶点使用到的法线id到myNormals数组
当把box03的光滑组取消的时候,得到的打印结果是:
#{1…24}
当把box03的所有面光滑组设置成1后,得到的打印结果是:
#{1…8}
很明显,在把所有面的光滑组设置成1后,这个box03的法线方向的确是只剩下了8个。于是我们能得出结论,模型的一个顶点具体有多少个法线方向,是根据面的光滑组来分的。或者换个说法,面与面之间是硬边过渡,还是光滑过渡,是看组成面之间的边缘的顶点,是否共用法线。

3.通过Edit_Normals修改器来获取法线数据

通过了上面的实验,我们知道,只有通过Edit_Normals修改器,才能比较准确的获得和修改模型的法线。所以接下来就使用这个修改器来获取数据。
具体的步骤是这样的?
(1)通过ConvertVertexSelection 方法,获取到所有的NormalId
(2)通过GetFaceDegree方法逐个面获取当前的面有多少个不同角度的点组成
(3)通过GetNormalID方法,获得组成每个面每个顶点的对应NormalId
(4)根据1和4的结果,就可以知道每个顶点的发现方向了
具体代码:

local vertNum = box03.numVertslocal myVerts = #{1..vertNum}local myNormals = #{}local modN = box03.modifiers[1]--通过ConvertVertexSelection把所有顶点用到的normalId存到myNormals数组modN.ConvertVertexSelection &myVerts&myNormals--通过GetNormal方法把每一个normalId对应的法线方向,存到normalArr里面local normalArr = #()for i in myNormals do(local norPos = modN.GetNormal inormalArr[i] = norPos)print "法线集合:"print normalArr--获得面的数量local faceNum = modN.GetNumFaces()local faceNormalIdList = #()for i in 1 to faceNum do(--corner的含义可以理解成这个面由多少个不同角度的点组成local corners = modN.GetFaceDegree i--遍历组成面的这些conner,通过GetNormalID方法,获得组成这个面的顶点对应的normalIdlocal tempFaceNormalList = #()for j in 1 to corners do(local norInd = modN.GetNormalID i jappend tempFaceNormalList norInd)faceNormalIdList[i] = tempFaceNormalList)	print "面对应法线Id"print faceNormalIdList

运行的结果:

"法线集合:"
[0,0,-1]
[0,0,-1]
[0,0,-1]
[0,0,-1]
[0,0,1]
[0,0,1]
[0,0,1]
[0,0,1]
[0,-1,0]
[0,-1,0]
[0,-1,0]
[0,-1,0]
[1,0,0]
[1,0,0]
[1,0,0]
[1,0,0]
[0,1,0]
[0,1,0]
[0,1,0]
[0,1,0]
[-1,0,0]
[-1,0,0]
[-1,0,0]
[-1,0,0]
"面对应法线Id"
#(1, 2, 3, 4)
#(5, 6, 7, 8)
#(9, 10, 11, 12)
#(13, 14, 15, 16)
#(17, 18, 19, 20)
#(21, 22, 23, 24)

根据需要,把这些数据保存你的文件里面就可以了。

4.修改法线

顺便提一下怎样修改法线。
之前用GetNormalId可以获取到某个点的NormalId,然后用GetNormal可以获得对应NormalId的具体法线方向值。那么反过来,通过SetNormal方法,就可以改变对应NormalId的点的法线方向了,比如,刚才那个例子,需要把第16个NormalId的值改成[0.5,0.6,0.7],可以这样:

modN.SetNormal 16 [0.5,0.6,0.7]

相关内容

热门资讯

苹果系统安卓爱思助手,系统兼容... 你有没有发现,手机的世界里,苹果系统和安卓系统就像是一对欢喜冤家,总是各有各的粉丝,各有各的拥趸。而...
安卓系统占用很大内存,揭秘内存... 手机里的安卓系统是不是让你感觉内存不够用,就像你的房间堆满了杂物,总是找不到地方放新东西?别急,今天...
安卓系统p30,安卓系统下的摄... 你有没有发现,最近安卓系统P30在手机圈里可是火得一塌糊涂呢!这不,我就来给你好好扒一扒这款手机的那...
siri被安卓系统进入了,智能... 你知道吗?最近科技圈可是炸开了锅,因为一个大家伙——Siri,竟然悄悄地溜进了安卓系统!这可不是什么...
最强挂机系统和安卓区别,揭秘安... 亲爱的读者,你是否曾在游戏中遇到过这样的困扰:一边想要享受游戏带来的乐趣,一边又不想放弃手中的零食或...
安卓系统为什么设系统盘,保障稳... 你有没有想过,为什么安卓系统里会有一个叫做“系统盘”的东西呢?这可不是随便设置的,背后可是有大学问的...
王者怎么加安卓系统的,轻松提升... 你有没有想过,你的手机里那款超酷的王者荣耀,怎么才能让它更好地在你的安卓系统上运行呢?别急,今天就来...
安卓手机系统怎么开热点,共享网... 你有没有想过,当你身处一个没有Wi-Fi信号的地方,而你的安卓手机里却存满了精彩视频和游戏时,是不是...
安卓系统11的平板电脑,性能升... 你有没有发现,最近平板电脑市场又热闹起来了?没错,安卓系统11的新一代平板电脑正在悄悄地走进我们的生...
安卓手机系统创始人,安卓手机系... 你有没有想过,那些陪伴我们每天生活的安卓手机,它们的灵魂是谁赋予的呢?没错,就是那位神秘而又传奇的安...
安卓11系统速度提升,体验再升... 你知道吗?最近安卓系统又升级啦!这次可是直接跳到了安卓11,听说速度提升了不少呢!是不是很心动?那就...
安卓5.1原生系统设置apk,... 你有没有想过,你的安卓手机里那些看似普通的设置,其实隐藏着不少小秘密呢?今天,就让我带你一探究竟,揭...
手机安卓系统玩音游,畅享指尖音... 你有没有发现,现在手机上的游戏种类越来越丰富,尤其是音游,简直让人爱不释手!今天,就让我来给你详细介...
安卓系统与win10,系统融合... 你有没有想过,为什么你的手机里装的是安卓系统,而电脑上却是Windows 10呢?这两种操作系统,就...
苹果系统王者安卓系统可以登吗,... 你有没有想过,为什么苹果系统的手机那么受欢迎,而安卓系统的手机却也能在市场上占有一席之地呢?今天,咱...
安卓系统怎么重制系统还原,安卓... 手机用久了是不是感觉卡得要命,想给它来个大变身?别急,今天就来教你怎么给安卓手机重置系统,让它焕然一...
安卓9系统怎样应用分身,轻松实... 你有没有发现,手机里的APP越来越多,有时候一个APP里还要处理好多任务,分身功能简直就是救星啊!今...
获取安卓系统的ip地址,轻松获... 你有没有想过,你的安卓手机里隐藏着一个神秘的IP地址?没错,就是那个能让你在网络世界里找到自己的小秘...
LG彩电安卓系统升级,畅享智能... 你家的LG彩电是不是最近有点儿“闹别扭”,屏幕上时不时地跳出个升级提示?别急,今天就来给你详细说说这...
阴阳师安卓苹果系统,安卓与苹果... 亲爱的玩家们,你是否曾在深夜里,手握手机,沉浸在阴阳师的神秘世界?今天,就让我带你一起探索这款风靡全...