OpenGL Flying View (Win32 MFC)

since 2001/05/18
last modified 2001/06/19

はじめに

このプログラムは、M$派の取り込みのための作業の第三段として用意した よくあるフライトシミュレータ的なカメラの動きを実現するプログラムです。

オイラー角を使った回転処理は、ややこしくてどうしても頭が狂いそうになってしまいます (私の場合だけかもしれませんが)。もっとシンプルに回転処理が出来ないものかと、 つい考えてしまいます。

そこで、色々とWebpageを巡回したところ、次のようなWebpageに遭遇しました (このような分かりやすいWebpageが実在することに、まず感謝)。


ということで、これらのWebpageから学んだことを簡単に言えば"glRotated()"関数の多用には 注意しましょう。"gluLookAt()"関数を使った方が、簡単にフライトシミュレータ的な カメラの動きを実現出来るということでしょうか。

カメラ座標系への視覚変換 "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)べクトルという言葉が出て来ましたが。カメラ座標系を次のように、 直交する三(軸)方向のベクトルで定義しているものと考えて下さい (この辺は向井さんのWebpageの説明がすばらしいです)。
  前向き(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)
これで、カメラ座標系の回転処理は完成です。

サンプルプログラム
OpenGL FlyingView (MS-Windows95/98/NT用,lzh圧縮)
OpenGL FlyingView のソースコード (Win32MFC, lzh圧縮)

このプログラムの3x3行列クラスCMatrix33は、 向井さんのWebpage の"Matrix33.javaのソースリスト"をMFCで使えるように書き直したものです。

この3x3行列クラスCMatrix33を使用することで、簡単にカメラ座標系の回転処理が可能になります (向井さんありがとうございます)。

操作方法は、カーソルでカメラの縦横回転。[PageUp]、[PageDown]キーで前後進。 カメラのロール操作は[q],[e]キーです。

また、[w][s]キーで垂直平行移動、[a][d]キーで水平平行移動します。

後、前回作成した水プログラム"OpenGLwater"の水面、球体、cubeといったオブジェクトを OpenGLフィールド内に浮かべています。もちろん、水面は[スペース]キーで中央をへこませ、 [c]キーにより水面の動きをクリア出来ます。


[Top Pageに戻る]