はじめに |
このプログラムは、M$派の取り込みのための作業の第三段として用意した
よくあるフライトシミュレータ的なカメラの動きを実現するプログラムです。
オイラー角を使った回転処理は、ややこしくてどうしても頭が狂いそうになってしまいます
(私の場合だけかもしれませんが)。もっとシンプルに回転処理が出来ないものかと、
つい考えてしまいます。
そこで、色々とWebpageを巡回したところ、次のようなWebpageに遭遇しました
(このような分かりやすいWebpageが実在することに、まず感謝)。
私がいつもお世話になっている金子さんのWebpageです。"NekoFlight for Java"内で 使用しているテクニックを惜しみなく、丁寧に説明されています。
向井さんのWebpageで三次元世界での回転処理についての丁寧な説明があります。 またJavaアプレットの動作は目から鱗ものです。
現在Cマガジンにて「EnterThe3DProgramming」連載中のでびるまんさんのWebpageです。 "3D Code Tips", "C Magazine Tips"の御蔭で大変大助かりです。でびるまんさんの連載の 御蔭でCマガも買い続けたりしている。
カメラ座標系への視覚変換 "gluLookAt()"関数 |
しかし、前述の説明ではあまりに端折り過ぎですね。カメラを基準とした三方向のべクトルを
使って回転処理をさせようってことなんだけど。
ここで"gluLookAt()"関数について少し説明します。この関数はGLU(OpenGL Utility Library)
の関数群の一つで、カメラ座標系への視覚変換を定義します。
void gluLooKAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble targetx, GLdouble targety, GLdouble targetz, GLdouble upx, GLdouble upy, GLdouble upz) eyex, eyey, eyez: 始点(eye)の位置 targetx, targety, targetz: 目標(target)の位置 upx, upy, upz: 上向き(up)ベクトルの方向このように"gluLookAt()"関数は始点(eye)の位置、目標(target)の位置、上向きベクトルの方向、 といった三種類の引数を必要とします。ここで始点(eye)から目標(target)までの距離が一定値t だとすると、前向き(front)べクトルとの乗算で目標(target)の位置を求めることが出来ます。
前向き(front)べクトル vz=(zx, zy, zz) 上向き(up)べクトル vy=(yx, yy, yz) 右向き(right)べクトル vx=(xx, xy, xx)左手座標系になっていることに気が付きますね。そして、これらのべクトルを 計算しやすいように行列にすると
カメラ行列M 初期状態 |xx, xy, xz| |1.0, 0.0, 0.0| |yx, yy, yz|=|0.0, 1.0, 0.0| |zx, zy, zz| |0.0, 0.0, 1.0|となります。ここまでくると、後は以下の各軸を中心とした回転行列を掛ければOK。
x軸回転行列A |1, 0, 0| M = |0, cos(r), -sin(r)| X M |0, sin(r), cos(r)| y軸回転行列A |cos(r), 0, sin(r)| M = |0, 1, 0| X M |-sin(r), 0, cos(r)| z軸回転行列A |cos(r), -sin(r), 0| M = |sin(r), cos(r), 0| X M | 0, 0, 1|てな要領で最後に、前向き(front)べクトル vz=(zx, zy, zz)と、始点(eye)から目標(target) までの一定距離tから目標(target)の位置を求める。
target(x, y, z) = eye(x, y, z) + vz(zx, zy, zz) * t = ( targetx = eyex + zx * t, targety = eyey + zy * t, tergetz = eyez + zz * t)これで、カメラ座標系の回転処理は完成です。
サンプルプログラム |
このプログラムの3x3行列クラスCMatrix33は、
向井さんのWebpage
の"Matrix33.javaのソースリスト"をMFCで使えるように書き直したものです。
この3x3行列クラスCMatrix33を使用することで、簡単にカメラ座標系の回転処理が可能になります
(向井さんありがとうございます)。
操作方法は、カーソルでカメラの縦横回転。[PageUp]、[PageDown]キーで前後進。
カメラのロール操作は[q],[e]キーです。
また、[w][s]キーで垂直平行移動、[a][d]キーで水平平行移動します。
後、前回作成した水プログラム"OpenGLwater"の水面、球体、cubeといったオブジェクトを
OpenGLフィールド内に浮かべています。もちろん、水面は[スペース]キーで中央をへこませ、
[c]キーにより水面の動きをクリア出来ます。