之前在玩directx编程的时候,对于组织3D网格模型数据的文件,我用过几种格式,分别是.x,.obj,.sdkmesh等等,.x文件用得比较多,.obj文件比较简单,.sdkmesh是要用directx SDK里面的工具转化而成的,看SDK文档说推荐用它,因为会比较高效(好久以前看的了,好像是这样)。在这里对.x文件进行分析一下,对于以后使用physX,bullet等做物理模拟碰、撞检测等会有帮助,因为之前看physX SDK里面的sample是对.obj的文件进行解析然后才cook成可以用于检测碰撞的模型的。
1、每个.x文件都是以一个header开头,如下所示。xof代表这是一个.x文件,0302代表.x文件是使用3.2版本的模板,txt代表接下来的.x文件是用text格式存储的,而不是二进制。最后的0032是浮点数的位数是32位。
xof 0302txt 0032
下面是一个模板。模板的名字是Header,可以由数字、字符、下划线组成,但是不能用数字开头。第二行是GUID,第三四五行是数据成员
template Header { <3D82AB43-62DA-11cf-AB39-0020AF71E433> WORD major; WORD minor; DWORD flags; }
模板中有一个部分是用户控制模板的限制程度,一个模板可以是开放的、闭合的或者是受限的。开放的模板的定义在结束部位有一个待展开的方括号
[...]表示它可以包含其他数据类型,封闭模板不能包含其他任何数据结构,受限模板只能包含特定的数据结构。可以看到下面模板的最后一部分是[...]。
template Mesh { <3D82AB44-62DA-11CF-AB39-0020AF71E433> DWORD nVertices; array Vector vertices[nVertices]; DWORD nFaces; array MeshFace faces[nFaces]; [...] }
在.x文件中使用frame来对一个网格模型的不同部分进行组织和管理。框架仅仅是一个外壳,在框架中通常需要包含具体的网格和一个框架变换矩阵,其中框架变换矩阵用于指定该框架包含的部分再整个模型中的初始位置,FrameTransformMatrix是定义框架的本地转换矩阵,是一个4X4的矩阵,共16个浮点数据。框架可以嵌套,即一个宽假可以由许多子框架组成。在.x文件可以看到Frame Frame_SCENE_ROOT,这个为最上层的一个框架。
template Frame { < 3D82AB46-62DA-11CF-AB39-0020AF71E433 > [...] } template FrameTransformMatrix { < F6F23F41-7686-11cf-8F52-0040333594A3 > Matrix4x4 frameMatrix; } template Matrix4x4 { < F6F23F45-7686-11cf-8F52-0040333594A3 > array float matrix[16]; }
2、.x文件广泛用于包含一个mesh信息,一个标准的Mesh模板包含有过多的信息,很多是可选的。
AnimationSet动画的组合,包括一个活多个Animation。
Animation 描述一个动画,包含一个或几个AnimationKey
AnimationKey动画键,定义具体的动作数据,包括一些列旋转、移动、放缩、矩阵变换。
ColorRGB定义RGB对象,包括三个Float的值,分别是R、G、B。
ColorRGBA 定义RGBA对象。包括四个Float的值,分别是R、G、B、alpha。
Coords2d 定义纹理坐标向量,包括两个Float值,分别是u、v。
FloatKeys 定义浮点数组,用来定义动画键数值,包括两个部分:浮点值个数,浮点值列表。
Material 定义材质信息,可以被应用到一个完整的Mesh对象,也可以应用到其中的一个面。包含1.FaceColor环境光 2.Power镜面反射的强度 3.specularcolor镜面反射 等等。
Matrix4X4 定义4X4矩阵,16个浮点数值。
Mesh 定义个Mesh对象,共有9个部分组成:1、包含的顶点数 2、顶点列表,一个顶点包含三个浮点值 3、面数 4、面的顶点索引列表,每个面包含三个顶点 5、MeshFaceWraps 结构,暂时无用 6、MeshTextureCoords 纹理坐标,可选 7、MeshNormals 法向,可选 8、MeshVertexColors 顶点颜色,默认为白色 9、MeshMaterialList 材质,不提供的话默认为白色。
MeshFace 面索引,包含两部分:面数,定点索引构成的面数组。
MeshTextureCoords 定义纹理坐标,包括:纹理坐标的个数,纹理坐标(每个纹理坐标有两个浮点值)。
MeshMaterialList 定义材质的应用,包括:多少个材质被使用,材质影响面的个数,面索引。
MeshNormals 定义Mesh的法向量,包括4部分:nNormals法向量的个数=顶点数,Normals顶点法向量列表,nFaceNormals面的个数,FaceNormals面对应的法向量。
MeshVertexColors 指定顶点的颜色代替原来的材质,包含:顶点数目,颜色索引
TextureFilename 纹理的名称,字符串类型。
VertexDuplicationIndices 保留副本,用于精简Mesh的操作,包含:顶点数,原始顶点数,实际顶点数。
XSkinMeshHeader 描述被导出的SkinMesh相关信息,影响一个顶点的最多变换数目,影响每个面三个顶点的最大变换数目,影响一个顶点的骨骼数。
TimedFloatKeys 时间值,用于Animaterkey中定义时间间隔。
Vector三维向量,三个浮点值。
SkinWeights 定义骨骼影响权重。包括以下几个部分:骨骼的名字,有多少个权重值,顶点的索引列表,相对应的影响顶点索引列表,本地转换矩阵,转换到骨骼空间。