2017年12月16日

マルチプラットフォーム開発はじめました

近況&生存報告です。
最近は、12月5日にMac miniの一番安いやつとSSD&外付けケース合わせて6万ほどで購入しまして、自作エンジンをMacに移植するなどしてました。
Linuxへの移植は2ヶ月前に終わっていて、今現在の開発の拠点もLinuxMintに移行しています。
更新をサボっている間にいろいろな事が一気に進んでしまったので、何から書けばいいやら迷う感じですが、とりあえず移植は大きなトピックだと思ったので、今回はそれだけでもお伝えしたかった感じです。
拙作の自作エンジンは、Windows,Linux,Macの3つOS上で動くようになりました(ご満悦

ただ、残念なことにSDL2のIMEサポートによる日本語入力機能については、OS間で挙動が異なったため移植を保留しています。
Windows版では、以前から日本語入力中に変換候補リストが表示されない問題がありましたが、移植の結果、それがWIndowsの標準IMEで発生する固有の問題だということが分かりました。
LinuxとMacの日本語入力は、基本的にSDL2がIMEのUIを起動してくれて、それが入力処理全般を行ってくれるようでしたが、WIndows用に作った自作の入力機能とIMEがかち合って誤動作を起こしたため、移植はできませんでした。まあ、もとから不具合があったのでそもそも移植対象外という感じでしたが。
日本語入力の修正については、WindowsはIMEを自分で叩かないとダメっぽいですが、LinuxとMacはSDL2のサポートが行き届いてるようなので、Wiki見ながら実装すればそれで済むかと思います。
日本語入力以外の機能については全て無事に移植できています。


開発環境について。
現在テストで使っているOSは以下になります。

Windows10 HomeEdition
LinuxMint Mate
MacOS 10.13

全て64bitOSで、LinuxとMacへの移植は64bit版のみを対象に行いました。
Windows7については、Kabylake世代で新PCを自作したため使えなくなりました。そのためWindows版は10のみテストしています。

最後に、Macに移植した自作エンジンのスクショを貼って終わります。

スクリーンショット 2017-12-16 21.41.04.png

ちなみにですが、このスザンヌの描画には独自フォーマットのモデルデータを使用しています。
独自フォーマットモデルのスクショを貼ったことがなかったので、序でに撮ってみました。
移植が落ち着いたら独自フォーマットも再開したいですね。

では。

posted by gency at 22:10| Comment(0) | 3DProgramming

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