3D復習2

by shunsuke_ohba
@author Shunsuke Ohba
@version 1.0
@see http://reinit.info/blog/
♥0 | Line 82 | Modified 2011-02-13 21:43:09 | MIT License
play

ActionScript3 source code

/**
 * Copyright shunsuke_ohba ( http://wonderfl.net/user/shunsuke_ohba )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/pecy
 */

package
{
    import flash.display.MovieClip;
    import flash.events.Event;
    import flash.geom.Point;
    /**
    *
    * @author Shunsuke Ohba
    * @version 1.0
    * @see http://reinit.info/blog/
    */
    public class World3D extends MovieClip
    {
        //焦点距離
        public var fl:Number = 250;
        //消失点の座標
        public var vanishingPoint:Point;
        //3Dオブジェクト
        public var ball:Ball3D;

        public function World3D()
        {
            vanishingPoint = new Point(stage.stageWidth >> 1, stage.stageHeight >> 1);
            //3Dオブジェクトを生成
            ball = addChild(new Ball3D) as Ball3D;
            ball.addEventListener(Event.COMPLETE,_onComplete);
            ball.start("http://wonderfl.reinit.info/logo.png");
        }

        private function _onComplete(e:Event):void
        {
            e.target.removeEventListener(e.type,_onComplete);
            startRendering();
        }
        private function startRendering():void
        {
            //3Dオブジェクトを3D座標(150,-80,40)に配置する
            ball.xpos = 150;
            ball.ypos = -80;
            ball.zpos = 40;

            //レンダリングする
            addEventListener(Event.ENTER_FRAME, rendering);
        }

        private function rendering(e:Event):void
        {
            //y軸上で、1フレーム3度回転させる
            var angleY:Number = 3;
            rotateY(angleY);
        }

        private function rotateY(angleY:Number):void
        {
            //角度をラジアンに変換
            var radianY:Number = angleY * (Math.PI / 180);

            //アフィン変換を行う
            var afterX:Number = ball.xpos * Math.cos(radianY) - ball.zpos * Math.sin(radianY);
            var afterZ:Number = ball.zpos * Math.cos(radianY) + ball.xpos * Math.sin(radianY);

            //回転後の3D座標を代入する
            ball.xpos = afterX;
            ball.zpos = afterZ;

            //拡大率を計算する
            var scale:Number = fl / (fl + ball.zpos);

            ball.scaleX = ball.scaleY = scale;

            //3D座標から2D座標に変換する
            ball.x = ball.xpos * scale + vanishingPoint.x;
            ball.y = ball.ypos * scale + vanishingPoint.y;

            //投影面より3Dオブジェクトが手前に来た場合は、3Dオブジェクトを非表示にする
            ball.visible = ball.zpos > fl?false:true;
        }
    }
}
 import flash.display.Bitmap;
 import flash.display.Graphics;
 import flash.display.Loader;
 import flash.display.LoaderInfo;
 import flash.display.MovieClip;
 import flash.events.Event;
 import flash.net.URLRequest;
 import flash.system.LoaderContext;
 /**
 *
 * @author Shunsuke Ohba
 * @version 1.0
 * @see http://reinit.info/blog/
 */
class Ball3D extends MovieClip
{
    //3D空間上のX座標
    public var xpos:Number = 0;
    //3D空間上のY座標
    public var ypos:Number = 0;
    //3D空間上のZ座標
    public var zpos:Number = 0;

    public function Ball3D()
    {
        
    }
    public function start(url:String):void
    {
        var loader:Loader = new Loader;
        addChild(loader);
        loader.contentLoaderInfo.addEventListener(Event.COMPLETE, _onComplete);
        loader.load(new URLRequest(url), new LoaderContext(true));
    }

    private function _onComplete(e:Event):void 
    {
        e.target.removeEventListener(e.type, _onComplete);
        var loader:Loader = LoaderInfo(e.target).loader;
        loader.x = -loader.width >> 1;
        loader.y = -loader.height >> 1;
        Bitmap(loader.content).smoothing = true;
        dispatchEvent(new Event(Event.COMPLETE));
    }
}