汎用的な衝突検知クラス

halo_w22005-03-27

OpenGLの今まで書き散らしたコードを、適当にnamespaceで囲いつつクラス化してみる。こういう作業は楽しいもんですな。なるべく汎用的に使えそうなクラス設計を心がける。

とりあえず衝突検知をクラス化して汎用的に使いまわせるようにしようという企て。衝突検知には、線分と線分、線分と点、線分と平面、点と平面・・・・などなど種類ごとに異なる検知メソッドが必要になるわけだけど、上手くまとめて扱える方法はないもんかな。WEB上のArticleやサンプルコードを漁る。

id:i-saint氏のEmpireTohuのソースを読んでいると面白い衝突検知クラスの実装をハケーン。templateや継承を上手く使っていて綺麗にまとまっている。ほとんどこのまま使いまわせそうなくらい。すごいなあ。

検証用プログラムを書いていて、どうしてもでたらめな結果しか出ない・・・よくよく調べてみると最近手を入れたベクトルの正規化ルーチンがバグってたことが判明。改良したつもりが改悪にしかなっていなかったという罠。 _| ̄|○

状態保存クラスを考える

作ってる最中に思った。あったらいいなこんなクラス。たとえば、ある作業の間だけ特定の機能を有効ないし無効にしておきたい場合がある。

glDisable(GL_LIGHTING);
 // この間だけライティング無効にしたい
glEnable(GL_LIGHTING);

こういう風に書いてるわけだけど、生成時にGL_LIGHTINGの状態を記憶しておいて、デストラクタで状態を復元してくれるクラスがあれば楽だと思った。

{
  GLParamSaver saver(GL_LIGHTING, false); // ライティング無効
  //この間だけライティング無効にしたい
  
} // GLParamSaverデストラクタでライティング状態を復元

という風に書ければ格好いい。
GLParamSaverのコンストラクタでglGet〜でパラメータの状態を保存しておけばよさそうだけれど、パラメータによってglGetBooleanv, glGetIntegerv, glGetFloatv, glGetDoublevと4種類の関数を使い分けないといけない上に、返してくる値も1つとは限らない。
GLBoolParamSaver, GLFloatParamSaverとか型別にクラスを用意しておくのも手だけれど、できれば使う側からはそういう事を意識しないようにしたい。コンストラクタ内でswitch〜caseで判別するのも格好悪いしねえ。難しいもんだ。

追記:glPushAttrib使えばいいだけですたな・・・無駄なことをしたorz