Mesh(网格)文件格式
Unigine引擎支持适用一般网格和骨骼蒙皮的如下两种mesh文件格式:
您也可以使用MeshImport工具将外部格式的mesh文件转换为Unigine支持的mesh格式。
这里给出一些适用任意mesh格式的一般说明。
- 所有数据都是按Little-Endian(低字节序)方式被存储的。
- 【float】是IEEE754标准给出的32位浮点类型。 它的取值范围是从3.4 e-38到3.4 e+38。
- 【int】代表32位有符号二进制补码整型。 它的取值范围是从–2,147,483,648到2,147,483,647。
- 【unsigned short】代表16位无符号整型。 它的取值范围是从0到65,535。
- 【char】代表8位有符号二进制补码整型。 它的取值范围是从-128到127。
- 【unsigned char】代表8位无符号整型。 它的取值范围是从0到255。
- 【string】类型必须以null空字符结尾。 其字符串大小应该包含该结尾null空字符。
- 所有格式都可以存储多个表面。
Compression of Normals(法线的压缩)
在Unigine中是按如下方式将归一化的浮点法线压缩成【unsigned short】格式的:
x = (unsigned short)(clamp((int)((normal.x * 0.5f + 0.5f) * 65535.0f),0,65535));
y = (unsigned short)(clamp((int)((normal.y * 0.5f + 0.5f) * 65535.0f),0,65535));
z = (unsigned short)(clamp((int)((normal.z * 0.5f + 0.5f) * 65535.0f),0,65535));
- normal 代表归一化的浮点法线。
- x, y 和 z 分别代表unsigned short类型的压缩法线。
Decompression of Animation Frames(动画帧的解压缩)
被压缩成【unsigned short】格式的帧的变换和缩放,可以按如下方式实现解压缩:
- 帧变换的解压缩:
在这里:
x = xyz_min.x + xyz_size.x * (compressed_position.x / 65535.0f); y = xyz_min.y + xyz_size.y * (compressed_position.y / 65535.0f); z = xyz_min.z + xyz_size.z * (compressed_position.z / 65535.0f);
- 【xyz_min】代表沿X,Y和Z轴方向上的Bounding Box(包围盒)的最小值点坐标。
- 【xyz_size】代表Bounding Box(包围盒)的大小。
- 【x】,【y】和【z】分别代表unsigned short类型的已压缩的帧变换。
- 帧缩放的解压缩:
在这里:
x = scale_min.x + scale_size.x * (compressed_scale.x / 65535.0f); y = scale_min.y + scale_size.y * (compressed_scale.y / 65535.0f); z = scale_min.z + scale_size.z * (compressed_scale.z / 65535.0f);
- 【scale_min】代表沿X,Y和Z轴方向上的Bounding Box(包围盒)的最小值点坐标。
- 【scale_size】代表Bounding Box(包围盒)的大小。
- 【x】,【y】和z分别代表unsigned short类型的已压缩的帧缩放。
存储一般网格(Meshes)
MESH是存储静态网格和蒙皮几何体的通用文件格式。
骨骼蒙皮有如下两种存储形式:
- 既包含mesh数据(指顶点以及这些顶点的权重)又包含动画(指骨骼以及这些骨骼的变换)。 这种将mesh数据与动画数据存储在同一文件中的方法缺少灵活性,还会占用更多内存。 它通常只用于存储短小的动画序列。
- 只包含mesh数据,也就是Bind Pose(绑定姿势)。 如果您更愿意将附加动画放到单独的文件中,那么这种存储方法会非常有用。
第一幅动画帧不应包含绑定姿势。
MESH 文件格式
- 文件格式标识符(int "ms10" ('m' | ('s' << 8) | ('1' << 16) | ('0' << 24)))
- 整个mesh的包围体积:
- Mesh包围盒(Bounding Box)的最小值点坐标(float[3])
- Mesh包围盒(Bounding Box)的最大值点坐标(float[3])
- Mesh包围球体(Bounding Sphere)的中心(float[3])
- Mesh包围球体(Bounding Sphere)的半径(float)
- Bone(骨骼)的数量(int)
- 每个bone的标头信息:
- Bone名称。 它是以null空字符结尾的【string】类型的字符串,包含有如下信息:
- 包含有null空字符的字符串中的字符数量(int)。
- 指定长度的bone名称(char[length])。
- 父bone。 如果存在没有父bone的根骨骼(root bone),这里就要使用-1参数。(short)
- Bone名称。 它是以null空字符结尾的【string】类型的字符串,包含有如下信息:
- Mesh animation(一般网格动画)的数量(int)
- 每个animation的标头信息:
- Animation名称。 它是以null空字符结尾的【string】类型的字符串,包含有如下信息:
- 包含有null空字符的字符串中的字符数量(int)。
- 指定长度的animation名称(char[length])。
- Animation名称。 它是以null空字符结尾的【string】类型的字符串,包含有如下信息:
- Surface(表面)的数量(int)
- 每个surface的标头信息:
- Surface名称。 它是以null空字符结尾的【string】类型的字符串,包含有如下信息:
- 包含有null空字符的字符串中的字符数量(int)。
- 指定长度的surface名称(char[length])。
- Surface包围盒(Bounding Box)的最小值点坐标 (float[3])
- Surface包围盒(Bounding Box)的最大值点坐标 (float[3])
- Surface包围球体(Bounding Sphere)的中心 (float[3])
- Surface包围球体(Bounding Sphere)的半径 (float)
- Surface变形目标(Morph Target)的数量 (int)
- 每个morph target的标头信息:
- Morph Target名称。 它是以null空字符结尾的【string】类型的字符串,包含有如下信息:
- 包含有null空字符的字符串中的字符数量 (int)。
- 指定长度的morph target名称 (char[length])。
- Morph Target名称。 它是以null空字符结尾的【string】类型的字符串,包含有如下信息:
- Surface名称。 它是以null空字符结尾的【string】类型的字符串,包含有如下信息:
- 文件格式标识符 (int "ms10" ('m' | ('s' << 8) | ('1' << 16) | ('0' << 24)))
- 每个bone包含的信息:
- 沿X,Y,Z轴方向上的bone坐标位置 (float[3])
- Bone旋转四元数 (float[4])
- 沿所有方向上的bone缩放 (float[3])
- 每个animation包含的信息:
- 涉及该animation的bone数量 (int)
- 涉及该animation的bone索引 (short[length])
- Flag(标志位)(unsigned char),每个8位标志位用来决定一般网格动画(Mesh Animations)是否应该对涉及它们本身的bones的平移分量,缩放分量或旋转分量进行存储
- Animation帧(Frame)的数量 (int)
- 每一帧中每个bone的变换数据:
- Flag(标志位)(unsigned char),每个8位标志位用来决定当前帧是否应该存储bone的新平移分量,新缩放分量或新旋转分量。 如果这些分量自上一帧以后就没发生过改变,那么就不需要存储新数据。 这种情况下当前帧反而会使用上一帧中的数据,如此一来内存的使用效率也就大大提高了。
- 如果有数据被标记为发生改变了,那么就要存储bone的每一组新分量,涉及的信息如下:
- 沿X轴方向上的bone平移 (float)
- 沿Y轴方向上的bone平移 (float)
- 沿Z轴方向上的bone平移 (float)
- 旋转四元数 (short[4])
- Bone缩放的X轴分量 (float)
- Bone缩放的Y轴分量 (float)
- Bone缩放的Z轴分量 (float)
-->
- 每个surface包含的geometry(几何)数据:
- Surface的每个morph target(变形目标)上包含的数据:
- Morph target中的顶点数量 (int)
- Morph target的顶点 (float[3*length])
- 切线数量 (int)
- 对每条切线而言:
- 其X,Y和Z轴分量都是【short】类型;W轴分量是【char】类型。
- Surface权重的数量 (int)
- 每个surface权重包含的信息:
- 影响顶点的bone数量(其最大值是4) (unsigned char)
- 影响顶点的每个bone所包含的信息:
- Bone索引 (short)
- Bone权重 (unsigned short)
- 第一UV集中texture(纹理)坐标的数量 (int)
- 每个texture坐标包含的信息:
- 第一UV的texture坐标(float[2])
- N第二UV集中texture坐标的数量 (int)
- 每个texture坐标包含的信息:
- 第二UV的texture坐标 (float[2])
- 8位顶点colors(颜色)的数量 (int)
- 每个color包含的信息:
- Color值 (char[4])
- Coordinate index(坐标索引)的数量 (int)
- 对surface的每个顶点的Coordinate index而言:
- 如果零号morph target包含的坐标顶点数少于256个,那么所有的index都应是【unsigned char[length]】类型
- 如果零号morph target包含的坐标顶点数少于65536个,那么所有的index都应是【short[length]】类型
- 对于其它的情况,所有的index都应是【int[length]】类型
- Triangle index(三角形索引)的数量 (int)
- 对surface的每个顶点的Triangle index而言:
- 如果零号morph target包含的三角形顶点数少于256个,那么所有的index都应是【unsigned char[length]】类型
- 如果零号morph target包含的三角形顶点数少于65536个,那么所有的index都应是【short[length]】类型
- 对于其它的情况,所有的index都应是【int[length]】类型
- 文件格式标识符 (int "ms10" ('m' | ('s' << 8) | ('1' << 16) | ('0' << 24)))
- Surface的每个morph target(变形目标)上包含的数据:
存储骨骼蒙皮动画(Skinned Mesh Animation)
骨骼蒙皮动画(Skinned Mesh Animation)格式只用于存储骨骼蒙皮的MESH文件中的动画数据部分。 不过,如果该种格式的绑定姿势中只包含有顶点以及这些顶点的权重而没有"基本"骨骼蒙皮,那它里面存储的数据也是无用的。
使用ANIM文件存储动画数据会比在一个骨骼蒙皮的MESH文件中既存储网格又存储骨骼变换数据更高效。 这也是为什么ANIM文件最适合存储长动画的原因所在。
如果您需要在脚本中加载这样一个文件,那只需将它当作MESH动画文件来处理即可。
ANIM文件格式
- 文件格式标识符 (int "an10" ('a' | ('n' << 8) | ('1' << 16) | ('0' << 24)))
- 整个animation的包围体积:
- Bounding Box(包围盒)的最小值点坐标 (float[3])
- Bounding Box(包围盒)的最大值点坐标 (float[3])
- Bounding Sphere(包围球体)的中心 (float[3])
- Bounding Sphere(包围球体)的半径 (float)
- Skinned Animation(蒙皮动画)中的bone数量 (int)
- 每个bone的标头信息:
- Bone名称。 它是以null空字符结尾的【string】类型的字符串,包含有如下信息:
- 包含有null空字符的字符串中的字符数量 (int)
- 指定长度的bone名称 (char[length])
- 父bone (short)
- Bone名称。 它是以null空字符结尾的【string】类型的字符串,包含有如下信息:
- Animation的数量 (int)
- 每个animation的标头信息:
- Animation名称。 它是以null空字符结尾的【string】类型的字符串,包含有如下信息:
- 包含有null空字符的字符串中的字符数量 (int)
- 指定长度的animation名称 (char[length])
- Animation名称。 它是以null空字符结尾的【string】类型的字符串,包含有如下信息:
- 文件格式标识符 (int "an10" ('a' | ('n' << 8) | ('1' << 16) | ('0' << 24)))
- 每个bone包含的信息:
- 沿X,Y,Z轴方向上的bone坐标位置 (float[3])
- Bone旋转四元数 (float[4])
- 沿所有方向上的bone缩放 (float[3])
- 每个animation包含的信息:
- Animation bone(动画骨骼)的数量 (int)
- 涉及该animation的bone索引 (short[length])
- 在其内进行动画所用到的那个Bounding Box(包围盒)包含的信息:
- 在其内执行animation bones平移所用到的那个Bounding Box(包围盒)包含的信息:
- 沿X,Y和Z轴方向上的Bounding Box(包围盒)的最小值点坐标 (float[3])
- Bounding Box(包围盒)的大小 (float[3]).
- 在其内执行animation bones缩放所用到的那个Bounding Box(包围盒)包含的信息:
- 沿X,Y和Z轴方向上的Bounding Box(包围盒)的最小值点坐标 (float[3])
- Bounding Box(包围盒)的大小 (float[3]).
- 在其内执行animation bones平移所用到的那个Bounding Box(包围盒)包含的信息:
- Flag(标志位)(unsigned char),每个8位标志位用来决定动画( Animations)是否应该对涉及它们本身的bones的平移分量,缩放分量或旋转分量进行存储
- Animation帧(Frame)的数量 (int)
- 每一帧中每个骨骼的变换数据:
- Flag(标志位)(unsigned char),每个8位标志位用来决定当前帧是否应该存储bone的新平移分量,新缩放分量或新旋转分量。 如果这些分量自上一帧以后就没发生过改变,那么就不需要存储新数据。 这种情况下当前帧反而会使用上一帧中的数据,如此一来内存的使用效率也就大大提高了
- 如果有数据被标记为发生改变了,那么就要存储bone的每一组新分量,涉及的信息如下:
- 沿X轴方向上的bone平移 (unsigned short)
- 沿Y轴方向上的bone平移 (unsigned short)
- 沿Z轴方向上的bone平移 (unsigned short)
- 旋转四元数 (short[4])
- Bone缩放的X轴分量 (unsigned short)
- Bone缩放的Y轴分量 (unsigned short)
- Bone缩放的Z轴分量 (unsigned short)
上述这些位置和旋转都被限定在计算所得的Bounding Box(包围盒)的内部取值:也就是说,它们的坐标值须从该包围盒的最小值点坐标和最大值点坐标之间的范围选择(其取值范围是从0到65535)。
- 文件格式标识符 (int "an10" ('a' | ('n' << 8) | ('1' << 16) | ('0' << 24)))
Last update: 2017-07-03
Help improve this article
Was this article helpful?
(or select a word/phrase and press Ctrl+Enter)