2008-03-07 | 21:47
上下左右キーでカメラ一が移動します。
(カメラが移動しても視線は原点を向いているという設定です)
カメラの向いている方向をである視線ベクトルをE、カメラの上向きのベクトルをU、EUに直行するベクトル(EをZ軸、UをY軸とした時のX軸)をX、カメラの位置をPとすると、ビュー変換行列は
で表される。
(カメラ座標を基底に持つ回転行列は
なので、ワールド座標をカメラ座標に変換するためにはその逆行列である
を掛ける。(回転行列の逆行列はその転置行列))
(カメラが移動しても視線は原点を向いているという設定です)
カメラの向いている方向をである視線ベクトルをE、カメラの上向きのベクトルをU、EUに直行するベクトル(EをZ軸、UをY軸とした時のX軸)をX、カメラの位置をPとすると、ビュー変換行列は

(カメラ座標を基底に持つ回転行列は


package { import flash.display.*; import flash.events.*; import flash.geom.*; import org.papervision3d.core.*; import org.papervision3d.core.geom.*; import org.papervision3d.core.math.*; [SWF(width="600", height="400", frameRate="10", backgroundColor="#ffffff")] public class ViewMatrix extends Sprite{ private var LEN:int = 80; private var initialPoints:Array = [new Number3D(LEN, +LEN, LEN), new Number3D(LEN, +LEN, -LEN), new Number3D(-LEN, +LEN, -LEN), new Number3D(-LEN, +LEN, LEN), new Number3D(LEN, -LEN, LEN), new Number3D(LEN, -LEN, -LEN), new Number3D(-LEN, -LEN, -LEN), new Number3D(-LEN, -LEN, LEN) ]; private var initialPoints2:Array = [new Number3D(LEN + 200, +LEN, LEN), new Number3D(LEN + 200, +LEN, -LEN), new Number3D(-LEN + 200, +LEN, -LEN), new Number3D(-LEN + 200, +LEN, LEN), new Number3D(LEN + 200, -LEN, LEN), new Number3D(LEN + 200, -LEN, -LEN), new Number3D(-LEN + 200, -LEN, -LEN), new Number3D(-LEN + 200, -LEN, LEN) ]; // 射影変換行列 private var m:Matrix3D = new Matrix3D(); // ビュー変換行列 private var vm:Matrix3D = new Matrix3D(); private var cameraPos:Number3D = new Number3D(); public function ViewMatrix():void { var r:Number = 500; var l:Number = -500; var t:Number = 500; var b:Number = -500; var n:Number = 500; var f:Number = 1000; m.n11 = 2*n/(r-l); m.n13 = (r+l)/(r-l); m.n22 = 2*n/(t-b); m.n23 = (t+b)/(t-b); m.n33 = -(f+n)/(f-n); m.n34 = -2*n*f/(f-n); m.n43 = -1; cameraPos.z = -50; drawCube(initialPoints); drawCube(initialPoints2); stage.addEventListener(KeyboardEvent.KEY_DOWN , keyDown); } private function keyDown(e:*):void{ switch (e.keyCode){ case 37 :// ← cameraPos.x-- break; case 39 :// → cameraPos.x++ break; case 38 :// ↑ cameraPos.y++ break; case 40 :// ↓ cameraPos.y--; break; } // カメラ視点ベクトル var cev:Number3D = new Number3D(-cameraPos.x, -cameraPos.y, -cameraPos.z); cev.normalize(); var cxv :Number3D = Number3D.cross( cev, new Number3D(0,1,0)); cxv.normalize(); var cuv :Number3D = Number3D.cross( cxv, cev); cuv.normalize(); vm.n11 = cxv.x; vm.n12 = cxv.y; vm.n13 = cxv.z; vm.n14 = -Number3D.dot(cameraPos, cxv); vm.n21 = cuv.x; vm.n22 = cuv.y; vm.n23 = cuv.z; vm.n24 = -Number3D.dot(cameraPos, cuv); vm.n31 = cev.x; vm.n32 = cev.y; vm.n33 = cev.z; vm.n34 = -Number3D.dot(cameraPos, cev); graphics.clear(); drawCube(initialPoints); drawCube(initialPoints2); } private function drawCube(points:Array):void{ var points2D:Array = []; for each(var pp:Number3D in points){ var p:Number3D = pp.clone(); var point:Point = convertPoint(p); points2D.push(p); } graphics.lineStyle(3,0,0.8); graphics.drawCircle(points2D[0].x, points2D[0].y, 5); graphics.moveTo(points2D[0].x, points2D[0].y); for (var i:int = 1 ; i < 4; i++){ graphics.lineTo(points2D[i].x, points2D[i].y); } graphics.lineTo(points2D[0].x, points2D[0].y); graphics.moveTo(points2D[4].x, points2D[4].y); for (i = 5 ; i < 8; i++){ graphics.lineTo(points2D[i].x, points2D[i].y); } graphics.lineTo(points2D[4].x, points2D[4].y); for (i = 0 ; i < 4; i++){ graphics.moveTo(points2D[i].x, points2D[i].y); graphics.lineTo(points2D[i+4].x, points2D[i+4].y); } // draw x axis graphics.lineStyle(2,0xff0000,0.8); var p1:Point = convertPoint(new Number3D(-300, 0,0)); var p2:Point = convertPoint(new Number3D(300, 0,0)); graphics.moveTo(p1.x, p1.y); graphics.lineTo(p2.x, p2.y); graphics.lineStyle(2,0xff,0.8); p1= convertPoint(new Number3D(0, 300,0)); p2= convertPoint(new Number3D(0, -300,0)); graphics.moveTo(p1.x, p1.y); graphics.lineTo(p2.x, p2.y); graphics.lineStyle(2,0xff00,0.8); p1= convertPoint(new Number3D(0, 0, 300)); p2= convertPoint(new Number3D(0, 0, -300)); graphics.moveTo(p1.x, p1.y); graphics.lineTo(p2.x, p2.y); } private function convertPoint(p:Number3D):Point{ // apply view matrix Matrix3D.multiplyVector(vm,p); // convert to 2D point Matrix3D.multiplyVector(m,p); p.x += 300; p.y = 200 - p.y; return new Point(p.x, p.y); } } }
スポンサーサイト