あけおめ!

というわけで一月ぶりです。らりおです。

コミケ行ってきました。一般参加です。
いや、本当はサークル参加したかったんですけどね。
ゲーム作ってるはずだったのに、いつの間にかライブラリ作ってました
とはいえそれ自体は嘗て幾度となく経験したことなので今更ですが、 何度も進捗が後退するようだとさすがに悲しいので、 ばばーん!とリリースしてしまうことにしました。
今回はそのライブラリと、実装に使った言語の話です。

ライブラリ作った

fbx_direct というライブラリを、 Rust という言語で書きました。

何をするライブラリ?

3DコンテンツのファイルフォーマットであるFBXを読み書きするための、低レイヤーのライブラリです。

FBXはAutodesk社が策定しているフォーマットで、Mayaをはじめ多くのソフトウェアで利用でき、業界標準らしいです (Mayaについては、昨年講習会がありました: Maya講習会 : 東京工業大学 ロボット技術研究会)。

実はFBXというのは構文とデータ構造が結構独立していて、別々に考えることができます (そのおかげで、「ユーザ独自のデータ型をFBXファイルに含める」なんてこともできます)。

同じ3Dコンテンツで喩えるなら、XMLで記述されるCOLLADAのようなもので、 fbx_direct はその場合XMLに該当する部分を扱うライブラリです。

もっと別の喩えをすると、プログラミング言語とアルゴリズムとようなもので、3Dコンテンツをアルゴリズムに喩えれば、 fbx_direct はプログラミング言語のレイヤーを扱うものです。

何故作ったの?

Rust言語でFBXファイルを読むためのライブラリが無かったからです。
正確には、C/C++のassimpというオープンソースのライブラリのバインディング(違う言語で使えるようにしたもの)があったのですが、 作者のgithubアカウントごと消滅していて、当然メンテナンスもされないようだったので、さすがに使うのは躊躇われます。

Autodesk社が公式で FBX SDK というものも開発していて、 C++やPythonでFBXデータを使うのであれば、これを使うのがおそらく最善手です。
しかし、リファレンスを見てみると継承や仮想関数やオーバーロードの嵐で、とてもとてもRustから使う気にはなれませんでした。
さらに、ライブラリの仕様(APIや型名等)もバージョンアップとともに大きく変わるようで、これに追従するのは結構面倒そうです。
おまけに、ライセンスの英語を読むのが面倒で正直やってられません。

要するに、

  • APIが安定しているか追従が楽であり、

  • Rustから使い易く、

  • ついでにオープンソース

そんなライブラリが欲しかったのですが、いかんせんRustはかなり新しい言語なのでそうそう都合の良いものは見付かりません。

無ければ作れ!
そういうわけで作りました。

使うと何がうれしいの?

プロプライエタリなFBXフォーマットを読み書きできる

FBXは非常にメジャーで、ネットで見付けられる有難いフリー素材の多くがFBX形式です。 しかし、FBXはオープンな(仕様が公開されている)フォーマットではないため、自分で読もうと思っても情報がまとまっていなかったり、 古い情報が混じっていたりと、簡単にはいきません。

fbx_direct を使えば、その辺りのことは全部ライブラリでよしなにやってくれるので、 頭をすっからかんにしてXMLと同じようにデータを読めます。

(とはいえ fbx_direct はレイヤー低めのライブラリなので、3Dコンテンツとして利用するにはまだ別の処理が必要ですが……)

Rustで使えるFBX

現時点(2016/01/01)で、Rustでfbxを扱う手段は、 fbx_direct を除けば、C++のライブラリである assimp のバインディングしかないようです。 まあ assimp を使えばいい話ではあるんですが、 assimp はインポート用のライブラリであり、多数のフォーマットに対応していますが、 出力できるフォーマットは意外と少なく 、 FBX特有の情報の操作はおそらくできません。

FBX特有の情報や構造を弄りたい!という場合、今のところ assimp は使えず、 Rustにおいては fbx_direct (或いはそのラッパーライブラリ)一択となります。

オップンソッス

fbx_direct はオープンソース(MITライセンス)です。
コードを読むなり解析するなり、自分のサイトで配布するなり自由にしてください。

「らりおは駄目だ!こんなクソコードを書くやつは部長にできない!」と思ったら、forkして改良するのも自分仕様に改造するのもあなたの自由です。

これからどうするの?

ASCII FBXも読み書きできるようにする (そのうちに、ね)

実はFBXはバイナリ形式だけでなく、ASCII(テキスト)形式も存在します。 ファイルサイズが膨らんだりするし、あまりメリットはないのですが、人間には読み易いです。 (とはいえ慣れればバイナリだって大部分は読めるようになりますが。)

ということで、誰得な気はしますが、未実装のままの機能が残るというのも愉快ではないので、そのうち実装したいものです。
でも私はテキストのパーサを書くのは得意ではないので、誰か実装してくれないものですかね。 せっかくオープンソースなんだし。

FBXの仕様をまとめた文書を作る

FBX SDKについてはそれなりに情報があるのでどうにかなりますが、 FBX形式そのものについては十分にまとまった情報源が少なく、特に日本語では極めて少ない状態です。

そんなわけで、仕様をまとめたドキュメントを作っています。 手前味噌になりますが、既にある程度まとめたものを書いたので、興味のある方は一ヶ月後くらいに読んでみてください: FBX 7.4 フォーマット解説
(今はまだ fbx_direct 周辺のことしかまとめていないので、解釈の部分が編集途中だったりします。)

3Dコンテンツとして解釈するライブラリを書く

先にも書きましたが、まだこのライブラリでやったのはXMLを読んだようなもので、 ゲームで使うには、それを3Dデータとして解釈する部分が残っています。
FBXはモデリングツールに優しい設計になっている一方、単に表示するだけならば、いくらか面倒な前処理をしてやらなければいけません (異なるノードに散っている情報を集めたり、多段階のインデックス参照を行ったり、三角形分割を行ったりなどです)。

というわけで、次に目指すのはやはり画面上に表示するための処理です。

一応、ライブラリ実装以前に雑に書いたコードではそれなりにできていたので、うまいこと抽象化してやれば多分問題なくいけるだろうとは思います。
というか、これが書けないことにはゲーム作る以前の問題なので、どうにかします。

ゲーム作る

らりお「いや、新歓までまだ時間あるぞ!」 (1年ぶり・n回目)

そもそもRustって何さ

Rustはコンパイル型のプログラミング言語です。 オーバーヘッドが小さく、型付けは厳密で、並列プログラミングを前提に作られていて、 標準ライブラリは充実しており、マクロは健全で、ポインタの安全性がコンパイル時に保証される、そんな言語です。

使ってみれば、現代的な言語だけあって、様々な言語の知見がふんだんに盛り込まれているのがわかります。

未だバージョン1.5であり発展途上ではありますが、C++をある程度わかっていれば(鉞投げるんじゃねえぞ!)すぐに馴染むことができるでしょうし、 valgrindやaddress sanitizer、スマートポインタなど様々な道具を用いて戦ってきたdangling pointerという問題をコンパイル時に撲滅できるというのは、 コンパイル時に何でもやってしまいたいC++erにとって、このうえない歓びとなることでしょう。

さいごに

  • 時代はRust!!!C++は古(ここで闇の軍団に殴られて死亡)

  • Autodesk社に圧倒的感謝!

  • 来年から本気出す!!!