サンプル

座標系とカメラ

ここではMascotCapsuleに用いられている座標系とその変換、およびカメラの設定について解説します。


座標系とカメラ

目次


1. 座標系

MascotCapsuleではモデル座標系・ワールド座標系・カメラ座標系・スクリーン座標系の4つの座標系が用いられています。これらの座標系はすべて直交座標系として扱います。

モデル座標系

各3Dモデルごとに用意された座標系です。

ワールド座標系

ワールドの基準となる座標系です。各3Dモデルはワールド座標系上に配置されます。

カメラ座標系

カメラから見たときの座標系です。カメラ座標系で描画される領域はニアクリップ面・ファークリップ面・画角などを定めることによってできる視体積内になります。

スクリーン座標系

ディスプレイに実際に描画されるときの座標系です。カメラ座標系における視体積を1辺の長さが1の立方体に拡大・縮小し、それをスクリーンに投影します。

MascotCapsuleでは、ディスプレイに3Dグラフィックスを表示するために、
モデル座標系→ワールド座標系→カメラ座標系→スクリーン座標系
という3回の座標変換を行います。



2. Transform クラス

Transformクラスは3次元アフィン変換用の4×4行列を保持するクラスです。カメラや3Dオブジェクトの配置や移動はこのクラスを用いて行います。
ここではSample2を用いてTransformクラスを用いたカメラの配置および3Dモデルの操作について解説します。

2.1. カメラの配置

レンダリングされた3Dモデルはワールド座標系上に配置されます。
それらをディスプレイに表示するためにはワールド座標系からカメラ座標系に変換し、そこから、さらにスクリーン座標系に変換する必要があります。そのためにまず、ワールド座標系からカメラ座標系に変換するために、ワールド座標系上にカメラを配置します。
カメラがどのように配置されるかはカメラの位置(position)・参照方向(lookAt)・カメラの頭頂部の向き(up)をそれぞれ3次元ベクトルで指定することで定まります。

MascotCapsuleでは、その3次元ベクトルをVector3Dクラスという3次元ベクトルクラスのインスタンスとして扱います。Vector3Dクラスは、直交座標系におけるx成分、y成分、z成分の3つを要素としてもつクラスです。
カメラを配置するには、position・lookAt・upベクトルをそれぞれVector3Dクラスのオブジェクトとして定義し、それらを引数としてTransformクラスのlookAt( Vector3D position, Vector3D lookAt, Vector3D up )メソッドを用いることで行います。

lookAtメソッドが引数として取るこれら3つのVector3Dオブジェクトの詳細は次の通りです。

position

カメラを配置する位置です。

lookAt

positionが示す位置に配置されたカメラは、そこから点lookAtがある方に向かってカメラを向けます。つまり、カメラが向く方向ベクトルはlookAtベクトルからpositionベクトルを引いたものになります。

up

カメラの頭頂部の向きです。このベクトルの向きがディスプレイの上方向になります。ただし、カメラが向く方向ベクトルがupベクトルと反対方向になるようにpositionベクトルとlookAtベクトルを定めることはできません。また、upベクトルは方向ベクトルですので、通常は正規化されたベクトル(長さが1のベクトル)を設定してください。

これら3つのオブジェクトを上に挙げた順にlookAtメソッドの引数に設定することで、カメラの配置を定めます。


以下はサンプルコード内でカメラを設定している部分です。

// Sample02Canvas.java 35行
// Transformクラスのインスタンスの作成
Transform vTrans = new Transform();

// カメラ座標設定用の各ベクトル
Vector3D position = new Vector3D( 0.f, 10.f, 20.f );
Vector3D lookAt = new Vector3D( 0.f, 0.f, 0.f );
Vector3D up = new Vector3D( 0.f, 1.f, 0.f);

・・・

// Sample02Canvas.java 62行
// カメラ位置および参照方向の設定
vTrans.lookAt( position, lookAt, up );

このサンプルでは、カメラは(0, 10, 20)の位置に配置され、カメラの向きは原点方向、頭頂部はy軸正の方向を向いています。


2.2. 3D モデルの操作

3DモデルのTransformクラスによる操作には、rotate(回転)、translate(平行移動)、scale(拡大・縮小)があります。これらのメソッドは実際には、Transformオブジェクトにそれぞれの操作を行う4×4のアフィン変換行列を掛けることで実現しています。それぞれのメソッドが掛ける変換行列の中身はjavadocのTransformクラスの項を参照してください。

rotate( Vector3D v, float angle )

対象となるモデルに対し、方向ベクトルvを軸としてangleの分だけ回転を行います。angleの単位は度(degree)です。なお、rotate( float x, float y, float z, float angle )として方向ベクトルの各成分を引数として実行することも可能です。

translate( Vector3D v )

対象となるモデルを方向ベクトルvの分だけ平行移動します。translate( float x, float y, float z )として方向ベクトルの各成分を引数として実行することも可能です。

scale( Vector3D v )

対象となるモデルを各方向に各成分の値の分だけ拡大します。scale( float x, float y, float z )として方向ベクトルの各成分を引数として実行することも可能です。

以下はサンプルコード内でモデルに対し回転を行っている部分です。

// Sample02Canvas.java 113行
// Graphics3Dオブジェクトの回転行列の設定
vTrans.rotate( new Vector3D( 0, 1.0f, 0 ), 2.0f );


画面の再描画が行われるたびに ( 0, 1, 0 ) 方向を軸として2.0度3Dモデルと床のプリミティブが回転しています。

Sample02.java 描画結果

Sample02.java 描画結果



このページの先頭へ戻る