1
$\begingroup$

I'm currently writing a Java parser for reading FBX binary files and rendering them in OpenGL using the LWJGL (Light-Weight Java Games Library). I have pretty much managed to parse everything thanks to a couple of blog posts by the Blender Foundation, but there is one more challenge remaining. I thought I'd try posting here given that the Blender guys are the only ones who have tried to outline the format in full.

As, hopefully, you already know, the file consists of a series of nodes which are in turn comprised of nested nodes. These nested nodes (you guessed it), also can contain nested nodes.

My question is how do I detected when a nested node belongs to the node above, and isn't a separate nested node? For example:

Node: Objects<br>
Nested Node: Model<br>
Nested Node: Properties60<br>
Nested Node: Property<br>
[Series of data types]<br>
Nested Node: Property<br>
[Series of data types]<br>
Nested Node: [NULL]<br>
Nested Node: [NULL]<br>
End of Objects

In this situation, Model contains within itself another nested node called Properties60, which in turn contains several nested nodes, one for each property. You then have two null Nested Nodes representing the end of that particular node (like a closing bracket I guess).

My question is how do I detect the "opening" bracket? So I know by looking at the above that each "Property" nested node belongs to Properties60 and not to Model, but only because it makes sense to me as a human. How do I automatically detect that? I've tried examining each unicode value for each byte and cannot find a consistent character that is used to denote a change in scope. I've also checked and there doesn't appear to be an end offset value for nested nodes to tell you how big it is like you have with Nodes.

Have I missed something? I would much appreciate any help you can offer as it's the last piece of the puzzle for me :) Without it, I can't reliably tell when, for example, one model definition ends and another begins.

$\endgroup$
1
$\begingroup$

Everything is explained here, in Node Record Format section. Below I’m just rephrasing that document:

  • The first four bytes are an uint32, the total size (in bytes) of the node.
  • The next four bytes are an uint32, the total number of properties.
  • The next four bytes are an uint32, the total size (in bytes) of properties (aka propertieslen).
  • The next byte is a uint8, the total size (in bytes) of the node name (aka namelen).
  • Then you have the node name itself.
  • Then you have the properties.
  • Then you have the nested list of sub-nodes.
  • Then you have the final 13 NULL bytes.

So, you know nested subnodes (if any) start at 4 + 4 + 4 + 1 + <namelen> + <propertieslen> bytes from beginning of current node. This is your “opening bracket”.

If you can “read” python, you can also have a look to our FBX addon code, in particular parse_fbx.py and fbx2json.py, that code is fairly simple and short, and illustrate well how to parse binary FBX.

$\endgroup$
2
  • $\begingroup$ That's odd, I did try reading the first 4 bytes as the length of the nested node but I was getting weird results, and therefore assumed that the rule didn't hold for nested nodes (the same code worked fine for the parent nodes). Maybe at the time I had some issues with the cursor position while working through the nested nodes. I'll try again, thanks. $\endgroup$ – Neoptolemus Mar 4 '15 at 11:18
  • $\begingroup$ Yes, so I tried what you suggested and took the first 4 bytes to be the node length, and I used the Properties60 node as an example. I got some odd results though, Properties60 claimed to be around 5800 bytes large, but the size of each Property nested node added up to far more than that (around 10x bigger!). Also, each Property nested node claimed to be around 1500 bytes big, but with only around 64 bytes of actual property data, so where did the rest go? I'm sure I'm taking the right 4 bytes, as the number of properties, the name and name length are correct and I use the same logic. $\endgroup$ – Neoptolemus Mar 4 '15 at 13:38
0
$\begingroup$

Just a small correction about The first four bytes are an uint32, the total size (in bytes) of the node.

Indeed is the absolute node's end offset e.g. if first int is 128, it means the next node starts at that address It means the whole node, including all nested nodes

In other words start node address contains the address of next node at the same level ADDR VALUE 0017 0128 Node starts here, next node is at 0x0128 00XX NodeData 00XX Inner Node 00XX Inner Node 00XX Inner inner node ... 0128 ZZZZ NExt node address

Hope this is clear and helps

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.