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

intersectRay2(Mouse位置を取得する) [Alternativa3D 7.6 TIPS]

interactive
Object3DにMouseでお絵かき

2011/01/12 7.5から7.6仕様に変更
/**
 * Copyright narutohyper ( http://wonderfl.net/user/narutohyper )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/yN8x
 */

// forked from narutohyper's intersectRay(Mouse位置を取得する) [Alternativa3D 7.5.1 TIPS]
// forked from narutohyper's Alternativa3D 7.5 Template
package
{
    import alternativ7.engine3d.controllers.SimpleObjectController;
    import alternativ7.engine3d.core.MouseEvent3D;
    import alternativ7.engine3d.core.Object3D;
    import alternativ7.engine3d.core.Camera3D;
    import alternativ7.engine3d.core.RayIntersectionData;
    import alternativ7.engine3d.materials.FillMaterial;
    import alternativ7.engine3d.materials.TextureMaterial;
    import alternativ7.engine3d.primitives.Box;
    import alternativ7.engine3d.primitives.Plane;
    import flash.display.BitmapData;
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.filters.*;
    import flash.geom.Point;
    import com.bit101.components.Slider;
    import com.bit101.components.Label;
    /**
     * Alternativa3D 7.5.1
     *
     * interactive
     * Object3DにMouseでお絵かき
     *
     * @author narutohyper
     */
    [SWF(backgroundColor="#000000", frameRate="100", width="800", height="600")]
    public class Main extends Sprite
    {
        
        private var box:Vector.<Box> = new Vector.<Box>();
        private var camera:Camera3D;
        private var objectController:SimpleObjectController;
        
        
        public function Main():void    {
        
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }

        
        private function init(e:Event=null):void {
            removeEventListener(Event.ADDED_TO_STAGE, init);
        
            //AlternativaTemplate作成
            var scene:AlternativaTemplate = new AlternativaTemplate(this);

            
            var materials:Vector.<TextureMaterial> = new Vector.<TextureMaterial>(36);

            var i:int;
            var j:int;
            var colors:Array=[0xFFFFFF,0xCCCCFF,0xFFCCCC,0xFFCCFF,0xFFFFCC,0xCCFFFF];
            for (i = 0; i < 6; i++)
            {
                for (j = 0; j < 6; j++)
                {
                    var bmd:BitmapData = new BitmapData(500, 500, false, colors[i]);
                    materials[i*5+j] = new TextureMaterial(bmd);
                }
                
                box[i] = new Box(500,500,500,1,1,1,false,false,materials[i*5],materials[i*5+1],materials[i*5+2],materials[i*5+3],materials[i*5+4],materials[i*5+5]);
                scene.container.addChild(box[i]);
                box[i].addEventListener(MouseEvent3D.MOUSE_DOWN, onMouseDown3D);
            }
            box[0].x=1000;
            box[1].x=-1000;
            box[2].z=1000;
            box[3].z=-1000;
            box[4].y=1000;
            box[5].y=-1000;
            
            
            bmd = new BitmapData(2000, 2000, false, 0xCCFFCC);
            var material:TextureMaterial = new TextureMaterial(bmd);
            var plane:Plane = new Plane(2000, 2000);
            plane.setMaterialToAllFaces(material);
            scene.container.addChild(plane);
            plane.addEventListener(MouseEvent3D.MOUSE_DOWN, onMouseDown3D);
            plane.z = -1500;
            
            //ObjectControllerの作成
            //MouseDragで、Objectを回転させる為のController
            objectController = new SimpleObjectController(stage, box[4], 100);
            objectController.mouseSensitivity = 0.5;
            objectController.unbindAll();
            
            
            //CameraをControllerから切り離す
            scene.cameraController.object = null;
            camera = scene.camera;
            camera.x=0;
            camera.y=0;
            camera.z=0;
            
            makeSlider();
            
            var RADIAN:Number = Math.PI/180;
            scene.onPreRender = function():void {
                objectController.update();
            }
            
            //描画開始
            scene.startRendering();

        }
        
    
        private var counter:uint =0;
        
        private function onMouseDown3D(e:MouseEvent3D):void
        {
            objectController.mouseSensitivity = 0;
            var object:Object3D = e.target as Object3D;
            object.removeEventListener(MouseEvent3D.MOUSE_DOWN, onMouseDown3D);
            object.addEventListener(MouseEvent3D.MOUSE_MOVE, onMouseMove3D);
            object.addEventListener(MouseEvent3D.MOUSE_OUT,onMouseOut3D);
            object.addEventListener(MouseEvent3D.MOUSE_UP, onMouseUp);
        }
        
        private function onMouseUp(e:MouseEvent3D):void
        {
            objectController.mouseSensitivity = 0.5;
            var object:Object3D = e.target as Object3D;
            
            object.addEventListener(MouseEvent3D.MOUSE_DOWN, onMouseDown3D);
            object.removeEventListener(MouseEvent3D.MOUSE_MOVE, onMouseMove3D);
            object.removeEventListener(MouseEvent3D.MOUSE_OUT,onMouseOut3D);
            object.removeEventListener(MouseEvent3D.MOUSE_UP, onMouseUp);
            oldX=-1;
            oldY=-1;
        }
                

        private var oldX:Number=-1;
        private var oldY:Number=-1;
        private var oldTexture:BitmapData;
        private function onMouseMove3D(e:MouseEvent3D):void
        {
            var object:Object3D = e.target as Object3D;
            var data:RayIntersectionData = object.intersectRay(e.localOrigin, e.localDirection);
            if (data != null) {
                var texture:BitmapData = (data.face.material as TextureMaterial).texture;
                if (oldTexture==texture) {
                    var uv:Point = data.face.getUV(data.point);
                    var spot:Shape = new Shape();
                    spot.graphics.lineStyle(10, 0x000000, 1);
                    if (oldX>=0 && oldY>=0) {
                        spot.graphics.moveTo(oldX, oldY);
                    } else {
                        spot.graphics.moveTo(uv.x * texture.width, uv.y * texture.height);
                    }
                    spot.graphics.lineTo(uv.x * texture.width, uv.y * texture.height);
                    texture.draw(spot);
                    oldX = uv.x * texture.width;
                    oldY = uv.y * texture.height;
                } else {
                    oldTexture = texture;
                    oldX=-1;
                    oldY=-1;
                }
            }
        }
        
        private function onMouseOut3D(e:MouseEvent3D):void
        {
            oldTexture = null;
            oldX=-1;
            oldY=-1;
        }
                
        
        private function makeSlider():void {
                var base:Sprite = new Sprite();
                addChild(base);
                base.graphics.beginFill(0xCCCCCC);
                base.graphics.drawRect(0, 0, 300, 70);

                base.addEventListener(MouseEvent.MOUSE_OVER, onMouseOver);
                base.addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
                
                function onMouseOver(e:MouseEvent):void {
                    objectController.mouseSensitivity = 0;
                }
                
                function onMouseOut(e:MouseEvent):void {
                    objectController.mouseSensitivity = 0.5;
                }
                
                var labelYaw:Label = new Label(base, 20,10);
                labelYaw.text = "CameraYaw";
                var yaw:Slider = new Slider(Slider.HORIZONTAL, base, 100, 10, onSliderYaw);
                yaw.value = 0;

                var labelPitch:Label = new Label(base, 20,40);
                labelPitch.text = "CameraPitch";
                var pitch:Slider = new Slider(Slider.HORIZONTAL, base, 100, 40, onSliderPitch);
                pitch.value = 75;
                
                
                var RADIAN:Number=Math.PI/180;
                function onSliderYaw(e:Event):void {
                    camera.rotationZ = RADIAN * (yaw.value / 100) * 360;
                    switchControllerObject();
                }

                function onSliderPitch(e:Event):void {
                    camera.rotationX = RADIAN * (pitch.value / 100) * 360;
                    switchControllerObject();
                }

                function switchControllerObject():void {
                    var yawAngle:Number = yaw.value / 100 * 360;
                    var pitchAngle:Number = pitch.value / 100 * 360;
                    if (pitchAngle >= 135 && pitchAngle < 225) {
                        objectController.object = box[3];
                    } else if ((pitchAngle >= 0 && pitchAngle < 45) || (pitchAngle >= 315 && pitchAngle <= 360)) {
                        objectController.object = box[2];
                    } else if (pitchAngle >= 45 && pitchAngle < 135) {
                        if (yawAngle>=45 && yawAngle<135) {
                            objectController.object = box[0];
                        } else if (yawAngle>=135 && yawAngle<225) {
                            objectController.object=box[4];
                        } else if (yawAngle>=225 && yawAngle<315) {
                            objectController.object=box[1];
                        } else {
                            objectController.object=box[5];
                        }
                    } else {
                        if (yawAngle>=45 && yawAngle<135) {
                            objectController.object = box[1];
                        } else if (yawAngle>=135 && yawAngle<225) {
                            objectController.object=box[5];
                        } else if (yawAngle>=225 && yawAngle<315) {
                            objectController.object=box[0];
                        } else {
                            objectController.object=box[4];
                        }
                    }
                }
                
                
                
        }


    }
    
}







/**
 * BasicTemplate for Alternativa3D 7.5
 * Alternativa3D 7.5を扱いやすくするためのテンプレートです
 * @author narutohyper & clockmaker
 *
 */
import alternativ7.engine3d.containers.BSPContainer;
import alternativ7.engine3d.containers.ConflictContainer;
import alternativ7.engine3d.containers.DistanceSortContainer;
import alternativ7.engine3d.containers.KDContainer;
import alternativ7.engine3d.containers.LODContainer;
import alternativ7.engine3d.controllers.SimpleObjectController;
import alternativ7.engine3d.core.Camera3D;
import alternativ7.engine3d.core.Object3DContainer;
import alternativ7.engine3d.core.View;
import flash.display.DisplayObject;

import flash.display.DisplayObjectContainer;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageQuality;
import flash.display.StageScaleMode;

import flash.events.Event;

class AlternativaTemplate extends Sprite
{
    /**
     * 子オブジェクトを最適な方法でソートするコンテナ
     * (ConflictContainer)
     */
    public static const CONFLICT:String = 'conflict';
    /**
     * 子オブジェクトをBSP(バイナリ空間分割法)によってソートするコンテナ
     * (BSPContainer)
     */
    public static const BSP:String = 'bsp';
    
    /**
     * 子オブジェクトをカメラからのZ値でソートするコンテナ
     * (DistanceSortContainer)
     */
    public static const ZSORT:String = 'zsort';
    /**
     * KDツリー(http://ja.wikipedia.org/wiki/Kd%E6%9C%A8)によってソートするコンテナ
     * (KDContainer)
     */
    public static const KD:String = 'kd';
    /**
     * detalizationと子オブジェクトの距離でソートするコンテナ(詳細は調査中)
     * (LODContainer)
     */
    public static const LOD:String = 'lod';
    
    /**
     * 3dオブジェクト格納するコンテナインスタンス。
     */
    public var container:Object3DContainer;

    /**
     * ビューインスタンスです。
     */
    public var view:View;
    
    /**
     * カメラインスタンスです。
     */
    public var camera:Camera3D;
    
    /**
     * カメラコントローラーです。
     */
    public var cameraController:SimpleObjectController;
    
    private var _mc:DisplayObjectContainer;
    private var _viewWidth:int;
    private var _viewHeight:int;
    private var _scaleToStage:Boolean;
    private var _containerType:String;
    
    /**
     * 新しい Alternativa3DTemplate インスタンスを作成します。
     * @param    mc
     * @param    containerType
     * @param    viewWidth
     * @param    viewHeight
     * @param    scaleToStage
     */
    public function AlternativaTemplate(mc:DisplayObjectContainer,containerType:String=CONFLICT,viewWidth:int=640, viewHeight:int=480, scaleToStage:Boolean = true)
    {
        
        _mc = mc;
        _mc.addChild(this);

        _containerType = containerType;
        _viewWidth = viewWidth;
        _viewHeight = viewHeight;
        _scaleToStage = scaleToStage;
        
        if (stage) init();
        else addEventListener(Event.ADDED_TO_STAGE, init);
    }


    /**
     * 初期化されたときに実行されるイベントです。
     * 初期化時に実行したい処理をオーバーライドして記述します。
     */
    protected function atInit():void {}


    /**
     * Event.ENTER_FRAME 時に実行されるレンダリングのイベントです。
     * レンダリング前に実行したい処理をオーバーライドして記述します。
     */
    protected function atPreRender():void {}
    
    /**
     * Event.ENTER_FRAME 時に実行されるレンダリングのイベントです。
     * レンダリング前に実行したい処理をオーバーライドして記述します。
     */
    private var _onPreRender:Function = function():void{};
    public function get onPreRender():Function { return _onPreRender; }
    public function set onPreRender(value:Function):void
    {
        _onPreRender = value;
    }
    
    /**
     * Event.ENTER_FRAME 時に実行されるレンダリングのイベントです。
     * レンダリング後に実行したい処理をオーバーライドして記述します。
     */
    protected function atPostRender():void {}
    
    /**
     * Event.ENTER_FRAME 時に実行されるレンダリングのイベントです。
     * レンダリング後に実行したい処理を記述します。
     */
    private var _onPostRender:Function = function():void{};
    public function get onPostRender():Function { return _onPostRender; }
    public function set onPostRender(value:Function):void
    {
        _onPostRender = value;
    }
    
    
    /**
     * レンダリングを開始します。
     */
    public function startRendering():void
    {
        addEventListener(Event.ENTER_FRAME, onRenderTick);
    }

    /**
    * レンダリングを停止します。
    */
    public function stopRendering():void
    {
        removeEventListener(Event.ENTER_FRAME, onRenderTick);
    }

    /**
     * シングルレンダリング(レンダリングを一回だけ)を実行します。
     */
    public function singleRender():void
    {
        onRenderTick();
    }

    /**
     * @private
     */
    private function init(e:Event = null):void
    {
        removeEventListener(Event.ADDED_TO_STAGE, init);
        // entry point
        stage.scaleMode = StageScaleMode.NO_SCALE;
        stage.align = StageAlign.TOP_LEFT;
        stage.quality = StageQuality.HIGH;
        
        //Root objectの作成
        if (_containerType == CONFLICT) {
            container = new ConflictContainer();
        } else if (_containerType == BSP) {
            container = new BSPContainer();
        } else if (_containerType == ZSORT) {
            container = new DistanceSortContainer();
        } else if (_containerType == KD) {
            container = new KDContainer();
        } else if (_containerType == LOD) {
            container = new LODContainer();
        }
        //Viewの作成
        view = new View(stage.stageWidth, stage.stageHeight);
        _mc.addChild(view);

        //cameraの作成
        camera = new Camera3D();
        camera.view = view;
        camera.x = 0;
        camera.y = -500;
        camera.z = 0;
        container.addChild(camera);
        
        // Camera controller
        cameraController = new SimpleObjectController(stage, camera, 10);
        cameraController.mouseSensitivity = 0;
        cameraController.unbindAll();
        cameraController.lookAtXYZ(0, 0, 0);
        
        onResize();
        stage.addEventListener(Event.RESIZE, onResize);
        
        atInit();
    }
    
    /**
     * @private
     */
    private function onResize(e:Event = null):void
    {
        if (_scaleToStage)
        {
            view.width = stage.stageWidth;
            view.height = stage.stageHeight;
        }
        else
        {
            view.width = _viewWidth;
            view.height = _viewHeight;
        }
    }
    
    /**
     * @private
     */
    private function onRenderTick(e:Event = null):void
    {
        atPreRender();
        _onPreRender();
        cameraController.update();
        camera.render();
        atPostRender();
        _onPostRender();
    }
    
    
}