Matrix3D Universe Test02

by bradsedito
import caurina.transitions.Tweener;
♥0 | Line 229 | Modified 2011-07-27 09:31:29 | MIT License
play

ActionScript3 source code

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




package
{
    import flash.display.Sprite;
    import flash.display.DisplayObject;
    import flash.display.StageQuality;
    import flash.events.Event;
    import flash.utils.setInterval;
    import com.greensock.*;
    import com.greensock.easing.*;
    import net.hires.debug.Stats;

    [SWF(backgroundColor=0xffffff, frameRate=60)] 

    public class Matrix3DUniverse extends Sprite 
    {
        public const mX:Number = new Number( stage.mouseX );
        public const mY:Number = new Number( stage.mouseY );
        private var _scene:Scene3D;
        private var _camera:Camera3D;
        private var _easeCamera:EaseObject;
        private var screenX:Number;
        private var screenY:Number;
        private var stats:Stats = new Stats();
        
        public function Matrix3DUniverse() 
        {
            addChild(stats);
            stage.quality = StageQuality.HIGH;
            
            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 = 10, yNum:uint = 10 , zNum:uint = 10;
            var xInterval:uint = 10, yInterval:uint = 10, zInterval:uint =40;
            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 = 1.0;  //  0.5; 
                TweenMax.to( obj, 2, {z:tz, ease:Quad.easeInOut});
            }
        }

        private function changeScale():void {
            var l:uint = _scene.renderList.length;
            var scale :Number = 2*Math.random()+0.4;
            var rotation:Number = 0; // 360*Math.random();
            for( var i:uint=0; i<l; ++i ) {
                var obj:DisplayObject3D =  _scene.renderList[i];
                TweenMax.to( obj, 2, {rotationX:rotation, rotationY:rotation, rotationZ:rotation, scaleX:scale , scaleY:scale , scaleZ:scale, ease:Quad.easeInOut});            
            }
        }
        private function enterframeHandler (e:Event):void{
            _easeCamera.vRotateX = 0; //1;
            _easeCamera.vRotateY = 0; //1;
            _easeCamera.vRotateZ = 0; //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.appendRotation(rotateX, Vector3D.X_AXIS);
        matrix.appendRotation(rotateY, Vector3D.Y_AXIS);
        matrix.appendRotation(rotateZ, Vector3D.Z_AXIS);
        matrix.appendScale( scaleX, scaleY, scaleY );
        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 = 100;
    
    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.beginFill(0x131413, 1 );
        graphics.drawCircle( 0, 0, 2 );
        graphics.endFill();
     // graphics.lineStyle(0,0xffffff);
     // filters = [ new BlurFilter() ];
     // cacheAsBitmap = true;
    }
}