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

3D演習その4 +Camera3Dの回転2

ActionScript3.0Animation読みながら、とりあえず3D投影してみる。
Z軸で動かしてみる
Camera を導入してみる
Camera を回転させてみた
Zsortをつけてみた
Camera.rotationY がおかしいのを直した。
ぐるぐる回してみる。
// forked from yd_niku's 3D演習その3 +Camera3Dの回転
// forked from yd_niku's forked from: 3D演習その1
// forked from yd_niku's 3D演習その1
package {

    // ActionScript3.0Animation読みながら、とりあえず3D投影してみる。
    // Z軸で動かしてみる
    // Camera を導入してみる
    // Camera を回転させてみた
    // Zsortをつけてみた
    // Camera.rotationY がおかしいのを直した。
    // ぐるぐる回してみる。
    import flash.display.Sprite;
    import flash.display.DisplayObject;
    import flash.display.StageQuality;
    import flash.events.Event;
    import caurina.transitions.Tweener;

    public class FlashTest extends Sprite {
        private var _scene:Scene3D;
        private var _camera:Camera3D;
        private var _easeCamera:EaseObject;

        private var screenX:Number;
        private var screenY:Number;
        public function FlashTest() {
            stage.frameRate = 60;
            stage.quality = StageQuality.MEDIUM;
            setup();

            putThemFar();

            _easeCamera= new EaseObject( _camera );
            addEventListener( Event.ENTER_FRAME, enterframeHandler );
        }

        private function setup():void {
            DisplayObject3D.screenX = stage.stageWidth/2;
            DisplayObject3D.screenY = stage.stageHeight/2;

            _camera = new Camera3D();
            _scene = new Scene3D( this, _camera );

            var xNum:uint = 8, yNum:uint = 8, zNum:uint = 10;
            var xInterval:uint = 50, yInterval:uint = 50, zInterval:uint = 50;
            for( var i:int=0; i<xNum; ++i ) {
                for( var j:int=0; j<yNum; ++j ) {
                    for( var k:int=0; k<zNum; ++k ) {
                        createBall(
                            (i-xNum*0.5)*xInterval,
                            (j-yNum*0.5)*yInterval,
                            (k-zNum*0.2)*zInterval
                        );
                    }
                }
            }
        }
        private function createBall( sx:Number, sy:Number, sz:Number ):void {
            var obj3D:DisplayObject3D = new DisplayObject3D(new Ball());
            obj3D.x = sx;
            obj3D.y = sy;
            obj3D.z = sz;
            _scene.addChild( obj3D );
        }
        private function putThemFar():void {
            var l:uint = _scene.renderList.length;
            for( var i:uint=0; i<l; ++i ) {
                var obj:DisplayObject3D =  _scene.renderList[i];
                var tz:Number= obj.z;
                obj.z = 0;
                Tweener.addTween( obj, { z: tz, time:2, transition:"easeInOutQuart" } );
            }
        }
        private function enterframeHandler (e:Event):void{
            _easeCamera.vRotationX = 1;
            _easeCamera.vRotationY = 1;
            _easeCamera.vRotationZ = 1;
            _easeCamera.calcuration();
        }

    }
}


class EaseObject {
    public var vx :Number = 0;
    public var vy :Number = 0;
    public var vz :Number = 0;
    public var vRotationX :Number = 0;
    public var vRotationY :Number = 0;
    public var vRotationZ :Number = 0;

    private var friction:Number = 0.95;
    private var _target:Object;
    public function EaseObject ( target:Object ) {
        _target = target;
    }
    public function calcuration():void {
        vx *= friction;
        vy *= friction;
        vz *= friction;
        vRotationX *= friction;
        vRotationY *= friction;
        vRotationZ *= friction;

        _target.x += vx;
        _target.y += vy;
        _target.z += vz;
        _target.rotationX += vRotationX;
        _target.rotationY += vRotationY;
        _target.rotationZ += vRotationZ;
    }
}

import flash.display.*;
import flash.events.*;
class DisplayObject3D {
    public static var screenX:Number = 0;
    public static var screenY:Number = 0;

    public var view:DisplayObject;
    public var x:Number = 0;
    public var y:Number = 0;
    public var z:Number = 0;

    public function DisplayObject3D( view:DisplayObject ) {
        this.view = view;
    }
    public function render( tx:Number, ty:Number, persepective:Number ):void {
        view.x = tx + screenX;
        view.y = ty + screenY;
        view.scaleX = view.scaleY = persepective;
        view.alpha = Math.min( 1, persepective);
    }
    public function set visible( value:Boolean ) :void {
        view.visible = value;
    }
    public function get visible() :Boolean {
        return view.visible;
    }
}

class Scene3D {
    private var _stage:DisplayObjectContainer;
    private var _camera :Camera3D;
    private var _renderList:Array = [];
    private var _ZsortList:Array = [];
    public function Scene3D( stage:DisplayObjectContainer, camera:Camera3D ){
        _stage = stage;
        _camera = camera;
        _stage.addEventListener( Event.ENTER_FRAME, enterfameHandler );
    }

    private function enterfameHandler(e:Event):void {
        render();
    }
    public function addChild( obj3D :DisplayObject3D ) :DisplayObject3D {
        _renderList.push(  obj3D );
        _stage.addChild( obj3D.view );
        return obj3D;
    }
    private const PI:Number = Math.PI;
    public function render():void {

        _ZsortList = [];
        var camXCos:Number = Math.cos( PI*_camera.rotationX/180);
        var camXSin:Number = Math.sin( PI*_camera.rotationX/180);
        var camYCos:Number = Math.cos( PI*_camera.rotationY/180);
        var camYSin:Number = Math.sin( PI*_camera.rotationY/180);
        var camZCos:Number = Math.cos( PI*_camera.rotationZ/180);
        var camZSin:Number = Math.sin( PI*_camera.rotationZ/180);

        var l:uint = _renderList.length;
        for( var i:uint=0; i<l; ++i ) {
            var obj:DisplayObject3D= _renderList[i];
            var tmpX:Number = obj.x - _camera.x;
            var tmpY:Number = obj.y - _camera.y;
            var tmpZ:Number = obj.z - _camera.z;

            // TODO:Matrix3Dにまかせる
            // Z Axis
            var ZAxisX :Number = ( tmpX*camZCos - tmpY*camZSin );
            var ZAxisY :Number = ( tmpX*camZSin + tmpY*camZCos );
            var ZAxisZ :Number = tmpZ;
            // X Axis
            var XAxisY :Number = ( ZAxisY*camXCos - ZAxisZ*camXSin );
            var XAxisZ :Number = ( ZAxisY*camXSin + ZAxisZ*camXCos );
            var XAxisX :Number = ZAxisX;
            // Y Axis
            var YAxisZ :Number = ( XAxisZ*camYCos - XAxisX*camYSin );
            var YAxisX :Number = ( XAxisZ*camYSin + XAxisX*camYCos );
            var YAxisY :Number = XAxisY;

            if( _camera.isInFocus( YAxisY ) ) {
                var persepective:Number= _camera.getPersepective( YAxisZ );
                var tx:Number = YAxisX*persepective;
                var ty:Number = YAxisY*persepective;
                obj.render( tx, ty, persepective);
                obj.visible = true;
                _ZsortList.push( { z:YAxisZ, view:obj.view } );
            }
            else {
                obj.visible = false;
            }
        }

        // Zsort
        _ZsortList.sortOn( "z", Array.DESCENDING|Array.NUMERIC );
        l = _ZsortList.length;
        for( i=0; i<l; ++i ) {
            var zobj:Object = _ZsortList[i] as Object;
            _stage.setChildIndex( zobj.view, i );
        }
    }
    public function get renderList():Array{ return _renderList; }
}

class Camera3D{
    public var focus:Number = 500;
    public var x:Number = 0;
    public var y:Number = 0;
    public var z:Number = 0;
    public function getPersepective( tz :Number ):Number {
        return focus/( focus+tz );
    }
    public function isInFocus( tz:Number ):Boolean {
        var bool:Boolean = tz > -focus;
        return bool;
    }
    public var rotationX:Number = 0;
    public var rotationY:Number = 0;
    public var rotationZ:Number = 0;
}

class Ball extends Sprite {
    public function Ball() {
        //graphics.lineStyle(0,0xffffff);
        graphics.beginFill(0xcc6600, 0.8 );
        graphics.drawCircle( 0, 0, 6 );
        graphics.endFill();
    }
}