Processingで視点の位置・姿勢を取得する
3次元のCG空間において、空間に対する視点(カメラ)の位置・姿勢の情報が欲しいときがあります。例えば、監視カメラを表現したいときや、自分中心の移動を行いたいときなど。これに関するTipsを紹介します。
Processingでは、getMatrix()という命令を使うとモデルビュー行列を得ることができます。モデルビュー行列の中には、ローカル座標系からワールド座標系への変換(モデリング変換)と、ワールド座標系からカメラ座標系への変換(ビューイング変換)の2つの変換の情報が含まれています。
視点の位置・姿勢を設定する命令であるcamera()を実行した直後のモデルビュー行列は、モデリング変換の成分が単位行列になっているため、実質的にモデルビュー行列がビューイング変換を示す行列になっています。また、この行列を逆行列にすることで、カメラ座標系からワールド座標系への変換を得ることができます。これを利用することで、ワールド座標系から見た時の視点の位置・姿勢を計算することができます。
視点の前方、右方、下方を示す線を描画するサンプルコードを以下に示します。
void setup() { size(400, 300, P3D); } void draw() { background(200); PVector eye = new PVector(); // 視点1の目ん玉の位置 PVector right = new PVector(); // 視点1の右方向を示す点 PVector down = new PVector(); // 視点1の下方向を示す点 pushMatrix(); camera( 170, -100, 100, 0, 0, 0, 0, 1, 0 ); // 視点1 PMatrix3D mat = (PMatrix3D)getMatrix(); // モデルビュー行列の取得 mat.invert(); // 逆行列 mat.mult( new PVector( 0, 0, 0 ), eye ); // カメラ座標系の(0,0,0)をワールド座標系の座標値に変換 mat.mult( new PVector( 100, 0, 0 ), right ); // カメラ座標系の(100,0,0)をワールド座標系の座標値に変換 mat.mult( new PVector( 0, 100, 0 ), down ); // カメラ座標系の(0,100,0)をワールド座標系の座標値に変換 popMatrix(); // マウスクリックで視点切り替え if ( mousePressed ) { camera( 170, -100, 100, 0, 0, 0, 0, 1, 0 ); // 視点1 } else { camera( 220, -100, 520, 0, 0, 0, 0, 1, 0 ); // 視点2 } strokeWeight(3); noFill(); // 注視点(0,0,0)に立方体を置く stroke(0); box(100); // 視点1の右方向を示す線(赤) stroke(255, 0, 0); line( eye.x, eye.y, eye.z, right.x, right.y, right.z ); // 視点1の下方向を示す線(緑) stroke(0, 255, 0); line( eye.x, eye.y, eye.z, down.x, down.y, down.z ); // 視点1の視線方向を示す線(青) stroke(0, 0, 255); line( eye.x, eye.y, eye.z, 0, 0, 0); }