2017年07月10日

進捗が不具合

独自フォーマットの開発の続きになります。
アニメーションが動いたら進捗を上げる予定でしたが、6月中の進捗はほぼなく、7月に入って不具合を二つ修正しただけでした。結局、2ヶ月も遊んでしまって自己嫌悪。

進捗ひとつめはシェイプキーノードの問題修正。
前回のテストでは、シェイプキーを持つメッシュノードを再帰関数で処理できない問題があったのでこれを修正しました。修正は恐ろしく複雑な作業を要するものだったので詳しいことは書けませんが、まあ、大変でした(まる

進捗ふたつめは激遅インポータの修正。
リグなしの摩耶改二モデルを独自フォーマットで書き出して、自作エンジンで読み込んでみたところ、11.2MBあるこのモデルを読み込むのに、デバッグモードで52秒ほど(220KB/s)かかってしまうことが判明しました。
バイナリ版のFBXで書き出した同モデルのデバッグモードでの読み込み時間が、7.2MBで4秒(1843KB/s)なので、1秒あたりの処理速度は約8.3倍も遅れています。ロード時間では13倍の差。
これだけ遅れた原因は、ファイル読み込みに使っているifstreamのread()関数を頂点ごとに呼び出していたからでした。1回呼べばいい関数を60万回くらい呼んでたよ(・・;) 税金対策か。

修正後の読み込み時間は、デバッグモードで約1秒(1042ミリ秒)、リリースモードでは約0.5秒(524ミリ秒)という速度になりました。1秒あたりの処理速度は計算するまでもない感じですね。
デバッグモードの読み込み時間が一転して爆速になりましたが、これはAssimpがインポータで行っている処理を私はエクスポータに実装したのでインポータの仕事が極端に少なくなっているためと思われます。MSVCはデバッグモードだといろいろちょっかい出してきて処理が遅くなりますが、それを回避できているためではと思います。
リリースモードの速度は普通です。Colladaとほとんど同じでした。


進捗は以上です。今回は問題を2ヶ所修正しただけでした。
頑張れば1日でやれなくもない程度の進捗ですね。。だらしねえ。

現在はちょっとだけモデリングをしています。近頃は仕事が忙しくてプログラミングが捗らず遊んでばかりになっているので、これで配管と思い久しぶりにモデリングすることにしました。
作っているのは、GGXrdの某キャラ(まだ秘密)で、今は素体を作っているところです。モチベが微妙なため1日30分くらいしか作業できてないですが、素体はなかなかいい感じになってきています。そろそろ顔作るかというところです。
元ネタも3Dというハードルの高さもあっていろいろ難しそうですが、まぁどうにかして乗り越えたいですね。
とか書いたときに限ってプログラミングが急に捗るっていうパターンもあると思いますが、そのときは悪しからずです。

そんな感じです。
では。
posted by gency at 21:46| Comment(0) | 3DProgramming

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