package { import alternativ5.engine3d.controllers.WalkController; import alternativ5.engine3d.core.Camera3D; import alternativ5.engine3d.core.Object3D; import alternativ5.engine3d.core.Scene3D; import alternativ5.engine3d.display.View; import alternativ5.utils.MathUtils; import flash.geom.Point; import alternativ5.engine3d.materials.FillMaterial; import alternativ5.engine3d.primitives.Box; import alternativ5.engine3d.controllers.ObjectController import alternativ5.types.Point3D; import alternativ5.utils.KeyboardUtils import alternativ5.utils.FPS; import com.bit101.components.*; import flash.display.* import flash.events.Event; /* * Alternativa3D Tips Reflection * * 2台のカメラと2つのViewを使用した、Alternativa3Dでの鏡面反射です。 * とりあえず、行列変換やクォータニオンは使わないで実装しています。 * なので、下方向への反射のみです。 * * @narutohyper */ [SWF(width = 465, height = 465, frameRate = 60)] public class SimpleDemo extends Sprite { public var scene:Scene3D; public var view:View; public var view2:View; public var view3:View; public var camera:Camera3D; public var camera2:Camera3D; public var camera3:Camera3D; public var cameraController:WalkController; public var box:Array; public var plane:ReflectionPlane; private var debugBox:Box; public function SimpleDemo():void { FPS.init (stage); scene = new Scene3D(); scene.splitAnalysis = false; // not analysis for performance scene.root = new Object3D(); debugBox = new Box(); debugBox.cloneMaterialToAllSurfaces(new FillMaterial(0xff0000)); scene.root.addChild(debugBox); camera = new Camera3D(); camera.y = -1000; camera.z = 0; scene.root.addChild(camera); //Controllerのインスタンスを作る cameraController=new WalkController(this.stage) cameraController.object=camera cameraController.coords = new Point3D(0, -1500, 500) cameraController.checkCollisions = false; //キーボードのキー(Keyboard.KEY)を関連付ける(Bind)する cameraController.mouseEnabled=false //cameraController.bindKey(KeyboardUtils.W, ObjectController.ACTION_FORWARD); //cameraController.bindKey(KeyboardUtils.UP, ObjectController.ACTION_FORWARD); //cameraController.bindKey(KeyboardUtils.Z, ObjectController.ACTION_BACK); //cameraController.bindKey(KeyboardUtils.DOWN, ObjectController.ACTION_BACK); //cameraController.bindKey(KeyboardUtils.A, ObjectController.ACTION_LEFT); //cameraController.bindKey(KeyboardUtils.LEFT, ObjectController.ACTION_LEFT); //cameraController.bindKey(KeyboardUtils.D, ObjectController.ACTION_RIGHT); //cameraController.bindKey(KeyboardUtils.RIGHT, ObjectController.ACTION_RIGHT); //cameraController.bindKey(KeyboardUtils.SHIFT, ObjectController.ACTION_ACCELERATE); cameraController.setDefaultBindings(); cameraController.speed=400; cameraController.yawSpeed=800; cameraController.pitchSpeed=800; //メインビュー view = new View(); view.camera = camera; view.width = 465; view.height = 465; /** 2 */ camera2 = new Camera3D(); scene.root.addChild(camera2); camera2.coords = new Point3D(0, -2000, 1000); camera2.rotationX = MathUtils.toRadian(-90); view2 = new View(); view2.camera = camera2; view2.width = 200; view2.height = 400; view2.y = stage.stageHeight - 400; /** 3 */ camera3 = new Camera3D(); scene.root.addChild(camera3); camera3.coords = new Point3D(0, 0, 1500); camera3.rotationY = MathUtils.toRadian(-180); view3 = new View(); view3.camera = camera3; view3.width = 200; view3.height = 200; view3.x = 200; view3.y = stage.stageHeight - 200; //鏡面の作成 plane=new ReflectionPlane(this,view,cameraController) scene.root.addChild(plane); plane.init() addChild(view); addChild(view2); addChild(view3); // プリミティブを作成します box=[] for (var i:uint=0;i<9;i++) { box[i] = new Box(100, 100, Math.floor(i/3)*50+100); box[i].setMaterialToSurface(new FillMaterial(0xFF<<(8*(i%3))),'top'); box[i].setMaterialToSurface(new FillMaterial(0xCC<<(8*(i%3))),'front'); box[i].setMaterialToSurface(new FillMaterial(0xCC<<(8*(i%3))),'back'); box[i].setMaterialToSurface(new FillMaterial(0x99<<(8*(i%3))),'left'); box[i].setMaterialToSurface(new FillMaterial(0x99<<(8*(i%3))),'right'); box[i].setMaterialToSurface(new FillMaterial(0x33<<(8*(i%3))),'bottom'); box[i].z=150 box[i].x=Math.floor(i/3)*300-300 box[i].y=(i%3)*300-300 scene.root.addChild(box[i]); } var bmd:BitmapData=new BitmapData(100,100,true,0xFFFF0000) if (stage) { init(); } else { addEventListener(Event.ADDED_TO_STAGE, init); } } private var debuggerA:Label; private function init(e:Event = null):void { stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_LEFT; stage.quality = StageQuality.HIGH; stage.addEventListener(Event.RESIZE, onResize); onResize(null); debuggerA = new Label(stage, 10, 10); startRendering(); } private function startRendering():void { addEventListener(Event.ENTER_FRAME, onRenderTick); } private function onRenderTick(e:Event = null):void { for (var i:uint=0;i<9;i++) { box[i].rotationZ+=Math.PI/180 } //var dx:Number = box[4].coords.x-cameraController.coords.x //var dy:Number = cameraController.coords.y-box[4].coords.y //var dist:Number = Math.sqrt(dx * dx + dy * dy); //if (dist<150) { //cameraController.moveForward(false) //} debugBox.coords = cameraController.object.coords; cameraController.lookAt(box[4].coords); cameraController.processInput(); plane.onRenderTick(box[4].coords) scene.calculate(); debuggerA.text = String( "X : " + cameraController.object.x + "\n" + "Y : " + cameraController.object.y + "\n" + "Z : " + cameraController.object.z + "\n" + "RX :\t" + cameraController.object.rotationX + "\n" + "RY :\t" + cameraController.object.rotationY + "\n" + "RZ :\t" + cameraController.object.rotationZ + "\n" ); } private function onResize(event:Event = null):void { } } } import alternativ5.engine3d.controllers.WalkController; import alternativ5.engine3d.core.Camera3D; import alternativ5.engine3d.core.Object3D; import alternativ5.engine3d.display.View; import alternativ5.engine3d.materials.FillMaterial; import alternativ5.engine3d.primitives.Box; import alternativ5.engine3d.primitives.Plane; import alternativ5.types.Point3D; import com.bit101.components.Label; import flash.display.* import flash.events.Event; class ReflectionPlane extends Object3D{ private var view:View; private var cameraController:WalkController; private var plane:Plane; private var localCamera:Camera3D; private var localView:View; private var localController:WalkController; private var msk:Sprite; private var stage:DisplayObjectContainer; private var debugBoxB:Box; private var debuggerB:Label; public function ReflectionPlane(mc:DisplayObjectContainer,_view:View,_cameraController:WalkController,_width:Number=1000,_height:Number=1000,_color:uint=0x000000,_alpha:Number=0.1) { view=_view cameraController = _cameraController stage = mc; //鏡面 plane=new Plane(_width,_height,1,1); plane.cloneMaterialToAllSurfaces(new FillMaterial(_color,_alpha)); this.addChild(plane); //鏡面用のカメラ localCamera = new Camera3D(); localCamera.y = -1000; localCamera.z = 0; //鏡面用のView localView = new View(); localView.camera = localCamera; localView.x = 0; localView.width = 465; localView.height = 465; localView.y = 465 localView.scaleY = -1 mc.addChild(localView); msk=new Sprite(); mc.addChild(msk); localView.mask=msk localController=new WalkController(mc.stage) localController.coords=new Point3D(0,0,0) localController.object = localCamera debugBoxB = new Box(); debugBoxB.cloneMaterialToAllSurfaces(new FillMaterial(0xffff00)); mc["scene"].root.addChild(debugBoxB); } public function init():void { scene.root.addChild(localCamera); debuggerB = new Label(stage, 200, 10); } public function onRenderTick(lookAt:Point3D):void { //鏡面処理 //鏡面用のカメラを面を基準にリフレクション var p1:Point3D=plane.globalToLocal(cameraController.coords) var p2:Point3D=new Point3D(p1.x,p1.y,-p1.z) localController.coords=plane.localToGlobal(p2) localController.lookAt(new Point3D(lookAt.x,lookAt.y,-lookAt.z)); msk.graphics.clear(); msk.graphics.beginFill(0x0000FF); var p:Point3D for (var i:uint=0;i<4;i++ ) { p=view.projectPoint(plane.localToGlobal(plane.vertices['0_0'].coords)) msk.graphics.moveTo(p.x, p.y); p=view.projectPoint(plane.localToGlobal(plane.vertices['0_1'].coords)) msk.graphics.lineTo(p.x, p.y); p=view.projectPoint(plane.localToGlobal(plane.vertices['1_1'].coords)) msk.graphics.lineTo(p.x, p.y); p=view.projectPoint(plane.localToGlobal(plane.vertices['1_0'].coords)) msk.graphics.lineTo(p.x, p.y); } msk.graphics.endFill(); debugBoxB.coords = localController.object.coords; debuggerB.text = String( "X :\t" + localController.object.x + "\n" + "Y :\t" + localController.object.y + "\n" + "Z :\t" + localController.object.z + "\n" + "RX :\t" + localController.object.rotationX + "\n" + "RY :\t" + localController.object.rotationY + "\n" + "RZ :\t" + localController.object.rotationZ + "\n" ); } } forked from: Alternativa3D Tips Reflection