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