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个字节包含标题。
- Bytes
0 - 20
:Kaydara FBX Binary \x00
(file - magic,最后有2个空格,然后是一个NULL终止符)。 - Bytes
21 - 22
:[0x1A,0x00]
(未知但所有观察到的文件都显示这些字节)。 - Bytes
23 - 26
:unsigned int,版本号。例如,版本7.3为7300。
在头数据之后,接下来是top-level对象记录。vs Text文本文件格式不同,不会省略 - 写入具有空名称和空属性列表的完整节点记录。
在该记录(递归地包含整个文件信息)之后,存在具有未知内容的页脚。
Node记录格式
命名Node记录具有以下内存布局:
大小(字节) 数据类型 名称 4 UINT32 EndOffset 4 UINT32 NumProperties 4 UINT32 PropertyListLen 1 Uint8 NameLen NameLen char Name ? ? Property [n],n中的n:PropertyListLen Optional ? ? NestedList 13 UINT8 [] 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 记录具有以下内存布局:
大小(字节) 数据类型 名称 1 char TypeCode ? ? 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
更复杂:
大小(字节) 数据类型 名称 4 UINT32 ArrayLength 4 UINT32 Encoding 4 UINT32 CompressedLength ? ? Contents
如果Encoding
为0,则Contents
只是ArrayLength
x ArrayType
。如果Encoding
为1,则Contents
是一个长度为CompressedLength
字节的deflate / zip压缩缓冲区。例如,可以使用zlib对缓冲区进行解码。
忽略Encoding
0,1以外的值。
**iii)**特殊类型
S
:字符串R
:原始二进制数据
这两个都有以下解释:
大小(字节) 数据类型 名称 4 UINT32 Length Length byte/char Data
该字符串不是以0结尾的,并且可能包含\0
字符(这实际上在某些FBX属性中使用)。