2008-02-29 | 20:29
マウスドラッグで視点変更できます。
graphicsに描画する時の座標およびスプライトの座標にビュー変換と射影変換を適用して3Dに見えるようにしています。
graphicsに描画する時の座標およびスプライトの座標にビュー変換と射影変換を適用して3Dに見えるようにしています。
package{ import flash.display.*; import flash.events.*; import flash.geom.*; import flash.utils.*; import org.papervision3d.core.math.*; [SWF(width="400", height="400",backgroundColor="0xffffff")] public class Light3D extends Sprite{ private var m:Matrix3D = new Matrix3D(); private var rm:Matrix3D = new Matrix3D(); private var lastPoint:Point; private var mouseDown:Boolean = false; private var objects:Array = []; public function Light3D(){ 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; var triangle:Triangle = new Triangle(); addChild(triangle); triangle.redraw(m, rm); triangle.zz = 0; objects.push(triangle); var star:Star = new Star(); addChild(star); star.redraw(m, rm); star.zz = 50; objects.push(star); var rectangle:Rectangle = new Rectangle(); addChild(rectangle); rectangle.redraw(m, rm); rectangle.zz = 100; objects.push(rectangle); stage.addEventListener(MouseEvent.MOUSE_DOWN, function(e:*):void{ mouseDown = true; lastPoint = new Point(stage.mouseX, stage.mouseY); }); stage.addEventListener(MouseEvent.MOUSE_UP, function(e:*):void{ mouseDown = false; lastPoint = new Point(stage.mouseX, stage.mouseY); }); stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); } private function onMouseMove(e:*):void{ if(!mouseDown) return; var xx:Number = stage.mouseX - lastPoint.x; var yy:Number = -stage.mouseY + lastPoint.y; if(yy == 00) return; var rotAxis:Number3D = new Number3D(); rotAxis.z = 0; rotAxis.x = yy; rotAxis.y = -xx; // calculate the amount of rotation var rotAngle:Number = Math.sqrt(xx*xx + yy*yy)/200*Math.PI; if(rotAngle == 0) return; rotAxis.normalize(); rm = Matrix3D.multiply(Matrix3D.rotationMatrix(rotAxis.x, rotAxis.y, 0, rotAngle), rm); lastPoint = new Point(stage.mouseX, stage.mouseY); for each(var o:Base3D in objects){ o.redraw(m, rm); } // 本当はZオーダーを考慮して並べ替える if(rm.n33 < 0){ setChildIndex(objects[0],2); setChildIndex(objects[1],1); setChildIndex(objects[2],0); }else{ setChildIndex(objects[0],0); setChildIndex(objects[1],1); setChildIndex(objects[2],2); } } } } internal class Base3D extends Sprite{ public var xx:int ; public var yy:int ; public var zz:int ; public function redraw(m:Matrix3D, rm:Matrix3D):void{ } protected function convertPoint(p:Number3D, m:Matrix3D, rm:Matrix3D):Point{ // apply camera rotation Matrix3D.multiplyVector(rm,p); // convert to 2D point Matrix3D.multiplyVector(m,p); return new Point(p.x + 200, 200 - p.y); } } import flash.display.Sprite; import flash.geom.*; import org.papervision3d.core.math.*; internal class Triangle extends Base3D { public function Triangle() { } public override function redraw(m:Matrix3D, rm:Matrix3D):void{ graphics.clear(); graphics.lineStyle(1, 0, 1); graphics.beginFill(0xff0000); var p:Point = convertPoint(new Number3D(-30,-30,zz), m, rm); var p2:Point = convertPoint(new Number3D(30,30,zz), m, rm); var p3:Point = convertPoint(new Number3D(-30,30,zz), m, rm); graphics.moveTo(p.x, p.y); graphics.lineTo(p2.x, p2.y); graphics.lineTo(p3.x, p3.y); graphics.endFill(); } } internal class Rectangle extends Base3D { public function Rectangle() { } public override function redraw(m:Matrix3D, rm:Matrix3D):void{ graphics.clear(); graphics.lineStyle(1, 0, 1); graphics.beginFill(0xff00); var p:Point = convertPoint(new Number3D(0,0,zz), m, rm); var p2:Point = convertPoint(new Number3D(0,150,zz), m, rm); var p3:Point = convertPoint(new Number3D(150, 150,zz), m, rm); var p4:Point = convertPoint(new Number3D(150, 0,zz), m, rm); graphics.moveTo(p.x, p.y); graphics.lineTo(p2.x, p2.y); graphics.lineTo(p3.x, p3.y); graphics.lineTo(p4.x, p4.y); graphics.endFill(); } } internal class Star extends Base3D{ public function Star(){ } public override function redraw(m:Matrix3D, rm:Matrix3D):void{ graphics.clear(); graphics.lineStyle(1, 0xff, 0.8); graphics.beginFill(0xff); var seq:Array=[2,4,1,3,0]; var p0:Point = convertPoint(new Number3D(100, 200, zz), m, rm); graphics.moveTo(p0.x, p0.y); for(var j:int = 0 ; j < 5 ; j++){ var rad:Number = seq[j] * Math.PI * 2 / 5; var p:Point = convertPoint(new Number3D(-Math.sin(rad)*100+100, Math.cos(rad)*100+100, zz), m, rm); graphics.lineTo(p.x, p.y); } graphics.endFill(); } }
スポンサーサイト