In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

forked from: Alternativa3D Tips Reflection

Alternativa3D Tips Reflection

2台のカメラと2つのViewを使用した、Alternativa3Dでの鏡面反射です。
とりあえず、行列変換やクォータニオンは使わないで実装しています。
なので、下方向への反射のみです。

@narutohyper
/**
 * Copyright TmskSt ( http://wonderfl.net/user/TmskSt )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/8jqw
 */

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"
		);
	}


}