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演習その5 +Matrix3DとScaleとRotate

ActionScript3.0Animation読みながら、とりあえず3D投影してみる。
Z軸で動かしてみる
Camera を導入してみる
Camera を回転させてみた
Zsortをつけてみた
Camera.rotationY がおかしいのを直した。
ぐるぐる回してみる。
Matrix3Dにしてみた
せっかくなのでObject3Dに抽象化&ScaleとRotate実装
// forked from yd_niku's 3D演習その4 +Camera3Dの回転2
// 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 がおかしいのを直した。
    // ぐるぐる回してみる。
    // Matrix3Dにしてみた
    // せっかくなのでObject3Dに抽象化&ScaleとRotate実装
    import flash.display.Sprite;
    import flash.display.DisplayObject;
    import flash.display.StageQuality;
    import flash.events.Event;
    import flash.utils.setInterval;
    import caurina.transitions.Tweener;

    [SWF (backgroundColor='#000A22',frameRate=60)]

    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.quality = StageQuality.MEDIUM;
            setup();

            putThemFar();
            setInterval( changeScale, 2500 );

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

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

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

            var xNum:uint = 8, yNum:uint =8, zNum:uint = 8;
            var xInterval:uint = 15, yInterval:uint = 15, zInterval:uint =15;
            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;
                obj.scaleX = obj.scaleY= obj.scaleZ = 0.5;
                Tweener.addTween( obj, {  z: tz, time:2, delay:1, transition:"easeInOutQuart" } );
            }
        }

        private function changeScale():void {
            var l:uint = _scene.renderList.length;
            var scale :Number = 2*Math.random()+0.4;
            var rotation:Number = 360*Math.random();
            for( var i:uint=0; i<l; ++i ) {
                var obj:DisplayObject3D =  _scene.renderList[i];
                Tweener.addTween( obj, { rotateX:rotation, rotateY:rotation, rotateX:rotation, scaleX:scale , scaleY:scale , scaleZ:scale,  time:2, transition:"easeInOutQuart" } );
            }
        }
        private function enterframeHandler (e:Event):void{
            _easeCamera.vRotateX = 1;
            _easeCamera.vRotateY = 1;
            _easeCamera.vRotateZ = 1;
            _easeCamera.calcuration();
        }

    }
}


class EaseObject {
    public var vx :Number = 0;
    public var vy :Number = 0;
    public var vz :Number = 0;
    public var vRotateX:Number = 0;
    public var vRotateY:Number = 0;
    public var vRotateZ: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;
        vRotateX *= friction;
        vRotateY *= friction;
        vRotateZ *= friction;

        _target.x += vx;
        _target.y += vy;
        _target.z += vz;
        _target.rotateX+= vRotateX;
        _target.rotateY+= vRotateY;
        _target.rotateZ+= vRotateZ;
    }
}

import flash.display.*;
import flash.events.*;
import flash.geom.*;

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 matrixCamera:Matrix3D = _camera.getMatrix3D();

        var l:uint = _renderList.length;
        for( var i:uint=0; i<l; ++i ) {
            var obj:DisplayObject3D= _renderList[i];
            var matrixObj :Matrix3D = obj.getMatrix3D();

            var p:Vector3D = new Vector3D(obj.x,obj.y,obj.z);
            p = matrixObj.transformVector( p );
            p = matrixCamera.transformVector( p );

            if( _camera.isInFocus( p.z) ) {
                var persepective:Number= _camera.getPersepective(p.z);
                var tx:Number = p.x*persepective;
                var ty:Number = p.y*persepective;
                obj.render( tx, ty, persepective);
                obj.visible = true;
                _ZsortList.push( { z:p.z, 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 Object3D {
    public static var screenX:Number = 0;
    public static var screenY:Number = 0;

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

    public var scaleX:Number = 1.0;
    public var scaleY:Number = 1.0;
    public var scaleZ:Number = 1.0;

    public var rotateX:Number = 0.0;
    public var rotateY:Number = 0.0;
    public var rotateZ:Number = 0.0;

    public function getMatrix3D():Matrix3D {
        var matrix:Matrix3D = new Matrix3D();
        matrix.appendTranslation(x, y, z);
        matrix.appendScale( scaleX, scaleY, scaleY );
        matrix.appendRotation(rotateX, Vector3D.X_AXIS);
        matrix.appendRotation(rotateY, Vector3D.Y_AXIS);
        matrix.appendRotation(rotateZ, Vector3D.Z_AXIS);
        return matrix;
    }
}

class DisplayObject3D extends Object3D {
    public var view:DisplayObject;
    public function DisplayObject3D( view:DisplayObject=null ) {
        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 Camera3D extends Object3D {
    public var focus:Number = 500;
    public function getPersepective( tz :Number ):Number {
        return focus/( focus+tz );
    }
    public function isInFocus( tz:Number ):Boolean {
        var bool:Boolean = tz > -focus;
        return bool;
    }
}

import flash.filters.*;
class Ball extends Sprite {
    public function Ball() {
        //graphics.lineStyle(0,0xffffff);
        graphics.beginFill(0xff9900, 1 );
        graphics.drawCircle( 0, 0, 5 );
        graphics.endFill();
//        filters = [ new BlurFilter() ];
//        cacheAsBitmap = true;
    }
}