tuedaの日記

2011-05-23

[] TriStripperを試す

この間からトライアングルストリップ化ツールを探している。

NvTriStripとか有名だけどいろいろ調べるとTriStripperが良さそうなので試してみる。

TriStripperの特徴

  • オープンソースかつ多分フリー
  • ランタイムで使えるように速度重視(当然毎フレームストリップ化するわけではない)
  • ジオメトリ構成を変更しない
  • ストリップの集合を作る。何も足さない、何も引かない(ウィスキーのCMであったな...)

アルゴリズム的には未処理のトライアングルの集合から隣接トライアングルが少ない面を選んで伸ばす。

伸ばしたあとにひっくり返して逆方向にも伸ばすのがスタンダードなアルゴリズムだがデフォルトではやらない(オプションで変更可)。

あと複数のストリップを縮退したトライアングルを使って結合することはない(何も足さない、何も引かない)。

キャッシュを考慮して短いストリップを作ることも可能(デフォルトでストリップ長は16)。

トライアングルは必ずCCWで渡し、CCWで帰ってくる。

使い方

こんな感じ。

  // インデックスの指定
    vector<size_t> indices;
    indices.push_back (3);
    indices.push_back (2);
    indices.push_back (0);
  以下略

    // ストリッパーの作成
    tri_stripper stripper (indices);
    stripper.SetCacheSize (0);
    stripper.SetMinStripSize (2);

    // ストリップ化する
    vector<primitive_group> prims;
    stripper.Strip (&prims);

TriStripperの実験

というわけでさっそく試してみた。

適当に作ったダビデの六芒星(13頂点,12トライアングル)をGL_TRIANGLESで書くとこうなる。

f:id:tueda_wolf:20110523214111p:image

これをストリップ化するとストリップ3本とリスト1本(2トライアングル)が帰ってきた。

/*
  0 : Type=5   0, 3, 2, 6, 5, 9, 8
  1 : Type=5   11, 10, 7, 6, 3
  2 : Type=5   6, 10, 9, 12
  3 : Type=4   2, 5, 1, 4, 7, 3
*/

これをGL_TRIANGLE_STRIPで描画するとこうなった。

f:id:tueda_wolf:20110523214109p:image

きちんとストリップ化されているようだ。

TriStripperの少し気にいらないところ

ネーミングセンスがクラス名がtri_stripperでインスタンス名がTriStripperって逆だろ普通。

使うときは名前を書き換えてしまおう。いくら何でもこの命名はひどい。

TriStripperの速度

TriStripperがどれくらいの速度が出るのか、スタンフォードバニー(3万5000頂点、約7万面)をストリップ化して試してみた。

読み込みにはTriMesh2を使っている。

手抜きしてプログラム実行全体をtimeコマンドで測ると、

$ time ./a.out
Reading bunny.obj... Done.
vertex count = 34835
face count = 69666
cache size = 16
strips = 8233
./a.out  0.53s user 0.02s system 98% cpu 0.560 total

全部合わせて0.5秒ぐらい。このうちストリップ化に何ミリ秒使ってるかは知らないけど、十分高速なので全く気にする必要はないだろう。

(追記)SetCacheSize()で大きな値、例えば1000とか指定すると10秒とか極端に遅くなる。

Connection: close