前面已经写过一个Hello
EGL的练习程序,手工设计和推算3D坐标是非常累,非常没有效率的,实际上我们应该使用专业的三维建模工具来制作模型。
Maya是我最喜欢的三维制作软件,除了操作界面非常符合我的直觉外,它强大而开放的MEL及SDK也是非常重要的因素。前些日子偶遇一个在好莱坞
混过三维制作的朋友说,最强悍而又符合程序员思维的工具是Houdini,不过还没学习过,目前Maya是我会用的最好的3D制作工具了。可惜曾经3D高
端的代名词SGI把它卖给Autodesk了,这让我心里多少有些郁闷。
Maya内部对3D场景有一个相当优美的描述,由结点连接而成的网络,这个网络可以MEL脚本来访问和控制,当然更可以通过SDK来利用和增强。
由于OpenGL|ES 1.x不支持QUADE,所以在为这类应用转换模型之前,注意先将模型表面三角化:
在MEL中转换模型的要点如下:
- 获取当前选中的物体清单,对每个物体分别进行转换和导出
- string $objs[] = `ls -sl`
- for( $obj in $objs ) { ... }
- 读取一个物体的所有的面
- string $f2v[]=`polyInfo -faceToVertex`
- 注意:这条命令在PSE版本里是不支持的,如果你是在使用这个版本学习建模的话,可能需要找一个有正式版本的朋友帮你导出模型。
- 这条命令的结果包含很多个字符串,每个字符串描述一个面,其内容类似于"FACE 0: 88 64
85",如果是没有三角化的模型,还会多出一个数字来(默认使用四边形)。
- FACE id:后面的数字是形成该面的顶点的索引
- int $faceCount = `size $f2v`
- 对于每一个面的字符串进行分析,读取构成面的顶点索引
- for ( int $i = 0; $i < $faceCount; $i++ )
- string oneFace[]
- tokenize($f2v[$i], $oneFace)
- (int) $oneFace[2,3,4] 就得到了顶点索引 (a,b,c)
- 读取物体所有的顶点
- int vc[] = `polyEvaluate -vertex`
- [0]是vertexCount
- 对于每一个顶点,读取其坐标
- for ( int $i = 0; $i < $faceCount; $i++ )
- string $point = $obj.vtx[$i]
- float v[] = `$pointPosition -l $point`
- ([0], [1], [2])就是(x, y, z)
- 读取法向坐标
- 对于每一个面 (参考2.2)
- 对于面的每一个顶点
- string $v = $obj.vtxFace[$f2v[$i*3 + 0,1,2]][$i]
- $i 是面的索引
- $f2v[$i*3 + 0,1,2] 分别取出第$i个面的三个顶点索引
- $obj.vtxFace[vertex][face]是一个关联数组或者说伪数组
- 比较有意思的是我在Maya联机文档里并没有找到这个vtxFace的说明,在网上倒有些讨论,感兴趣的可以之为关键字google之。
- 选中该顶点
- select -r $v
- 计算其法向
- float n[] = `polyNormalPerVertex -q -xyz`
- 取得的n[0],[1],[2]就是该顶点法向的(x,y,z)
- 恢复最初的选中状态
- select -r $objs;
- 读取UV坐标
- 对于每一个面 (参考2.2)
- 对于面上的每一个顶点 (参考4.2)
- 选中该顶点
- 分析UV坐标
- string u[] = `polyListComponentConversion -fromVertexFace -toUV`
- 如果返回数组长度为0,则未指定UV坐标
- 否则可获取UV坐标
- float uv[] = `polyEditUV -q u[0]`
- [0],[1]就是(u,v)
- 将读取的数据写入文件
- 打开文件 int $fid = `fopen $fname "w"`
- 写入数据 fwrite $fid $data
- 可写入MEL能识别的各种数据类型
- string写入后尾部会跟一个0(BYTE)
- int写入成32位
- float写入成64位,对应C语言里的double
- vector将写入三个float
- 关闭文件 fclose $fid
有经验的程序员都知道合理的代码重用是提高效率的好办法,自己重头写一个对于掌握以上要点是有好处的,但直接找一个现成的脚本来用显然可以节省大量
的时间,要知道,脚本程序的调试可是非常麻烦的。
网上可以找到一个简单易用的(),
作者也把这个脚本发布到highend3d()
了。 使用相当简单,选好要导出的物体,从ScriptEditor里打开这个脚本,在最后写上一行:exportToOgl( "fileName"
); 然后执行即可。我已经写了一个小程序,可以DUMP导出后的文件内容:可执行文件 程序源码(如
果你打算利用这些代码,注意有很多malloc没有free) 。
可以直接修改MEL以输出自己想要的格式,也可以修改程序适应导出格式,不过我觉得两者都太麻烦,还是再写一个转换程序将MEL输出格式转成自己认
为使用较为文件格式比较爽。
阅读(3213) | 评论(0) | 转发(0) |