オブジェクトシステム

注意:ここではある程度デモの話,C言語の基礎,WinAPIがわかるという前提で話を進めていきます。
その辺の話からよくわからない方はそういうサイトを回ってからの方が良いと思われます。
あと、VisualC++(以下VC)限定なので他の方にはあまり有効でないかもしれません。



さて、今回はオブジェクトについて進めていきます。
4KBデモではサイズの制限もあり、たくさんのオブジェクトは組み込むことは難しいでしょうが
64KBデモではデモの見栄えをよくするため、コードでつくった幾何的なオブジェクトだけよりも
モデラーで作成したオブジェクトがあるほうがカッコよく見えることも多いのではないでしょうか
しかし、通常のモデリングソフトで作成したオブジェクトを普通にEXEに組み込んでしまうとすぐ64KBに
なってしまうでしょう。そこで、いくつかの工夫が必要となってきます。


●プリミティブ方式
このプリミティブ方式は、いくつかのプリミティブ(直方体や球など)を組み合わせて任意の
オブジェクトをつくる方式です。プリミティブは球や立方体などなので、プログラムですぐに
作ることができるでしょう。あとはそれらを組み合わせて物体をつくるわけですが、意外に
プリミティブだけで、好きなオブジェクトを作るのはしばしば難しいでしょう。
この方式でモデルをつくれば、データとして保存するのはプリミティブを生成するときに必要なパラメータ
さえ保存されてばよいので、たとえば球なら[半径][分割数][中心位置]というデータのみ保存しておけばよいでしょう
立方体なら[横][高さ][幅][中心位置]などを保存しておけばよいでしょう。
これらのデータのみならモデルデータを座標や面を持つよりもサイズは小さくなります。
64KBを多く作るConspiracyのデモ構築システム"a.D.D.i.c.t."ではこのプリミティブの組み合わせで
オブジェクト作るようなシステムになっていますが、この機能だけでカッコイイオブジェクトを
つくるのはかなり大変な作業になりそうです。(a.D.D.i.c.t.のモデリング機能はコレだけではないので
複数の機能を併用してモデリングできるようです。)


●クローン方式
クローン方式とはモデリングしたオブジェクトを複製して空間上に配置することで、
同じようなオブジェクトをいくつも並べるときに効果が得られます。
元のオブジェクトは別にデータとしてもち、IDを割り振っておき、空間に配置するときに
[ID][中心座標][拡大縮小率][回転角度]などをデータとしてもっておけばよいでしょう。
同じ物体を使いまわすこの方式はあんがい使えなさそうですが、拡大縮小と回転の機能を
そなえておけば、案外いろんな場面でつかえます。デモをつくるときに、シンメトリーな
オブジェクトや空間を作ることもしばしばあると思うのでそういうときにはデータ量が
かなり削減できることでしょう。



●プリミティブ加工方式
コレはAND氏がやっている方法ですが、有名なモデリングソフトの3d maxで物体を作成すると
その作成手順が全部記録されているわけですが、基本的な手順はBOXなどのプリミティブを
面分割して、それを加工していきます。その加工手順を記録しておいて、デモプログラム側で
その加工を再現して、任意の物体を作る方法です。Farbrauschのwerkkzeugでも自前で同様の
システムを構築しています。またConspiracyのa.D.D.i.c.t.ではテクスチャをディスプレースメント
マップとして分割したプリミティブの頂点を動かすなど、かなりいろいろな方法で加工する方法が
考えれられています。



●結局・・・
結局のところ他人の作り上げたシステムを同様に作り上げても面白くないと思うので
やっぱりソフトシンセと同様、自分オリジナルのシステムを作りたいところであります。
かといっても、何もない状態ではどうしようもないので、基本的な方針は上にあげた
方式で進んでいくのがよいでしょう。とくにクローン方式は絶対にはずせないものでしょう。
ほとんどのいくつかのオブジェクトをもっている64KBでは、上であげたいくつかの方式を
組み合わせて使っているのがほとんどです。



●細かいテク
さて、大まかなデータ構成には触れましたが、それを実践するだけではやはり限界があるので
ちょっと細かいテクに触れていきたいと思います。実際に作るときは上の手法を参考にして
以下のようなテクを織り交ぜていけば、そこそこのデータサイズにはなると思います。

○doubleじゃなくてfloat
これは、ソフトシンセのところでも何気なく使ってきましたが、基本的に64KB/4KBではdoubleは
使いません。コレはたいていdoubleが64bitでありfloatが32bitなので、プログラム的にもデータ的にも
小さくなるからです。プログラム中に直接データを書くときは
1.2345678 と書くとdouble(8バイト)
1.2345678fと書くとfloat (4バイト)
となります。1つでは小さな差ですが、オブジェクトの頂点データなどたくさんのものに適応すれば
結構大きな効果となります。
実際にEXEに組み込むときは

float vertex[] = {1.234f, 2.345f, 3.456f, 7.890f, ・・・};

という感じでデータを作成すればよいでしょう。
モデラーで作成したデータをC言語のデータとして使えるようにコンバータを作るのもよいでしょう。


○Half-Float
これは上の発展系です。名前は私が勝手になずけたので一般的ではないです。
doubleは8バイトでfloatが4バイトだったのですが、これは両者に浮動小数点の精度の違いですね
doubleのほうがfloatよりも有効数字が多いわけです。それぞれにどれくらいの有効数字があるかというと
double型 -1.79769*10308〜1.79769*10308で、精度は15桁
float 型 -3.40282*1038〜3.40282*1038で、精度は6桁
らしいです。
しかし、デモのオブジェクトデータとして6桁も有効数字が必要かといわれると
かなり細かいモデリングをするなら別ですが、3桁か4桁くらいあれば足りそうなところです
そこで、floatの精度(4バイト)をさらに半分(2バイト)にしてしまいます。
double----- 1.23456789 をそれぞれの型に変換すると
float------ 1.234568
Half-Float- 1.234375
となります。
Half-Floatの精度は4桁くらいですが、それほど細かいモデルをつくらなければこの程度の精度で済みます。
このHalf-Floatならデータサイズはfloatの4バイトのさらに半分の2バイトですみます。
4KBのモデルデータがあるとるするなら2KBですむというわけです。
この方法でデータを作成すると 1.2345fというような記述はできないのでバイナリで保存しておく必要が
あります。プログラムに組み込むときは

char* data = {0x01, 0x21, 0x63, 0xA1, 0xB1, 0x57, 0x35, ・・・};

という感じで入れておくとよいでしょう。
作成方法としては、まず、データをバイナリモードでファイルを作成し、
そのファイルをCで使えるようにコンバートするのがよいでしょう。



○1byte-Angle
回転・傾きなどの角度も保存する必要がでてきますが、これらもfloatやHalf-Floatで保存できますが
そこまでの精度が必要ない場合がほとんどです。1回転が360度でモデリングするときに1度や2度ちがうだけで
そこまで見栄えは変わらないでしょう。そこでさらにバイトを削って1バイトにしてしまいます。
1バイトは0〜255の整数です。これはunsigned charの場合ですが、charにすると-128〜127になりますね。
そこで回転角度を-180〜180を-128〜128におきかえます。128はありませんが、どうせ-180と180は同じなので
なくても問題ありません。
しかも、この1バイトは都合がよく、char型の変数の127に1を足すと-128になりますね。
これは角度の性質とよく似ていますね。
まぁもしもっと角度の精度が必要であるなら、ビット数をふやしてください。
この360を256で置き換えたとしても精度は約1.4度ですからとくにモデリングに大きな影響がでるものでは
ありません。KObjectModelerでは、この方法を使用していますが、たしかに細かな角度調整はできませんが
それでサイズが半分になるのなら、悪くない選択だと思います。



●まとめ
とりあえず、オブジェクトシステムについてはコレくらいですね
他にもいくつかありますが、他は個人の創意工夫でってことで・・・。
まぁ個人的経験では、ソフトシンセでも同じですがフォーマットがどうこうよりも
その考えたフォーマットやシステムをいかに既存の方法に適応させるかのほうが
重要だと思います。たとえば、ここまでに小さいサイズでのモデルデータの保存
方法のヒントを書いてきましたが、一番重要なのはその理論をつんだモデラーを
つくることです。
すごいフォーマットをつくったとしても、それがメモ帳などでいちいち数値データを
打ち込んでいかないとデータをつくれなかったり、モデリングソフトをつくっても
非常に使いにくいソフトであったりすると、作りたいものが作れません。
作ろうとしているのはデモですから、物ができないとどうしようもありません。
使いやすくて、最適化されたデータを保存できるモデラーを作ってしまえば
あとは、それのデータを描画してやるだけです。


●おまけ
まぁここのソースは特には必要ないと思います。
WORKSのところのToolのKObjectModelerでもみてください。
物体を動かすときに左上の方に出ている数値が保存データです。(わかりやすいですねw とりあえず、自分なりのモデラーをつくってみるのがよいかと思います。
もし、それがいやなら3D maxあたりでエクスポータをかいてデータを吐くのもいいかもしれません。
私はちょっと値段も高いのでどうせならってことで自分で作ってみました。
3D maxはフリー版としてgmaxというのがありますが、全部英語なので少々詰まるかもしれませんねぇ
個人的にモデラーはメタセコイアをつかっているので、なんだか3D maxは慣れないというのが一番の
理由ですが・・・。

ソースの代わりといってはなんですが、上のほうであげた、データファイルをC言語の
配列で表現してEXEに組み込む話を書きましたが、そのとき、コンバータをつくらないと
いけないわけですが、私がつくったんでとりあえず公開しときます。
(まぁこれくらいすぐできるものですが・・・とりあえず、ソースの代わりw)
data2header コンバータをおいときます。



感想・質問・間違い指摘はBBSまで・・・