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

forked from: forked from: PapervisionMini3D

// forked from zerogravity's forked from: PapervisionMini3D
// forked from timknip's PapervisionMini3D
package {
    import flash.display.StageAlign;
    import flash.display.StageQuality;
    import flash.display.StageScaleMode;
    import flash.display.Graphics;
    import flash.display.Sprite;
    import flash.display.TriangleCulling;
    import flash.events.Event;
    import flash.geom.Matrix3D;
    import flash.geom.Utils3D;
    import flash.text.TextField;
    import flash.text.TextFormat;
    import net.hires.debug.Stats;

    [SWF (width="640", height="480", backgroundColor="#000000", frameRate="60")]

    public class PapervisionMini3D extends Sprite {
        private var _container :Sprite;
        private var _info :TextField;       
        private var _scene :SceneGraph3D;
        private var _camera :Camera3D;
        private var _cube :TriangleMesh3D;
        private var _stats :Stats;

        private var _modelingTransform :IRenderPipeProcessor;
        private var _viewingTransform :IRenderPipeProcessor;
        private var _renderSessionData :RenderSessionData;

        public function PapervisionMini3D() {
            super();

            stage.scaleMode = StageScaleMode.NO_SCALE;
	    stage.align = StageAlign.TOP_LEFT;
            stage.quality = StageQuality.LOW;

            _container = new Sprite();
            addChild(_container);
            _container.x = stage.stageWidth / 2;
            _container.y = stage.stageHeight / 2;
            
            _stats = new Stats();
            addChild(_stats);

            _info = new TextField();
            addChild(_info);
            _info.x = _info.y = 5;
            _info.width = 400;
            _info.height = 400;
            _info.multiline = true;
            _info.selectable = false;
            _info.defaultTextFormat = new TextFormat("Arial", 12, 0xff000);
            _info.text = "";

            _modelingTransform = new ModelingTransform();
            _viewingTransform = new ViewingTransform();
            _renderSessionData = new RenderSessionData();

            _scene = new SceneGraph3D();
            _camera = new Camera3D(50, 1.333, 0.01, 500, "Camera01");
            _camera.z = 30;
            _cube = buildCube(); 
              
            _scene.addChild(_camera);
            _scene.addChild(_cube);

            stage.addEventListener(Event.RESIZE, onStageResize);
            addEventListener(Event.ENTER_FRAME, onRenderTick);
        }
        
        private function onRenderTick(e:Event=null):void {	
            renderScene();

            _cube.rotationY += (Math.PI/180)*.2;
            
            Utils3D.projectVectors(_cube.viewTransform, _cube.vertices, 
                                   _cube.screenVertices, _cube.uvtData);

            _container.graphics.clear();

            draw(_cube.screenVertices, _cube.indices, _cube.uvtData);
        }

        public function renderScene():void {
            _renderSessionData.sceneGraph = _scene;
            _renderSessionData.camera = _camera;

            _modelingTransform.process(_renderSessionData);

            _camera.update();

            _renderSessionData.projection.rawData = _camera.worldTransform.rawData;
            _renderSessionData.projection.invert();
            _renderSessionData.projection.append(_camera.projection);

            _viewingTransform.process(_renderSessionData);
        }

        private function draw(verts:Vector.<Number>, indices :Vector.<int>, uvt:Vector.<Number>):void {
            var g :Graphics = _container.graphics;
            
            g.lineStyle(0, 0xff0000);
            g.drawTriangles(verts, indices, uvt, TriangleCulling.NEGATIVE);
            g.endFill();
        }

        protected function onStageResize(e:Event=null):void {
            _camera.aspect = stage.stageWidth / stage.stageHeight;
            _container.x = stage.stageWidth / 2;
            _container.y = stage.stageHeight / 2;
            _stats.x = stage.stageWidth - _stats.width - 10;
            _stats.y = 10;
        }

        private function buildCube(scale:Number=200):TriangleMesh3D {
            var mesh :TriangleMesh3D = new TriangleMesh3D("cube");
            mesh.vertices.push(-1 * scale, -1 * scale, 1 * scale);
            mesh.vertices.push(1 * scale, -1 * scale, 1 * scale);
            mesh.vertices.push(1 * scale, 1 * scale, 1 * scale);
            mesh.vertices.push(-1 * scale, 1 * scale, 1 * scale);

            mesh.vertices.push(-1 * scale, 1 * scale, -1 * scale);
            mesh.vertices.push(-1 * scale, -1 * scale, -1 * scale);
            mesh.vertices.push(-1 * scale, -1 * scale, 1 * scale);
            mesh.vertices.push(-1 * scale, 1 * scale, 1 * scale);
            mesh.screenVertices.push(0,0, 0,0, 0,0, 0,0);
            mesh.screenVertices.push(0,0, 0,0, 0,0, 0,0);
            mesh.uvtData.push(0,0,0, 0,0,0, 0,0,0, 0,0,0);
            mesh.uvtData.push(0,0,0, 0,0,0, 0,0,0, 0,0,0);
            mesh.indices = new Vector.<int>();
            mesh.indices.push(0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7);
            return mesh;
        }
    }
}

import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Matrix3D;
import flash.geom.Vector3D;

internal class DisplayObjectContainer3D {
    
    public var name :String;
    public var children :Vector.<DisplayObjectContainer3D>;
    public var parent :DisplayObjectContainer3D;
    
    public function DisplayObjectContainer3D(name:String=null) {
        this.name = name;
        children = new Vector.<DisplayObjectContainer3D>();
    }
    public function addChild(child:DisplayObjectContainer3D):DisplayObjectContainer3D {
        if(children.indexOf(child) == -1) {
            children.push(child);
        }
        return child;
    }
    public function removeChild(child:DisplayObjectContainer3D):DisplayObjectContainer3D {
        var idx :int = children.indexOf(child);
	if(idx >= 0) {
    	    child = children.splice(idx, 1)[0];
    	    child.parent = null;
	    return child;
	}
	return null;
    }
}

internal class DisplayObject3D extends DisplayObjectContainer3D {
    public var localTransform :Matrix3D;
    public var worldTransform :Matrix3D;
    public var viewTransform :Matrix3D;
    public var components :Vector.<Vector3D>;
    private var _orientation :Vector3D;
    private var _translation :Vector3D;
    private var _scale :Vector3D;

    public function DisplayObject3D(name:String=null) {
        super(name);
        localTransform = new Matrix3D();
        worldTransform = new Matrix3D();
        viewTransform = new Matrix3D();
        _orientation = new Vector3D();
        _translation = new Vector3D();
        _scale = new Vector3D(1, 1, 1);
        components = new Vector.<Vector3D>(3, true);
        components[0] = _translation;
	components[1] = _orientation;
        components[2] = _scale;
    }
    
    public function set x(value:Number):void {
        _translation.x = value;
    }
    public function get x():Number {
        return _translation.x;
    }
    public function set y(value:Number):void {
        _translation.y = value;
    }
    public function get y():Number {
        return _translation.y;
    }
    public function set z(value:Number):void {
        _translation.z = value;
    }
    public function get z():Number {
        return _translation.z;
    }
    public function set rotationX(value:Number):void {
        _orientation.x = value;
    }
    public function get rotationX():Number {
        return _orientation.x;
    }
    public function set rotationY(value:Number):void {
        _orientation.y = value;
    }
    public function get rotationY():Number {
        return _orientation.y;
    }
    public function set rotationZ(value:Number):void {
        _orientation.z = value;
    }
    public function get rotationZ():Number {
        return _orientation.z;
    }
    public function updateTransform():void {
        localTransform.recompose(components);
    }
}

internal class Vertices3D extends DisplayObject3D {
    public var vertices :Vector.<Number>;  
    public var viewVertices :Vector.<Number>;   
    public var screenVertices :Vector.<Number>; 
    public var uvtData :Vector.<Number>; 
    public var indices :Vector.<int>;

    public function Vertices3D(name:String=null) {
        super(name);
        vertices = new Vector.<Number>();
        viewVertices = new Vector.<Number>();
        screenVertices = new Vector.<Number>();
        uvtData = new Vector.<Number>();
    }
}

internal class TriangleMesh3D extends Vertices3D {
    
    public function TriangleMesh3D(name:String=null) {
        super(name);
    }
}

internal class SceneGraph3D extends DisplayObject3D {
}

internal class Camera3D extends DisplayObject3D {
    public var projection :Matrix3D;
    private var _fov :Number;
    private var _aspect :Number;
    private var _near :Number;
    private var _far :Number;
    private var _dirty :Boolean;

    public function Camera3D(fov:Number=90, aspect:Number=1.333, 
                             near:Number=1, far:Number=10000, name:String=null) {
        super(name);
        this.fov = fov;
        this.aspect = aspect;
        this.near = near;
        this.far = far;
        update();
    }
    public function set fov(value:Number):void { 
        if(value != _fov) {
            _fov = value; 
            _dirty = true;
        }
    }
    public function get fov():Number { return _fov; }
    public function set aspect(value:Number):void { 
        if(_aspect != value) {
             _aspect = value;
             _dirty = true; 
        }
    }
    public function get aspect():Number { return _aspect; }
    public function set near(value:Number):void { 
        if(_near != value) {
            _near = value;
            _dirty = true;
        } 
    }
    public function get near():Number { return _near; }
    public function set far(value:Number):void { 
        if(_far != value) {
            _far = value; 
            _dirty = true; 
        }
    }
    public function get far():Number { return _far; }
    public function update():void {
        if(_dirty) {
            _dirty = false;
            projection = init(_fov, _aspect, _near, _far);
        }
    }
    private function init(fovy:Number=90, aspect:Number=1.333, 
                          near:Number=1, far:Number = 10000):Matrix3D {
         var fov2:Number = (fovy/2) * (Math.PI/180);
         var tan:Number = Math.tan(fov2);
         var f:Number = 1 / tan;
         var v:Vector.<Number> = new Vector.<Number>(16, true);
         v[0] = f / aspect;
         v[1] = v[2] = v[3] = v[4] = 0;
         v[5] = f;
         v[6] = v[7] = v[8] = v[9] = v[12] = v[13] = v[15] = 0;
         v[10] = (near+far) / (near-far);
         v[11] = (2*far*near) / (near-far);
         v[14] = -1;
         return new Matrix3D(v);
     }
}

internal class RenderSessionData {
    public var sceneGraph :DisplayObject3D;
    public var camera :Camera3D;
    public var projection :Matrix3D;
    public function RenderSessionData() {
        projection = new Matrix3D();
    }
}

internal interface IRenderPipeProcessor {
    function process(renderSessionData:RenderSessionData):void;    
}

internal class ModelingTransform implements IRenderPipeProcessor {
    public function ModelingTransform() {}
    public function process(renderSessionData:RenderSessionData):void {
        transform(renderSessionData.sceneGraph);
    }
    private function transform(object:DisplayObject3D):void {
        for each(var child:DisplayObject3D in object.children) {
            child.updateTransform();
            child.worldTransform.rawData = object.worldTransform.rawData;
            child.worldTransform.append(child.localTransform);
            transform(child);
        }
    }
}

internal class ViewingTransform implements IRenderPipeProcessor {
    public function ViewingTransform() {}
    public function process(renderSessionData:RenderSessionData):void {
        transform(renderSessionData.sceneGraph, renderSessionData.projection);
    }
    private function transform(object:DisplayObject3D, projection:Matrix3D):void {
        for each(var child:DisplayObject3D in object.children) {
            child.viewTransform.rawData = child.worldTransform.rawData;
            child.viewTransform.append(projection);
            transform(child, projection);
        }
    }
}