2012年

11月

28日

FBXを読み込こんで描画したかっただけ

以前から自作レンダリングソフトで対応するべきか迷っていたfbxファイル。

 

「Colladaフォーマットが扱えるから別に良いかな~?」とか思ってずっと触りませんでしたが、最近になって気が変わりやってみようと思い立ちました。

 

今回はC#環境でfbxモデルフォーマットを使えるようにするために色々とやってみます。

 

項目:

FBXファイルとは?

結構歴史の古いファイル形式のようです。ここでは簡単にまとめておきます。

英語ですがwikipediaにも載っています。詳しく知りたい方はコチラからどうぞ。http://en.wikipedia.org/wiki/FBX

FBXでgoogle検索

 

FBXフォ-マットはAutodesk社が所有しているクロスプラットフォームのファイル形式です。ゲーム業界でも使用されているファイル形式で、有名どころの3Dソフト「Maya」や「Softimage(XSI)」では必ずサポートされているフォーマットです(同じAutodesk社の製品だから当たり前だけど)。ゲームライブラリ「XNA」、「Unity」でも標準サポートされています。

 

FBXファイルを入出力できるSDKがAutodesk社からリリースされていて、無償で入手できます。環境構築も簡単です。定期的に更新されサポートもそれなりに充実しているので、Xファイルに代わりよく利用されているフォーマットです。

 

おそらくColladaやMMDと並び(業界の人はMMDは使わないだろうけど)、現在最も広く使用されているフォーマットの一つでしょう。

 

でも私はColladaを愛用してますけどね。というのも、昔SDK等を使わずにColladaかFBXの自作ローダを作ろうとした際、FBXの中身を見た瞬間に迷わずFBXを諦めてColladaを選択しました。Colladaの分かりやすいXML形式とは違い、FBXフォーマットは作りが難解なのです。

 

どちらか一方のフォーマットさえ使えれば大丈夫かと思ってたのですが、先日、私の環境だとCollada→FBXへの変換は出来るのにFBX→Colladaへの変換が出来ないことに気づきました。BlenderだとFBX読み込みが出来ず、Softimage Mod Toolだとアニメーション付きFBXの出力方法が分からず、以下で紹介してるFBX Converterだと出力されたColladaファイルが壊れている等等・・・・・・

 

まぁこのように、両方のフォーマットをサポートしているソフトもあれば片方だけサポートしてるソフトもあるので、ColladaとFBX両方使えるに越した事はないでしょう。それぞれに利点・欠点がありますし。

 

ちなみにFBX周りのサポートは力が入っているらしく、Autodesk社からはFBXに関する様々なソフトが無償で提供されています。以下に一部紹介。

 

・FBX QuickTime Viewer

FBXファイルをQuickTimeで読み込み、表示するプラグイン。

アニメーション付きFBXにも対応。

 

・FBX Converter

FBXファイルと他フォーマットを相互変換するためのソフト。

対応フォーマット:.fbx、.dae、.3ds、.obj、.dxf

FBXの環境を整える

まずは「FBX SDK」を用意します。コチラのサイトからダウンロード。

 

 

今回はWindowsの「FBX SDK 2013 VS 2010」を使用しました。

Pythonコード用のSDKも存在するらしいです。コチラも気になる・・・

 

ダウンロードしたexeファイルを実行するとインストールが始まります。手順通りに進めればとくに問題もなくインストールは終了です。

 

 

次にVC++2010のプロジェクト設定。

(x86PCで、FBX SDKをデフォルトディレクトリにインストールした場合)

 

●追加のインクルードディレクトリ

C:\Program Files\Autodesk\FBX\FBX SDK\2013.3\include

 

●追加のライブラリディレクトリ

C:\Program Files\Autodesk\FBX\FBX SDK\2013.3\lib\vs2010\x86


●追加の依存ファイル

プロジェクトのランタイムライブラリ設定によって使用すべき.libファイルが異なります。

 

・マルチスレッド デバッグ DLL(/MDd) → fbxsdk-2013.3-mdd.lib

・マルチスレッド デバッグ(/MTd) → fbxsdk-2013.3-mtd.lib
・マルチスレッド DLL(/MD) → fbxsdk-2013.3-md.lib

・マルチスレッド(/MT) → fbxsdk-2013.3-mt.lib

 

これらをプロジェクトに追加すれば環境設定終了です。

 

・参考にさせていただいたサイト

Autodesk FBX SDK インストールメモ

まずはC++で読み込んでみる

コチラのサイトを参考にさせていただきました。結構有名なところである。

ゲームつくろー! FBX習得編

 

少々情報は古いけど、殆ど仕様が変わってないので問題ない。

まずはファイルを読み込むまでの簡単なコードを。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <stdio.h>
#include <fbxsdk.h>

void GetMesh(FbxNode* node)
{
    // メッシュ
    FbxMesh* mesh = node->GetMesh();

    if(NULL != mesh)
        printf("\nMesh=%s Node=%s", mesh->GetName(), node->GetName());

    // 子ノード
    for(int i = 0; i < node->GetChildCount(); i++)
        GetMesh(node->GetChild(i));
}

int main()
{
    // FBXを管理するクラス コレを作らないと始まらない
    FbxManager* manager = FbxManager::Create();

    // FBXファイルのインポータを作成(第二引数は名前 適当なものでいい)
    FbxImporter* importer = FbxImporter::Create(manager, "Importer");

    // シーンクラスを作成
    FbxScene* scene = FbxScene::Create(manager, "Scene");
    
    // FBXファイルを読み込む
    const char* filename = "読み込みたいFBXファイルの名前";
    importer->Initialize(filename);

    // 読み込んだFBXファイルからシーンデータを取り出す
    importer->Import(scene);

    // ルートフレームの名前を表示
    printf("Root=%s", scene->GetRootNode()->GetName());

    // メッシュ探索
    GetMesh(scene->GetRootNode());
    
    // FBX開放処理
    manager->Destroy();

    return 0;
}

このように、簡単に読み込むことが出来ます。

メッシュから座標・ポリゴンデータを抽出するのも簡単です。法線・UV座標はちょっと面倒。

 

FBXの開放処理は、管理クラス「FbxManager」のDestroyメソッドを呼ぶだけで全ての開放処理を行ってくれます。昔のFBX SDKはメモリリークが発生してたらしいですが、このバージョンでは発生しませんでした。不具合も修正されているようです。

 

一日使って何とかモデルを描画するところまで出来た。描画にはOpenGLを使いました。

モデルはMMDfromColladaでpmd→collada、Blenderでcollada→fbx変換して用意しました。

 

こんな感じ↓

 

でもまだ完全にFBXモデルに対応できているわけではなく、他のモデルでやるとこうなった。

 

本来はこういうモデルです。

原因は分かってますけどね。

 

座標、法線、UV座標はそれぞれ独立してFbxMeshというクラスにあり、座標と法線はVector4配列、UV座標はVector2配列で取得できます。

 

最初に読み込んだ初音ミクモデルは頂点数が9,331個で、座標・法線・UV座標の配列もそれぞれ9,331個の要素数だったのできれいに読み込めましたが、モデルによってはこの3つの配列の要素数はバラバラになることもあるようです。

 

2つ目のモデルが正にそれで、モデルを確認したところ座標は11,433個、法線は67,521個、UV座標は13,079個でした。

 

調べてみるとインデックス配列にも色々種類があり、頂点インデックス配列の他に法線のインデックス配列・UV座標のインデックス配列もありました。これらの頂点ストリームを組み合わせて頂点を組み立てないと正しく描画できないみたいです。

 

この辺りはColladaと同じ仕組みなんですけど、面倒だなぁ・・・

Xファイルは読み込んだ時点で座標やら法線やらを自動的に組み立ててくれるんだけど、そこまでの機能は流石にないか・・・・・・

 

まぁ、今回はSDKの使い方を把握するための作業だったので本格的に実装するのはまた今度です。ひとまずSDKの使い方は覚えることが出来ました。

C#でFBXを扱うためには?

ここからが本題。

 

現在私はC#を主に使っているので、FBXをC++だけでなくC#でもやりたいんです。

で、C#環境でFBXを読み込むことが出来るライブラリを調べてみました。

 

・XNA

おなじみMicrosoftが無償提供してるゲームエンジン。FBXフォーマットはサポートされているものの、仕様上FBXファイルをプロジェクトリソースに追加しないと読み取れず、プログラム起動後に外部ファイルを読み込むことは出来ない。

 

・Unity

WindowsやOS Xで動くゲームエンジン。FBX、Colladaといったモデルファイルを読み込むことが出来る。本格的に使ったことが無いのでよく分からないが、どうも仕様がXNAと同じっぽい。外部ファイルを読み込めるかは不明。

 

・fbx2xfile

FBX SDKのラッパーライブラリ。なのだが・・・古い。SDKの仕様が現在のものと異なっていたり、内部でManaged DirectXを使っていたり、とにかく古い。

古くてもいい方は、一応コチラからダウンロードできます。 ソース付き。

 

・ManagedFBX

FBX SDKのラッパーライブラリ。コチラは最新版のSDKに対応している。ソース付き。

VC2010にも対応しているが、SDKの一部のクラスしかラップされていない。

コチラからダウンロードできます。

 

・Fbx.Net

.Net用のFBX SDKのラッパーライブラリ。コチラはdllのみ配布されている。

今のところVC2008でのみ対応しているらしい。VC2010で使いたいところだが・・・

VC2008でいいなら、この中では一番使いやすいライブラリ。

コチラからダウンロードできます。

と、この5つが候補に上がりました。

 

本来なら「Fbx.Net」を使いたいのですが、VC2010で使用できないので諦めて、仕方が無いので今回は「ManagedFBX」を選択しました。

 

ダウンロードすると中に「ManagedFbx」と「ManagedFbx.Samples」の2つのプロジェクトファイルがあります。サンプルはFBXファイルを読み込んで情報を確認することが出来ます。

 

アニメーション関連のラッパークラスが無いのは残念ですが、ソースファイルがあるので参考にしながら自作できそうです。ひとまずはこのライブラリでFBX読み込みをやってみようかと思います。場合によっては一からラッパークラス作るのもアリかも・・・

 

●ラッピングされてるクラス

・FbxManager    → Manager

・FbxScene      → Scene

・FbxNode       → SceneNode

・FbxMesh       → Mesh

・FbxLight       → Light

・FbxNodeAttribute → NodeAttribute

 

※注意

Managerクラスを確認したところ、開放処理が書かれておらずFbxmanager::Destroyメソッドが使われていません。そのまま使用するとメモリリークが発生するので使用する際はManagerクラスに開放処理を書き加えてからご使用ください。

2012/12/01 追記

MikuMikuMoving」というMogg氏が開発しているMikuMikuDanceのクローンソフトがあるのですが、そのソフトのSystemフォルダの中に「FbxLib」という名前のdllを見つけました。

 

FBX SDK のバージョンは2013.02(現在最新版は2013.03)、VC2010にも対応していて、クラスのほとんどがラッピングされているようです。

 

ただ調べてみたところ、FbxLibに関する情報が皆無でした。おそらく同氏が開発したライブラリなのでしょう。使い方等の解説は一切ありませんが、上記で紹介したライブラリの中では一番マトモなライブラリだと思います。