Thursday, September 18, 2008

FBX and XNA Part 1 - FBX Format and Reader

So you have an FBX file and want to read it.

FBX Encoding
FBX files come in two flavors. ASCII and Binary. The ASCII format can be viewed in any text editor. The binary format is more compact. So far we only handle ASCII.

The file is encoded as tagged fields. For example, here is the definitions section of a file...

Definitions: {
Version: 100
Count: 33
ObjectType: "Model" {
Count: 14
ObjectType: "Geometry" {
Count: 3
ObjectType: "Material" {
Count: 1
ObjectType: "Deformer" {
Count: 12
ObjectType: "Pose" {
Count: 3
ObjectType: "GlobalSettings" {
Count: 1

The Definitions: part is a tag, and what follows it is the values. In this case the value of Definitions: is a compound set of values. The tag Version: is followed by a single value, 100.

Some entries have both single values and compound values following a tag.

The Parser
The parser is organized to read the general format of the FBX ASCII file but does not know what any of it means.
The lowest level of the parser is the FbxWordReader class. It knows how to read the next token in the FBX file. The method NextToken does this. There is also a PushBack and SkipWhite.

The next level up is converting tokens into nodes in a tree, representing the hierarchy of the file.
the base class is FbxNode, and it's two subclasses, StringNode, KeyNode and ListNode. The StringNode is a single element that may be a string, integer, or float, or several other types, but at this level is always seen as a string. The ListNode is a set of FbxNodes representing a compound entry. The KeyNode is a key (tag) and then a series of values.
These nodes know how to find sub-nodes (both single sub nodes, and lists of sub nodes.)

The KeyNode knows about the key and it's values, and how to extract a Matrix.

StringNode knows about String, float, int, ulong, time, and char.

The FbxReader is the top level and does the recursive work of parsing the entire FBX file into a tree of nodes.

Now we have the whole FBX file in memory, what does it all mean?

Partial Loads
When we load a model we check to see if there is a subdirectory called Animations. If there is we remove all the takes from the model, and load all the fbx files in Animations and extract their single take. Then we rename the take to match the file name (e.g. Run.fbx get the take named set to Run) and insert it into the main model. This way all our animations are single files in a subdirectory. This is way easier on the modeler. Of course, we have to be careful that all bone names remain the same and such. We do this insertion in the FBX parsed tree before building the model in memory.


1 comment:

Unknown said...


any plan to release the source code of your fbx xna loader ?
or even just a dll/library that could be freely used..