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

Vertex 3D model

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

/**
 * @title Pixel Surface Model
 * @author Simo Endre (esimov)
 *
 * High resolution vertex data models can be found @ http://www.cyberware.com/products/scanners/pxSamples.html
 * Other scan samples @ http://graphics.stanford.edu/data/3Dscanrep/
 * For vertex point extraction i used a program from Kárpáti Zoltán (http://web.axelero.hu/karpo/) 
 * and slightly modified the obtained txt file for my own purposes.
 * We need only the x, y and z coordinate, so other aditional information can be deleted.
 * */

package
{    
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.BitmapDataChannel;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.events.ProgressEvent;
    import flash.events.IOErrorEvent;
    import flash.filters.BitmapFilterQuality;
    import flash.filters.BlurFilter;
    import flash.geom.ColorTransform;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    import flash.text.TextField;
    import flash.text.TextFormat;
    import flash.net.URLLoader;
    import flash.net.URLLoaderDataFormat;
    import flash.net.URLRequest;
    import flash.system.ApplicationDomain;
    import flash.system.SecurityDomain;
    import flash.system.LoaderContext;
    import flash.system.Security;
    import flash.errors.IllegalOperationError;
    import flash.utils.getTimer;
    
    import net.hires.debug.Stats;
    import com.bit101.components.Style;
    import com.bit101.components.Label;
    
    [SWF (backgroundColor = 0x00, width = '465', height = '465')]

    public class PixelSurfaceModel extends Sprite
    {
        private const WIDTH:Number = stage.stageWidth;
        private const HEIGHT:Number = stage.stageHeight;
        private static const PHI:Number = 3.14159265;
        
        private var _fl:Number = 250;
        private var _phi:Number;
        private var _theta:Number;
        private var _minDepth:Number;
        private var _maxDepth:Number;
        private var _expInt:Number;
        private var _expRate:Number;
        private var _maxLevel:Number;
        
        private var _projCenterX:Number;
        private var _projCenterY:Number;
        private var _numParticles:Number;
        private var _firstParticle:Particle3D;
        
        private var _screen:Sprite;
        private var _bmpData:BitmapData;
        private var _bmp:Bitmap;
        private var _ct:ColorTransform;
        private var _blur:BlurFilter;
        private var _particles:TextField;
        
        private var _loader:URLLoader;
        private var _label:Label;
        private var _vertices:Vector.<Number>;
        
        private var mousePressed:Boolean = false;
        
        public function PixelSurfaceModel():void
        {
            if (stage) initStage(null);
            else {
                addEventListener(Event.ADDED_TO_STAGE, initStage);
                throw new Error("Stage not initialized");
            }
        }
        
        private function initStage(event:Event):void
        {
            stage.align = StageAlign.TOP_LEFT;
            stage.frameRate = 60;
            stage.quality = "heigh";
            
            init();
        }
        
        private function init():void
        {
            _screen = new Sprite();
            _screen.x = _screen.y = 0;
            addChild(_screen);
            
            Wonderfl.capture_delay(10);
            _label = new Label(_screen, 0, HEIGHT - 15, "Loading File...");
            Security.loadPolicyFile("http://esimov.zxq.net/crossdomain.xml");
            var context:LoaderContext = new LoaderContext();
            context.checkPolicyFile = true;
            context.applicationDomain = ApplicationDomain.currentDomain;
            context.securityDomain = SecurityDomain.currentDomain;
            _loader = new URLLoader();
            _loader.load(new URLRequest("http://esimov.zxq.net/vertex_model.txt"));
            _loader.addEventListener(ProgressEvent.PROGRESS, onLoadProgress);
            _loader.addEventListener(IOErrorEvent.IO_ERROR, onLoadError);
            _loader.addEventListener(Event.COMPLETE, onLoadComplete);
        }
        
        private function onLoadProgress(event:ProgressEvent):void
        {
            var perc:int = int(event.bytesLoaded / event.bytesTotal) * 100;
            _label.text = "Loading: " + perc + " %";
            if (perc >= 100)
            _screen.removeChild(_label);
        }
        
        private function onLoadError(event:IOErrorEvent):void
        {
            throw new IllegalOperationError("Loading source file has failed...");
        }
        
        
        private function onLoadComplete(event:Event):void
        {
            _loader.removeEventListener(Event.COMPLETE, onLoadComplete);
            _loader.removeEventListener(ProgressEvent.PROGRESS, onLoadProgress);
            
            _vertices = new Vector.<Number>();
            var stringData:String = event.target.data as String;
            var delimitator:RegExp = /\s+/;
            var stringArr:Array = stringData.split(delimitator);
            _numParticles = stringArr.length / 5;
            
            for (var i:Number = 0; i < stringArr.length; i++)
            {
                _vertices.push(Number(stringArr[i]));
            }
            
            var level0:Number = 1/_fl;
            var level1:Number = 1;
            _minDepth = -100;
            _maxDepth = 120;
            _maxLevel = 255;
            
            _expInt = (Math.log(level0) - Math.log(level1)) / (_minDepth - _maxDepth);
            _expRate = _maxLevel * level1 + Math.pow(level1/level0, _minDepth/ (_minDepth - _maxDepth));
            
            _theta = 3*PHI/2;
            _phi = - PHI/4;
            
            _bmpData = new BitmapData(WIDTH, HEIGHT, true, 0xff000000);
            _bmp = new Bitmap(_bmpData);
            _screen.addChild(_bmp);
            
            var tf:TextFormat = new TextFormat("Verdana", 10);
            _particles = new TextField();
            _particles.defaultTextFormat = tf;
            _particles.background = true;
            _particles.backgroundColor = 0x333333;
            _particles.autoSize = "right";
            _particles.textColor = 0xffffff;
            _particles.x = WIDTH - _particles.textWidth - 5;
            _particles.text = "";
            
            addChild(new Stats());
            _screen.addChild(_particles);
            
            _ct = new ColorTransform(0.8, 0.8, 0.8);
            _blur = new BlurFilter(2, 2, BitmapFilterQuality.MEDIUM); 
            
            _projCenterX = _screen.width >> 1;
            _projCenterY = _screen.height >> 1;
            
            createParticles();
            
            stage.addEventListener(MouseEvent.MOUSE_DOWN, onMousePress);
            stage.addEventListener(MouseEvent.MOUSE_UP, onMousePress);
            addEventListener(Event.ENTER_FRAME, beginTest);
        }
        
        private function onMousePress(event:MouseEvent):void
        {
            switch(event.type)
            {
                case "mouseDown":
                mousePressed = true;
                break;
                
                case "mouseUp":
                mousePressed = false;
                break;
                
                default:
                break;
            }
        }
        
        private function beginTest(event:Event):void
        {
            var p:Particle3D = _firstParticle;
            var dx:Number = 0;
            var dy:Number = 0;
            
            if (!mousePressed)
            {
                dx = 0.00824 * Math.cos(getTimer() * 0.0001855);
                dy = 0.00824 * Math.sin(getTimer() * 0.0001855);
            }
            else
            {
                dx = 0.0002 * (mouseY - _projCenterY);
                dy = 0.0002 * (mouseX - _projCenterX);
            }
            
            _phi = dx + _phi;
            _theta = dy + _theta;
            
            var cosP:Number = Math.cos(_phi);
            var sinP:Number = Math.sin(_phi);

            var cosT:Number = Math.cos(_theta);
            var sinT:Number = Math.sin(_theta);
            
            var C11:Number = cosT * sinP;
            var C12:Number = sinT * sinP;
            var C21:Number = - cosP * cosT;
            var C22:Number = - sinT * cosP;
            
            _bmpData.lock();
            _bmpData.applyFilter(_bmpData, _bmpData.rect, new Point(), _blur);
            _bmpData.colorTransform(_bmpData.rect, _ct);
            
            do
            {                
                p.u = C11 * p.x + C12 * p.y + cosP * p.z;
                p.v = - sinT * p.x + cosT * p.y;
                p.w = C21 * p.x + C22 * p.y + sinP * p.z;
                
                var df:Number = _fl / (_fl - p.u);
                p.projX = df * p.v + _projCenterX;
                p.projY = df * p.w + _projCenterY;
                
                if (p.projX < 0 || p.projX > WIDTH || p.projY < 0 || p.projY > HEIGHT)
                {
                    p.onScreen = false;
                } else { p.onScreen = true }
                
                if (p.onScreen)
                {
                    var color:uint = _bmpData.getPixel(p.projX, p.projY) & 0xff;
                    var level:Number = _expRate*Math.exp(_expInt*p.u);
                    level = (level > _maxLevel) ? _maxLevel : level;
                    
                    if (level > color)
                    _bmpData.setPixel(p.projX, p.projY,(level << 16 | level << 8 | level));
                }
                
                p = p.next;
                
            } while (p != null);
            
            _bmpData.unlock();
        }
        
        private function createParticles():void
        {
            var prevParticle:Particle3D;
            var scale:Number = 2200;
            var offsetX:Number = 0.0182325;
            var offsetY:Number = -0.089232;
            var offsetZ:Number = -0.0092234;
            
            for (var i:Number = 0; i < _numParticles; i++)
            {
                var particle:Particle3D = new Particle3D(0x00);
                particle.x = scale * (_vertices[i*5] + offsetX);
                particle.y = scale * (_vertices[i*5+1] + offsetY);
                particle.z = scale * (_vertices[i*5+2] + offsetZ);
                
                particle.next = prevParticle;
                prevParticle = particle;
            }
            
            _firstParticle = particle;
            _particles.text = _numParticles + " particles";
        }
    }
}


internal class Point3D
{
    public var x:Number;
    public var y:Number;
    public var z:Number;
    
    public function Point3D(x:Number = 0, y:Number = 0, z:Number = 0):void
    {
        this.x = x;
        this.y = y;
        this.z = z;
    }
}


internal class Particle3D extends Point3D
{
    public var red:uint;
    public var green:uint;
    public var blue:uint;
    public var color:uint;
    
    public var projX:Number;
    public var projY:Number;
    
    public var u:Number;
    public var v:Number;
    public var w:Number;
    
    public var next:Particle3D;
    public var onScreen:Boolean;
    
    public function Particle3D(color:uint = 0xFFFFFF):void
    {
        this.color = color;
        this.red = getRed(color);
        this.green = getGreen(color);
        this.blue = getBlue(color);
    }
    
    public function getRed(c:uint):uint
    {
        return c >> 16 & 0xff;
    }
    
    public function getGreen(c:uint):uint
    {
        return c >> 08 & 0xff;
    }
    
    public function getBlue(c:uint):uint
    {
        return c >> 00 & 0xff;
    }
}