ノード
本節では FBX バイナリ形式におけるノードの表現を解説する。
ノードのデータ構造の概要については『共通の構造』節の『ノード』の項目を参照。
ひとつのノードの (子要素まで含めた) バイナリ構造は以下の通りである。
内容 | サイズ (FBX 7.4 まで) | サイズ (FBX 7.5 以降) | 補足 |
---|---|---|---|
終端位置 | 4 bytes | 8 bytes | |
属性数 | 4 bytes | 8 bytes | |
全属性の合計バイト長 | 4 bytes | 8 bytes | |
ノード名のバイト長 | 1 byte | 1 byte | |
ノード名 | 可変長 | 可変長 | 指定されたバイト長、特別な終端記号なし |
属性 | 可変長 | 可変長 | 0個以上 |
子ノード | 可変長 | 可変長 | 0個以上 |
ノード終端マーカー | 0 または 13 bytes | 0 または 25 bytes | 特定条件を満たしたとき省略される |
これらをグループ化するならば、以下のようになる。
ヘッダ
終端位置
ノードを表現するバイト列の末尾の位置。 正確には、ファイル先頭のバイトの位置を0として、ノードを表現する末尾のバイト列の次のバイトの位置を用いる。
この情報を用いることで、読む必要のないノードをパースせず読み飛ばすことができる。
このフィールドは FBX 7.4 までで4バイト (u32
型)、 FBX 7.5 以降で8バイト (u64
型) である。
属性数
ノードの属性の数。
このフィールドは FBX 7.4 までで4バイト (u32
型)、 FBX 7.5 以降で8バイト (u64
型) である。
全属性の合計バイト長
ノードの全属性の合計バイト長。 これは FBX データ上で占める長さである。 各属性のヘッダのサイズも長さに含め、圧縮された属性は展開せず圧縮済データのままのサイズを用いる。
このフィールドは FBX 7.4 までで4バイト (u32
型)、 FBX 7.5 以降で8バイト (u64
型) である。
ノード名
ノード名のバイト長
ノード名文字列のバイト長。
ノード名は NUL 終端などの特別なルールを持たず、そのままのバイト列で表現される。
このフィールドは1バイト (u8
型) である。
ノード名文字列
ノード名文字列。
ノード名は NUL 終端などの特別なルールを持たず、そのままのバイト列で表現される。
属性
属性はノードに紐付いた情報である。
属性については『属性』節で解説する。
子ノード
ノードは0個以上の子ノードを持つ。
子ノードについては『共通の構造』節の『ノード』節を参照。
ノード終端マーカー
ひとつのノードのバイナリ表現の終端を示すもので、特定条件下で省略される。
このフィールドは FBX 7.4 までで13バイト (u32
型)、 FBX 7.5 以降で25バイト (u64
型) である。
省略条件
ノード終端マーカーが省略される条件は、「ノードが属性を1つ以上持ち、かつ子ノードを持たない」ことである。
これは FBX テキスト形式において子ノード群を囲むための括弧 {}
が省略される条件と等しい。
長さの意味
13バイトや25バイトという長さは、ちょうどヘッダの長さ (すなわち 4+4+4+1 と 8+8+8+1) と同じである。
このマーカーの存在によって、パーサは (正しいデータならば) 理論上は 終端位置情報を記憶せずともノード階層を正しく把握できる。
ノード終端マーカーは最後の子ノードの直後に続くため、子ノードのヘッダを読もうとして13バイトまたは25バイト読み、その全てが 0x00
であるかを確認することで、ノードが終わるか新たな子ノードが続くかを判別できる。
ただし後述の通り複数の出力処理系に不具合が認められるため、ノード階層の把握を終端位置の記憶・照合なしに試みるべきでない。
省略と処理系のバグ
しかし実際には、 Maya 2015 (および FBX SDK 2015.1) や Blender 2.79 および 2.80 などが、ノード終端マーカーを省略すべき場所で誤って出力したり、逆に出力すべき場所で省略したりしている。 そのため、実用上は終端位置を用いなければノード階層を正確に判断することはできないと考えるべきであろう。
以下に参考情報を挙げる。
- ⚓ T71729 Lack of null record on Properties70 node by FBX Exporter
- Blender 2.79 / 2.80 で出力された FBX ファイルで、本来あるべきノード終端マーカーが欠落しているという報告。
- 属性も子ノードも持たない
Properties70
ノードを出力する際、ノード終端マーカーが存在すべきだが Blender が吐いたデータにそれがなかった。 - 最初に本書の著者のプロジェクトへ報告されたことで発覚した: Unable to import fbx from blender 2.79/2.8 · Issue #2 · lo48576/fbxcel
- https://mastodon.cardina1.red/@loliconductor/103510156295709353
Maya 2015 (FBX SDK/FBX Plugins version 2015.1 build=20140408)
で出力された FBX ファイルで、不要なはずのノード終端マーカーが挿入されている。-
具体的には、トップレベルの Objects ノード以下に子ノードを持たないようなノードがある場合 (典型的には CollectionExclusive (DisplayLayer) とか AnimationLayer ノード) に、余計な NULL record (13バイトの0) が吐かれている
— https://mastodon.cardina1.red/@loliconductor/103510165763794263
-
Objects の子は全てが3つくらい属性を持っているので、子ノードを持たない場合は NULL record が存在してはいけないはずなんだけど、どうやら余計に吐かれている。
ノードヘッダに入っているノード終端位置情報が正しいので普通の処理系はこの情報を無視できるんだけど……— https://mastodon.cardina1.red/@loliconductor/103510174844382235