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 mitien ( http://wonderfl.net/user/mitien )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/jE7e
 */

// forked from narutohyper's Alternativa3D Tips Reflection
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.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 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 camera:Camera3D;
        public var cameraController:WalkController;

        public var box:Array;
        public var plane:ReflectionPlane;


        public function SimpleDemo():void {
            FPS.init (stage);
            
            scene = new Scene3D();
            scene.splitAnalysis = false; // not analysis for performance
            scene.root = new Object3D();

            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,-1000,500)

            //キーボードのキー(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.speed=400;
            cameraController.yawSpeed=800;
            cameraController.pitchSpeed=800;

            //メインビュー
            view = new View();
            view.camera = camera;
            view.width = 465;
            view.height = 465;


            //鏡面の作成
            plane=new ReflectionPlane(this,view,cameraController)
            scene.root.addChild(plane);
            plane.init()


            addChild(view);


            // プリミティブを作成します
            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 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);
            
            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)
            }            

            cameraController.lookAt(box[4].coords);
            cameraController.processInput();


            plane.onRenderTick(box[4].coords)
            scene.calculate();
        }

        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.Plane;
import alternativ5.types.Point3D;

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;


    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

        //鏡面
        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

    }

    public function init():void {
        scene.root.addChild(localCamera);
    }


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


}