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

earthっぽいの [Alternativa3D 7.6 TIPS]

本家ロシア語フォーラムで、どうすればいいのみたいなのがあったので、作ったサンプル

earth Drag = Rotation the earth 
cosmos Drag = Rotation the camera
earth CLICK = Put mark & Move the camera

2011/01/12 7.5から7.6仕様に変更
Get Adobe Flash player
by narutohyper 23 Oct 2012
/**
 * Copyright narutohyper ( http://wonderfl.net/user/narutohyper )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/lUDh
 */

// forked from narutohyper's Alternativa3D 7.5 Template
package
{
    import alternativ7.engine3d.containers.ConflictContainer;
    import alternativ7.engine3d.controllers.SimpleObjectController;
    import alternativ7.engine3d.core.Camera3D;
    import alternativ7.engine3d.core.MouseEvent3D;
    import alternativ7.engine3d.core.Object3D;
    import alternativ7.engine3d.core.Object3DContainer;
    import alternativ7.engine3d.core.RayIntersectionData;
    import alternativ7.engine3d.core.Sorting;
    import alternativ7.engine3d.loaders.MaterialLoader;
    import alternativ7.engine3d.materials.FillMaterial;
    import alternativ7.engine3d.materials.TextureMaterial;
    import alternativ7.engine3d.objects.Sprite3D;
    import alternativ7.engine3d.primitives.GeoSphere;
    import com.bit101.components.Label;
    import com.bit101.components.Slider;
    import flash.display.BitmapData;
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Matrix3D;
    import flash.geom.Point;
    import flash.geom.Vector3D;
    import flash.system.LoaderContext;
    import org.libspark.betweenas3.BetweenAS3;
    import org.libspark.betweenas3.easing.*;
    import org.libspark.betweenas3.events.TweenEvent;
    import org.libspark.betweenas3.tweens.ITween;

    
    /**
     *
     * Alternativa3D 7.6
     *
     * earthっぽいの
     *
     * ...
     * @author narutohyper
     */
    [SWF(backgroundColor="#000000", frameRate="60", width="800", height="600")]
    public class Main extends Sprite
    {
        private const RADIAN:Number = Math.PI / 180;
        private var cameraController:SimpleObjectController;
        private var zoomController:SimpleObjectController;
        private var objectController:SimpleObjectController;
        private var earthContainer:Object3DContainer;
        private var earth:GeoSphere;
        private var camera:Camera3D;
        
        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);
            addChild(scene.camera.diagram);
        
            //星パーティクル
            var stars:Vector.<Sprite3D> = new Vector.<Sprite3D>(500, true);
            var circle:Shape = new Shape();
            circle.graphics.beginFill(0xFFFFFF);
            circle.graphics.drawCircle(25, 25, 25);
            var bmd:BitmapData = new BitmapData(50, 50, true, 0);
            bmd.draw(circle);
            var material:TextureMaterial = new TextureMaterial(bmd);
            var angle:Number;
            var length:Number;
            for (var i:int = 0; i < 500; i++)
            {
                stars[i] = new Sprite3D(100, 100, material);
                scene.container.addChild(stars[i]);
                angle = Math.random() * 360 * RADIAN;
                length = Math.random() * 100000 + 5000;
                stars[i].x = Math.cos(angle) * length;
                stars[i].y = Math.sin(angle) * length;
                angle = Math.random() * 360 * RADIAN;
                length = Math.random() * 100000 + 5000;
                stars[i].z = Math.sin(angle) * length;
            }

            //地球
            var earthMaterial:TextureMaterial = new TextureMaterial(null, false, true);
            earthMaterial.diffuseMapURL = 'http://assets.wonderfl.net/images/related_images/e/e9/e987/e9876c502c9e9693205335e106de6baa8865c1a6';

            var textures:Vector.<TextureMaterial> = new Vector.<TextureMaterial>();
            textures[0] = earthMaterial;
        var context:LoaderContext = new LoaderContext(true);
        var materialLoader:MaterialLoader = new MaterialLoader();
        materialLoader.load(textures,context);
            
            
            earthContainer = new ConflictContainer();
            earth = new GeoSphere(200, 8);
            earth.sorting = Sorting.DYNAMIC_BSP;
            earth.setMaterialToAllFaces(earthMaterial);
            earthContainer.addChild(earth);
            scene.container.addChild(earthContainer);
            earth.x = 0;
            earth.y = 0;
            
            //cameraの制御を簡単にするために、cameraをObject3DContainerに格納
            camera = scene.camera;
            var cameraContainer:Object3DContainer = new Object3DContainer();
            scene.container.addChild(cameraContainer);
            scene.container.removeChild(camera);
            
            cameraContainer.addChild(camera);

            //カメラの調整
            //カメラはControllerに関連付けている為、x,y,zで直接位置を指定できないので
            //SimpleController.setObjectPosXYZを使用
            zoomController = scene.cameraController;
            zoomController.mouseSensitivity = 0;
            zoomController.unbindAll();
            zoomController.setObjectPosXYZ(0,-250,0);
            zoomController.lookAtXYZ(0, 0, 0);
            
            //cameraControllerの作成
            //MouseDragで、cameraを回転させる為のController
            cameraController = new SimpleObjectController(stage, cameraContainer, 100);
            cameraController.mouseSensitivity = 0;
            cameraController.unbindAll();
            cameraController.setObjectPosXYZ(0,-300,0);
            cameraController.lookAtXYZ(0, 0, 0);
            

            earthContainer.addEventListener(MouseEvent3D.CLICK, onClick3D);
            earthContainer.addEventListener(MouseEvent3D.MOUSE_DOWN, onMouseDown3D);
            stage.addEventListener(MouseEvent.MOUSE_DOWN,onMouseDown);
            
            
            makeSlider();

            //描画開始
            scene.onPreRender = function():void {
                //objectController.update();
                cameraController.updateObjectTransform()
                cameraController.lookAtXYZ(0, 0, 0);
                cameraController.update();
            }
            scene.startRendering();

        }
        
        
        private var startPos:Vector3D;
        private var mouseSensitivity:Number = 0.5;
        private var startMouseX:Number;
        private var startMouseY:Number;
        private var startRotationZ:Number;
        private var startUV:Point;
        private var startMatrix:Matrix3D;
        private var _t:ITween;
        
        /**
         * cameraMove
         *
         */
        private function onClick3D(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;
                var uv:Point = data.face.getUV(data.point);
                if (startUV) {
                    
                    
                    //var spot:Shape = new Shape();
                    //spot.graphics.beginFill(0xFF0000);
                    //spot.graphics.drawCircle(uv.x * texture.width, uv.y * texture.height,1);
                    //texture.draw(spot);

                    //CLICKされた位置に3Dobjectをおいてみる
                    var marker:Sprite3D = new Sprite3D(10,10, new FillMaterial(0xFF0000,0.5));
                    earthContainer.addChild(marker);
                    
                    var matrix:Matrix3D = new Matrix3D();
                    var angle:Number;
                    var v:Vector3D;
                    matrix = new Matrix3D();
                    matrix.appendTranslation(210, 0, 0);
                    angle = (uv.y * 180 - 90);
                    matrix.appendRotation(angle, Vector3D.Y_AXIS);
                    angle = (uv.x * 360 - 180);
                    matrix.appendRotation(angle, Vector3D.Z_AXIS);
                    v = matrix.transformVector(new Vector3D())
                    marker.x = v.x;
                    marker.y = v.y;
                    marker.z = v.z;
                    
                    
                    
                    matrix = new Matrix3D();
                    matrix.appendTranslation(220, 0, 0);
                    angle = (uv.y * 180 - 90);
                    matrix.appendRotation(angle, Vector3D.Y_AXIS);
                    angle = (uv.x * 360 - 180) + earthContainer.rotationZ*180/Math.PI;
                    matrix.appendRotation(angle, Vector3D.Z_AXIS);
                    v = matrix.transformVector(new Vector3D())

                    
                    if (_t) _t.stop();
                    
                    var tweenArr:Array = [];
                    tweenArr[0] = BetweenAS3.tween(cameraController.object, {x:v.x }, null, 1);
                    tweenArr[1] = BetweenAS3.tween(cameraController.object, {y:v.y }, null, 1);
                    tweenArr[2] = BetweenAS3.tween(cameraController.object, {z:v.z }, null, 1);
                    _t = BetweenAS3.parallelTweens(tweenArr);
                    _t.addEventListener(TweenEvent.COMPLETE, onComplete);
                    _t.play();

                    function onComplete(e:TweenEvent):void {
                        _t.removeEventListener(TweenEvent.COMPLETE, onComplete);
                    }

                }
            }
        }

        


        
        
        
        /**
         * earthRotation
         *
         */
        private function onMouseUp3D(e:MouseEvent):void
        {
            mouseSensitivity=0.5;
            
            stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove3D);
            stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp3D);
        }
        
        
        private function onMouseDown3D(e:MouseEvent3D):void
        {
            mouseSensitivity = 0;
            if (_t) _t.stop();
            
            startMouseX = this.mouseX;
            startMouseY = this.mouseY;
            startRotationZ = earthContainer.rotationZ;
            stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove3D);
            stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp3D);
            
            var object:Object3D = e.target as Object3D;
            var data:RayIntersectionData = object.intersectRay(e.localOrigin, e.localDirection);
            if (data != null) {
                startUV = data.face.getUV(data.point);
            } else {
                startUV = null;
            }
            
        }
        
        private function onMouseMove3D(e:MouseEvent):void
        {
            earthContainer.rotationZ = startRotationZ + (startMouseX - this.mouseX) * RADIAN;
            startUV = null;
        }
        

        /**
         * cameraRotation
         *
         */
        private function onMouseUp(e:MouseEvent):void
        {
            stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
            stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
            
        }

        private function onMouseDown(e:MouseEvent):void
        {
            if (_t) _t.stop();
            stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
            stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
            startMouseX = mouseX;
            startMouseY = mouseY;
            startPos = new Vector3D(cameraController.object.x, cameraController.object.y, cameraController.object.z);
            
        }
        
        private function onMouseMove(e:MouseEvent):void
        {
            if (mouseSensitivity) {
                var mtr:Matrix3D = new Matrix3D();
                mtr.appendRotation((mouseX - startMouseX)*mouseSensitivity, Vector3D.Z_AXIS);
                mtr.appendRotation((mouseY - startMouseY)*mouseSensitivity, Vector3D.X_AXIS);
                var pos:Vector3D = mtr.transformVector(startPos)
                cameraController.object.x = pos.x;
                cameraController.object.y = pos.y;
                cameraController.object.z = pos.z;
            }
        }
        
        
        
        
        
        
        /**
         * zoomSlider
         *
         */
        private function makeSlider():void {
            var base:Sprite = new Sprite();
            addChild(base);
            base.graphics.beginFill(0xCCCCCC);
            base.graphics.drawRect(0, 0, 250, 40);
            
            base.addEventListener(MouseEvent.MOUSE_OVER, onMouseOver);
            base.addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
            
            function onMouseOver(e:MouseEvent):void {
                mouseSensitivity = 0;
            }
            
            function onMouseOut(e:MouseEvent):void {
                mouseSensitivity = 0.5;
            }
            
            var labelYaw:Label = new Label(base, 20,10);
            labelYaw.text = "CameraZoom";
            var zoom:Slider = new Slider(Slider.HORIZONTAL, base, 100, 10, onSliderZoom);
            zoom.value = 0;


            
            var RADIAN:Number=Math.PI/180;
            function onSliderZoom(e:Event):void {
                var value:Number = (zoom.value / 100) * -3000 - 250;
                zoomController.setObjectPosXYZ(0, value, 0);
                
            }


        }


    }
    
}









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


}