FBX binary file format specification
FBX是一种流行的3D文件格式,最初由Kaydara为MotionBuilder开发,于2006年被Autodesk公司收购。它现在是许多3D工具使用的主要3D交换格式之一。尽管Autodesk为FBX发布了“免费”SDK,但其许可证和软件本身仍然完全关闭。FBX有一个基于文本(ascii)和二进制版本。
由于没有关于二进制FBX格式的公开文档,Blender Foundation要求亚历山大写下他已经弄清楚了什么。我们希望这将导致更好的3D应用程序的互操作性。Blender的下一个版本(2.69)也将支持二进制FBX文件读取。
2013年8月,由Alexander Gessler,Campbell Barton审阅。由Blender Foundation发布,作为公共领域信息。
这是二进制FBX文件格式的不完整规范。
它已经过2011年开始的文件版本测试,但它也适用于早期版本。
本文档仅描述二进制FBX文件的编码,而不是对正在编码的数据的解释。
它应该使您能够将二进制FBX文件转换为ASCII文本格式(或其内存表示形式)。
基于文本的文件结构
对基于文本的格式的了解与本文档相关,因此这里有一个快速的文章。基于文本的FBX文档的核心层次结构块(节点)是
NodeType:SomeProperty0a,SomeProperty0b,…,{ NestedNodeType1:SomeProperty1a,… NestedNodeType2:SomeProperty2a,…,{ ……Sub-scope } …}
换句话说,文档本质上是嵌套的节点列表。每个节点都有…………
NodeType标识符(class类名)与之关联的属性元组tuple,元组tuple元素是通常的原始数据类型POC:float,integer,string等。包含相同格式(递归)节点的列表。
在全局级别,有一个“implicit list隐式列表”(即花括号{},属性列表和名称被省略),并定义了一些标准节点。这些标准项中的每一项仅包含嵌套列表,因此文件可能如下所示
FBXHeaderExtension:{…}GlobalSettings: {…}Documents:{…}Definitions:{…}Connections:{…}…
应用程序必须解析这些内容才能访问FBX几何体。
Binary 二进制文件结构
前27个字节包含标题。
Bytes0 – 20:Kaydara FBX Binary \x00(file – magic,最后有2个空格,然后是一个NULL终止符)。Bytes21 – 22:[0x1A,0x00](未知但所有观察到的文件都显示这些字节)。Bytes23 – 26:unsigned int,版本号。例如,版本7.3为7300。
在头数据之后,接下来是top-level对象记录。vs Text文本文件格式不同,不会省略 – 写入具有空名称和空属性列表的完整节点记录。
在该记录(递归地包含整个文件信息)之后,存在具有未知内容的页脚。
Node记录格式
命名Node记录具有以下内存布局:
大小(字节)数据类型名称4UINT32EndOffset4UINT32NumProperties4UINT32PropertyListLen1Uint8NameLenNameLencharName??Property [n],n中的n:PropertyListLenOptional??NestedList13UINT8 []NULL记录
解释如下…
EndOffset是从文件开头到节点记录结尾的距离(即接下来的任何内容的第一个字节)。这可以用于轻松跳过未知或不需要的记录。NumProperties是与节点关联的值元组tuple中的属性数。作为最后一个元素的嵌套列表不计为属性。PropertyListLen是属性列表的长度。这是存储NumProperties属性所需的大小,这取决于属性的数据类型。NameLen是对象名称的长度,以字符为单位。唯一情况是当值为0代表列表顶级top-level。Name是对象的名称。没有零终止 \0。Property [n]是第n个属性。有关格式,请参阅 property 记录格式部分。属性按顺序连续写入,没有间隔。NestedList是嵌套列表,保留NULL表示- 最后的记录。
读取包含属性的Node节点记录非常简单。要确定是否存在嵌套列表条目,请检查是否有剩余字节,直到达到EndOffset。如果是这样,则直接在最后一个属性之后递归读取对象记录。在该对象记录后面,有13个零字节,然后应该与EndOffset匹配。(注意:为什么需要NULL条目并不完全清楚。这强烈暗示了本文档作者所不知道的某些FBX细微或格式特征…………)
Property记录格式
Property 记录具有以下内存布局:
大小(字节)数据类型名称1charTypeCode??Data
其中TypeCode可以是以下字符代码之一,它们按需要类似处理的组排序。
**i)**原始类型
Y:2字节符号整数C:1位布尔值(1:真,0:假)编码为1字节值的LSB(最低有效位)。I:4字节签名整数F:4字节单精度IEEE 754 numberD:8字节双精度IEEE 754 numberL:8字节符号整数
对于原始标量类型,记录中的数据正是值的二进制表示,以little-endian(所有数字的低位组放在最前面)字节顺序排列。
**ii)**数组类型
f:4字节单精度IEEE 754数字的数组d:8字节双精度IEEE 754数字的数组l:8字节有符号整数的数组i:4字节有符号整数的数组b:1字节布尔值的数组(总是0或1)
对于数组类型,Data更复杂:
大小(字节)数据类型名称4UINT32ArrayLength4UINT32Encoding4UINT32CompressedLength??Contents
如果Encoding为0,则Contents只是ArrayLength x ArrayType。如果Encoding为1,则Contents是一个长度为CompressedLength字节的deflate / zip压缩缓冲区。例如,可以使用zlib对缓冲区进行解码。
忽略Encoding 0,1以外的值。
**iii)**特殊类型
S:字符串R:原始二进制数据
这两个都有以下解释:
大小(字节)数据类型名称4UINT32LengthLengthbyte/charData
该字符串不是以0结尾的,并且可能包含\0字符(这实际上在某些FBX属性中使用)。