2017年06月02日

独自フォーマットの仕様

仕様の公開はフォーマットが完成してからにしたかったですが、まだ時間がかかりそうなので早めに公開しておきます。
独自フォーマットのBlenderエクスポータが書き出せるデータの種類とその仕様は以下のようになっています。


Mesh
   ・マルチマテリアルの場合はマテリアルで分割したメッシュを書き出す
   ・シェイプキー対応(マルチマテリアルは分割、頂点数の最適化は無し、差分も無理)
   ・TangentSpaceの書き出し対応、UVがあれば無条件で書き出す(手抜き)
   ・UVレイヤーは4つまで
   ・頂点カラーレイヤーも4つまで
   ・四角面以上は全て三角面に変換して書き出す、三角面以外を扱うことはデータ構造上不可能
   ・ウエイトの影響ボーンは5本以上も書き出す、ウエイトの正規化もなし

Animation
   ・Blenderのスキニング行列をDecomposeして書き出す
   ・上によるキーフレームアニメーションに対応
   ・アニメーションクリップの書き出し対応
   ・シェイプキーアニメーションは未実装(実装予定あり
   ・Bake済みデータを書き出すため、EasingやBezierなどのキーフレーム補間情報は扱わない
   ・Armatureには関知せず存在するデータを全て書き出す
 
Armature
   ・IKターゲットなどの制御用ボーンも書き出す
   ・IKのデータは、ArmatureでなくSkeleton属性から書き出す
   ・アニメーションがBake済みのため、IK以外のBoneConstraintには未対応
   ・LeafBone(tail)の座標はSkeleton属性から書き出す(ノードである必要がないため)

Material
   ・Ambinet, Diffuse, Emission, Specularなどを書き出す(Blenderにないデータは0で埋めて書き出す)
   ・未使用のマテリアルを含む全てのデータを書き出す(手抜き
   ・テクスチャスロットは8個まで
   ・固定機能シェーダーには未対応
   ・PBRも未対応

Camera
   ・FoV, Near, Farなどを書き出す
   ・Transformは、Node属性から書き出す

Lamp
   ・Point, Spot, Hemi(Directional扱い)の書き出しに対応
   ・Transformは、Node属性から書き出す

Node
   ・オブジェクト名やTransformなど、オブジェクトの基本情報を書き出す
   ・ノードは、ツリー構造ではなく親と子の名前だけを書き出す
   ・メッシュはマテリアルによる分割の後にノード化される
   ・シェイプキーは暫定でノード扱い、メッシュと同様に分割後のノード化
   ・3DText、Curve、Emptyには未対応(対応予定あり)
   ・Selected or全てのシーンオブジェクトを書き出す(未対応オブジェクトは除外される)

Skeleton
   ・LeafBone座標、CollisionShapeMesh、IK制御データなどを書き出す
   ・Armatureと存在的に似ていますが、あっちはノードだけど、こっちはただのデータという違いもある

Image
   ・Materialのテクスチャスロットに関係なくBlenderが持つ全画像を吐き出す(手抜き
   ・画像データの埋め込みには未対応
   ・よって埋め込み画像を使う(ファイルパスを持たない)データ全般に未対応




細かい部分はだいぶ省略しましたが、こんな感じで作っています。
データのフォーマットはバイナリを採用しています。このバイナリは、Pythonの辞書とC++の列挙型に定義したマップを使って構造化されたデータを扱えるようになっています。これによりバイナリデータへの高速なランダムアクセスが可能になっています。また読めないバイナリを扱う上では文字通り地図としても使えるので、インポータの作成が非常に楽ちんでした。
フォーマットの特徴としては、高度なアニメーション機能のためのデータを扱っていることです。それ以外はFBXやglTFを目指している普通のフォーマットです。といっても仕様はいろいろオカシイですが、そのほとんどはデバッグを簡単にするための仕様です。データが動いたら少しずつ直して行くつもりです。



・進捗

先日、2回目のテストを行いまして、前回失敗に終わったメッシュの描画に成功しました。
続けてUVやマテリアルなどもテストしましたが、これも正常に描画されたことを確認しています。

テストで使用したメッシュの構成は以下のようになっています。

・単一メッシュ(スザンヌ1個
・複数のメッシュ(スザンヌ2〜5個程度
・マルチマテリアルメッシュ(3種類のマテリアルがAssignされたスザンヌ
・単一シェイプキー(スザンヌ1個 * シェイプ1個
・複数のシェイプキー(スザンヌ1個 * シェイプ3個
・複数のメッシュ+複数のシェイプキー(スザンヌ2個 * シェイプ3個
・複数のメッシュ+複数のマテリアル+複数のシェイプキー(スザンヌ3個 * マテリアル3個 * シェイプ3個


主にこういった構成で正常に描画できることを確認しています。ノードのツリー構造が複雑だったり、メッシュがスキニングデータを持ってたりすると描画できないこともありましたが、まあそれは今回のテスト範囲外の不具合で、剛体メッシュ単体(シェイプも剛体扱い)としては成功と見て良さそうな結果でした。

現在はノードからシーングラフを作成する処理のテストを行っていて、ファイルからノードを読み込んでシーングラフを作成し、それを再帰関数で回すという基本的な部分のテストには成功しています。ただ、一部のノードで子ノードの作り方に問題があったため、現在はBlenderエクスポータに戻ってそれの修正をしています。


今回は以上です。次回はアニメーションのテストが終わりしだい進捗を上げる予定です。
では。
posted by gency at 00:20| Comment(0) | 3DProgramming

2017年05月24日

やめるのやめました

2週間ほどプログラミングから離れて遊んでましたが、ぼちぼち作業を再開しています。
前回は独自フォーマットの実装が上手くいかず諦めましたが、5000行のコードを捨てることはやっぱりできなかったので開発を再開することにしました。ただ、前回のデータはいろいろ大変過ぎたので、今回からは仕様をイージーモードに変更しています。

前回テストしたときの独自フォーマットのデータ仕様は、daeやglTFに似たデータを採用していましたが、このデータだとデバッグがかなり大変だったので、データの仕様を変更した上で、C++のインポータで行っている処理の一部をBlenderエクスポータに移すことにしました。これにより作業の多くをBlenderで行えるようになり、デバッグがしやすくなりました。

Blenderのエクスポータでデータをデバッグするメリットは、スクリプトなので起動が高速というのが一番大きいです。他はデータ変換処理の一部をBlenderに用意されている実装に置き換えることで、自作コードをデバッグ対象から除外できることで作業が少し楽になります。
デメリットとしては、ファイルサイズや読み書き時間の増加、データの抽象度の低下等ありますが、まあデメリットを考えてもしょうがないですね。とにかくまずは、100%正しいことが保証されたデータを作ることが先決です。データがないと本当に何もできなくて困るので、多少のことは目を瞑ってとにかくデータの完成を目指したいです。


今回は以上です。あまり作業してないので書くことなかったです。GWからゲームで遊んでて2週間何もしてなくて、その後も風邪で寝込んだりしてたので作業再開したのはつい数日前のことで、まだいろいろと鈍ってる感じです。まぁいい息抜きになったので、これでまたフォーマット開発を頑張れそうです。


posted by gency at 01:44| Comment(0) | 3DProgramming

2017年04月17日

独自フォーマットは無理でした

独自フォーマットを作っていましたが、1ヶ月以上作業してもメッシュひとつ描画できなかったため、久しぶりに心が折れてしまいました。
Blenderからデータを取得してバイナリに書き出すまでは順調に思えたのですが、そのデータを使ってモデルを描画してみたところ、頂点インデックスがズレたような描画結果になっていて、その原因の特定ができずに作業が長期に渡って停滞しまい、モチベが尽きてしまいました。
書き出したデータが間違っていたのか、インポータでやらかしたのか、はたまたエンジンの不具合なのか、原因は結局分からずじまいですが、まあ、この問題が解決したとしても、この先に発生するであろう全ての不具合でこの3つの全てを疑いながら作業するのは重労働過ぎると思ったので、原因を解決する気力も起こらず諦めてしまいました。。

まぁ残念というか悔しい結果に終わってしまいましたが、モデルのエクスポートから描画までを通して作成したことはかなり勉強になったかと思います。今までAssimpに頼りきっていた部分をかなりクリアにできたことは今回の収穫といえると思います。とでも言わないとやってられない気分です(爆
まぁ勉強になったのは事実で、モデルデータ周りのことは本当に知らないことが多かったです。特にVBO対応の頂点属性データを作るのがこれほど難しいことだとは知りませんでした。個人的にはアニメーションよりはるかに難しく思いました。いい勉強になりました。
気力が回復して次にまた独自フォーマットに挑むことがあるなら、そのときは結果が出せそうな気がします。とでも言わないとやってr(ry


というわけで、今回は進捗が全くありませんでした。この1ヶ月で書いたコードは3000行くらいありましたが、すでに全て退場しています。Blenderのエクスポータは1500行の本編と__init__.pyというけっこう本格的なスクリプトを書きましたが、まぁこれはいつか掘り返して使うかもしれないのです。貴重なBlenderPythonの資産として今後に活かせそうな気がします。

ちなみに、独自フォーマットを作ろうとした理由ですが、Assimpがサポートしていない物理剛体やIKなどのデータを調達するためでした。ついでにAssimpも卒業したかったのですが、うん、甘かった。
足りないデータの調達は、それ専用のエクスポータを作成するつもりです。
最初からこうしとけばよかったかも。

今回はこんな感じです。
では。
posted by gency at 03:45| Comment(0) | 3DProgramming