座標系とカメラ
ここではシーングラフを用いたレンダリングについて、座標変換の流れを説明します。
目次
1. 座標系
MascotCapsule V4 の3D図形オブジェクトの座標変換では、以下の直行座標系が用いられています。
シーンを構成する各オブジェクト( モデル )の形状を定義する座標系です。各オブジェクトごとに固有のローカル座標系が設定されています。
ワールド座標系各オブジェクトを配置してシーンを構成するための座標系です。個々のオブジェクトはそれぞれが持つ変換行列によってワールド座標空間に配置されます。
カメラ座標系ワールド座標空間に配置されたカメラから見た座標系です。描画対象とするワールド座標空間の領域( ビューボリューム )を定義する際に使用します。通常使用される透視投影または平行投影において、ビューボリュームは四角錐( 透視投影 )または直方体( 平行投影 )となります。
正規化デバイス座標系投影面に対して投影を実行し、さらに各座標値を x ( -1,1 ), y ( -1,1 ), z ( -1,1 ) の範囲に正規化した座標系です。
スクリーン座標系実際のデバイス上でのピクセル位置を表す座標系です。デバイスの座標系は左上の点を原点として、x軸は右方向、y軸は下方向になります。
シーングラフの描画では、概念的には上から順に座標変換が行われます。
2. 変換行列
ここでは変換行列を表す2つのクラスについて解説します。
2.1. m3dTransform クラス
m3dTransform クラスは変換行列を表す汎用の4×4行列です。このクラスを操作するメソッドとして rotate( 回転 )、translate( 平行移動 )、scale( 拡大・縮小 )などが用意されており、これらを組み合わせて任意の座標変換を表すことができます。この操作はそれぞれの操作を行う4×4のアフィン変換行列を乗算することで実現しています。それぞれのメソッドで乗算される変換行列の内容については、API リファレンスマニュアルの m3dTransform クラスの項を参照してください。
( IMicro3Dv4es *m3d_v4es, m3dTransform *This, float angle, float ax, float ay, float az )
ベクトル ( ax, ay, az ) を軸として angle の分だけ回転を行います。angle の単位は度 ( degree ) です。なお、IMICRO3Dv4es_m3dTransform_postRotateQuat ( IMicro3Dv4es *m3d_v4es, m3dTransform *This, float qx, float qy, float qz, float qw ) を利用すると、四元数を用いた回転ができます。
IMICRO3Dv4es_m3dTransform_postTranslate( IMicro3Dv4es *m3d_v4es, m3dTransform *This, float tx, float ty, float tz )
ベクトル ( tx, ty, tz ) の分だけ平行移動します。
IMICRO3Dv4es_m3dTransform_postScale( IMicro3Dv4es *m3d_v4es, m3dTransform *This, float sx, float sy, float sz )
各方向に各成分の値の分だけ拡大します。
2.2. m3dTransformable クラス
m3dTransformableクラスは、可変変換とテクスチャ変換を操作するための共通メソッドを定義する NodeとTexture2Dの抽象基底クラスです。内部に変換行列を表す4×4行列を保持しています。
このクラスを操作するメソッドとして、m3dTransform クラスと同様に rotate( 回転 )、 translate( 平行移動 )、 scale ( 拡大・縮小 )などが用意されています。これらの操作は、それぞれの操作を行う4×4のアフィン変換行列を掛けることで実現しています。それぞれのメソッドで乗算される変換行列の内容については、API リファレンスマニュアルの m3dTransformable クラスの項を参照してください。
( IMicro3Dv4es *m3d_v4es, m3dTransformable *This, float angle, float ax, float ay, float az )
ベクトル ( ax, ay, az ) を軸として angle の分だけ回転を行います。 angle の単位は度 ( degree ) です。回転行列は対象となる行列に対し右から掛けられます。すなわち、このメソッドが呼び出される前に設定された、他のメソッドによる演算が終了した後に回転が行われます。
IMICRO3Dv4es_m3dTransformable_preRotate( IMicro3Dv4es *m3d_v4es, m3dTransformable *This, float angle, float ax, float ay, float az )
ベクトル ( ax, ay, az ) を軸として angle の分だけ回転を行います。 angle の単位は度 ( degree ) です。回転行列は対象となる行列に対し左から掛けられます。すなわち、このメソッドが呼び出される前に設定された、他のメソッドによる演算が開始される前に回転が行われます。
IMICRO3Dv4es_m3dTransformable_setTranslation( IMicro3Dv4es *m3d_v4es, m3dTransformable *This, float tx, float ty, float tz )
座標を( tx, ty, tz ) の位置に設定します。
IMICRO3Dv4es_m3dTransformable_translate( IMicro3Dv4es *m3d_v4es, m3dTransformable *This, float tx, float ty, float tz )
ベクトル ( tx, ty, tz ) の分だけ平行移動します。
IMICRO3Dv4es_m3dTransformable_setScale( IMicro3Dv4es *m3d_v4es, m3dTransformable *This, float sx, float sy, float sz )
拡大率を与えられた各成分値に設定します。
IMICRO3Dv4es_m3dTransformable_scale( IMicro3Dv4es *m3d_v4es, m3dTransformable *This, float sx, float sy, float sz )
各方向に各成分の値だけ拡大します。
なお、このサンプルではイミディエイトモードで描画を行っているため、m3dTransform クラスを使用して座標変換を表しています。
3. モデル、及びカメラの操作
ここではモデルやカメラの操作について解説します。
3.1 カメラの配置
各3Dモデルはワールド座標系上に配置された後、カメラからの見え方を表すカメラ座標系に変換されます。ワールド座標系からカメラ座標系への変換は、ワールド座標空間に配置されたカメラの方向・位置により設定されます。ここでは m3dTransform クラスを用いてカメラ変換行列を設定します。
カメラの方向は IMICRO3Dv4es_m3dTransform_postRotate() メソッドによって設定できます。カメラは初期状態ではZ 軸負方向を向いていますが、このメソッドにより任意の方向へ向けることができます。また、カメラの位置は IMICRO3Dv4es_m3dTransform_postRotate() メソッドによって設定できます。
pmc -> pCameraTrans = IMICRO3Dv4es_m3dTransform_create ( pMe -> pIM3D );
pmc -> pCameraTransInit = IMICRO3Dv4es_m3dTransform_create ( pMe -> pIM3D );
if ( pmc -> pCameraTrans == NULL || pmc -> pCameraTransInit == NULL ){
pmc -> cameraRot = 0.f;
/* pCameraTransInitを 4×4 単位行列に置き換える */
IMICRO3Dv4es_m3dTransform_setIdentity ( pMe -> pIM3D, pmc -> pCameraTransInit );
/* モデルが見える位置にカメラを設定 */
IMICRO3Dv4es_m3dTransform_postTranslate ( pMe -> pIM3D,pmc -> pCameraTransInit, 0.f, 2.5f, 5.f );
/* カメラの向きを回転させ、モデルの位置に合わせる */
IMICRO3Dv4es_m3dTransform_postRotate ( pMe -> pIM3D, pmc -> pCameraTransInit, -20.f, 1.f, 0.f, 0.f );
このサンプルではカメラはワールド座標系上の ( 0.0, 2.5, 5.0 ) の位置にあり、ベクトル ( 0, 0, -1 ) が X 軸を中心に –20 度回転した方向を向いています。
3.2. 3D モデル及びカメラの操作
以下は、サンプルコード内でモデル及びカメラに対し回転を行っている部分です。
IMICRO3Dv4es_m3dTransform_postRotate ( pMe -> pIM3D, pmc -> pBoxTrans, 1.5f, 0.f, 1.f, 0.f );
/* カメラの変換行列の更新 */
IMICRO3Dv4es_m3dTransform_setIdentity ( pMe -> pIM3D, pmc -> pCameraTrans );
/* キー処理を行った分だけカメラを回転させる */
IMICRO3Dv4es_m3dTransform_postRotate ( pMe -> pIM3D, pmc -> pCameraTrans, pmc -> cameraRot, 0.f, 1.f, 0.f );
IMICRO3Dv4es_m3dTransform_postMultiply ( pMe -> pIM3D, pmc -> pCameraTrans, pmc -> pCameraTransInit );
IMICRO3Dv4es_m3dGraphics3D_setCamera ( pMe -> pIM3D, pmc -> pG3D, pmc -> pCamera, pmc -> pCameraTrans );
3Dモデルとカメラの変換行列にそれぞれ違う回転を行っており、モデルとワールドが別々に回転しているように描画されます。

描画結果

