カメラワーク

ここでは、実践的なカメラワークを実現する方法について扱います。

- 目次 -

カメラワーク

一般的なカメラワークには、以下の2つが挙げられます。

地球儀方式(※)のカメラワーク

最も単純なカメラワークは、ビュー座標系上のワールド座標系を、 マウス操作に伴ってくるくると自転させる方式のものです。 例えるなら地球儀のような方式なので、 こでは地球儀方式(※これは別に一般的な呼称ではありません)と呼びましょう。 この方式は、ある程度小さい立体を、 色々な角度から眺めるような場合に向いています。 これまでに使用してきた、 マウス操作で視点を操作するためのsetGraphics3DEventSource関数でも、 この方式のカメラワークを採用しています。

地球儀方式のカメラワークは非常に簡単に実装できるため (ワールド座標系を、普通に移動させたり回転させたりするだけ)、 ここではあまり深く扱いません。

カメラ移動方式のカメラワーク

もう一つ、地球儀方式と共によく用いられるのが、 ワールド座標系上でカメラを動かすようなカメラワークです。 例えば3Dのアクションゲームなどでは、 主人公の背後から見下ろすような視点で、 主人公が移動するとカメラも後ろから追従していきます。 このようなカメラ移動方式のカメラワークは、 広大な立体を移動しながら眺めるような場合に向いています。

ここでは、このカメラ移動方式のカメラワークを中心に扱います。

ビュー変換

ワールド座標系からビュー座標系への座標変換は、 特別にビュー変換と呼ばれます。 カメラワークを制御する事は、 つまりはこのビュー変換を制御する事です。

座標変換の処理順序

一般に、立体の座標変換順序は

ローカル座標系
  → (ローカル変換) → ローカル座標系
  → (ワールド変換) → ワールド座標系
  → (ビュー変換)→ ビュー座標系

という流れで処理されます。

地球儀方式のビュー変換

地球儀方式のカメラワークの場合は、座標系の配置階層の順序は、 そのまま座標変換処理の順序に一致します。 即ち、ローカル座標系がワールド座標系上に配置されており、 ワールド座標系がビュー座標系上に配置されている(と見なせる)状態です。

そのため、ビュー変換は、 通常のローカル変換やワールド変換と全く変わりません。 従って、カメラワークの制御も通常と変わらず、 ワールド座標系をmoveCoordinate関数で移動させたり、 rotCoordinate関数で回転させたりする事で制御します。

カメラ移動方式のビュー変換

カメラ移動方式のカメラワークでは、 ワールド座標系の上にビュー座標系を配置し、 ビュー座標系を動かすような制御を行う必要があります。 従ってこの場合、ビュー変換において、座標系の配置階層の順序と、 座標変換処理の順序が逆転します。 そのため、ビュー変換は、ローカル変換やワールド変換とは少し異なる、 変換を行う必要が生じます。

しかしVCSSL Graphics3Dでは、このようなカメラ移動方式の ビュー変換を制御するための関数が標準で用意されています。 プログラマは、通常のmoveCoordinate関数やrotCoordinate関数の代わりに、 moveView関数やrotView関数を使うだけで、 通常の座標系操作と全く同じ感覚で、視点の操作を行う事ができます。

視点制御関数の引数についての注意点

これから解説する、視点を制御するための関数は、 1つめの引数が座標系のIDでは無く、 レンダラーのIDとなっています。 この点は混同しないように注意が必要です。

ビュー座標系の移動

ワールド座標系の座標軸を基準とした、 ビュー座標系の移動には、moveView関数を使用します。

- 関数仕様 -

void moveView ( int rendererID, float dx, float dy, float dz )

最初の引数rendererIDでレンダラーのIDを、 続く引数dx、dy、dzでそれぞれX、Y、Z方向のカメラの移動距離を指定します。

ビュー座標系の歩行

ビュー座標系の座標軸を基準とした、 ビュー座標系の動き、 つまりビュー座標系の歩行には、walkView関数を使用します。

- 関数仕様 -

void walkView ( int rendererID, float dx, float dy, float dz )

最初の引数rendererIDでレンダラーのIDを、 続く引数dx、dy、dzでそれぞれ X、Y、Z方向のカメラの移動距離を指定します。

ビュー座標系の回転

ワールド座標系の座標軸を基準とした、 ビュー座標系の回転には、 rotViewX、rotViewY、rotViewZ関数や、rotView関数を使用します。

- 関数仕様 -

void rotViewX ( int rendererID, float angle )
void rotViewY ( int rendererID, float angle )
void rotViewZ ( int rendererID, float angle )

これら3つの関数は、それぞれX、Y、Z軸まわりの回転を行います。 最初の引数rendererIDでレンダラーのIDを、 続く引数dx、dy、dz でそれぞれX、Y、Z方向のカメラの移動距離を指定します。

任意方向の回転軸まわりで回転させるには、rotView関数を使用します。

- 関数仕様 -

void rotView (
  int rendererID, float angle,
  float vx, float vy, float vz
)

最初の引数rendererIDでレンダラーのIDを、 続く引数dx、dy、dzでそれぞれX、Y、Z方向のカメラの移動距離を指定します。 残りの引数( vx, vy, vz )で、 ワールド座標系から見た回転軸の方向ベクトルを指定します。

回転軸の方向と原点位置を指定するには、 rotView関数に引数を追加して使用します。

- 関数仕様 -

void rotView (
  int rendererID, float angle,
  float vx, float vy, float vz,   float px, float py, float pz
)

最初の引数rendererIDでレンダラーのIDを、 続く引数dx、dy、dzでそれぞれX、Y、Z方向のカメラの移動距離を指定します。 残りの引数( vx, vy, vz )と( px, py, pz )で、 ワールド座標系から見た回転軸の方向ベクトルと原点位置ベクトルを指定します。

ビュー座標系の自転

ビュー座標系の座標軸を基準とした、ビュー座標系の回りこみ、 つまりビュー座標系の自転には、 spinViewX、spinViewY、spinViewZ関数や、spinView関数を使用します。

- 関数仕様 -

void spinViewX ( int rendererID, float angle )
void spinViewY ( int rendererID, float angle )
void spinViewZ ( int rendererID, float angle )

これら3つの関数は、それぞれX、Y、Z軸まわりの自転を行います。 最初の引数rendererIDでレンダラーのIDを、 続く引数dx、dy、dzでそれぞれX、Y、Z方向の移動距離を指定します。

任意方向の回転軸まわりで自転させるには、spinView関数を使用します。

- 関数仕様 -

void spinView (
  int rendererID, float angle,
  float vx, float vy, float vz
)

最初の引数rendererIDでレンダラーのIDを、 続く引数dx、dy、dzでそれぞれX、Y、Z方向のカメラの移動距離を指定します。 残りの引数( vx, vy, vz )で、 ワールド座標系から見た自転軸の方向ベクトルを指定します。

自転軸の方向と原点位置を指定するには、 spinView関数に引数を追加して使用します。

- 関数仕様 -

void spinView (
  int rendererID, float angle,
  float vx, float vy, float vz,
  float px, float py, float pz
)

最初の引数rendererIDでレンダラーのIDを、 続く引数dx、dy、dzでそれぞれX、Y、Z方向のカメラの移動距離を指定します。 残りの引数( vx, vy, vz )と( px, py, pz )で、 ワールド座標系から見た自転軸の方向ベクトルと原点位置ベクトルを指定します。

ビュー座標系の位置制御

ワールド座標系の座標軸を基準とした、 ビュー座標系の位置制御(原点位置の指定)には、 setViewLocation関数を使用します。

- 関数仕様 -

void setViewLocation ( int rendererID, float x, float y, float z )

最初の引数rendererIDでレンダラーのIDを、 続く引数x、y、zでそれぞれビュー座標系原点のX、Y、Z座標を指定します。

ビュー座標系の姿勢制御

ワールド座標系を基準とした、 ビュー座標系の姿勢制御(X-Z-Xオイラー角指定)には、 setViewAngle関数を使用します。

- 関数仕様 -

void setViewAngle (
  int rendererID,
  float alpha, float beta, float gamma
)

最初の引数rerndererIDでレンダラーのIDを指定します。 続く引数alphaでZ-X-Z系オイラー角の第一角を、 同様にalphaで第二角を、gammaで第三角を指定します。

プログラム例

実際にビュー座標系を操作し、 3D舞台の中をゲームのように歩いてみましょう。 キー入力のイベントハンドラを作成し、 キーボードの上下左右キーによるビュー座標系の移動を実装します。 以下のように記述し、実行してみてくさい。

Sample.vcssl

このプログラムを実行すると、黒い背景にカラフルな建物が表示されます。 キーボードの上下左右キー入力により、建物の間を歩いて移動する事ができます。

実行結果、舞台を移動するカメラの図
実行結果
カラフルな建物が表示される。キー操作で歩き回る事が可能。