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: movieProjector

Get Adobe Flash player
by sachiotsubouchi 28 Oct 2010
/**
 * Copyright sachiotsubouchi ( http://wonderfl.net/user/sachiotsubouchi )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/hZtv
 */

// forked from zonnbe's movieProjector
package  {
    import flash.display.*;
    import flash.filters.*;
    import flash.events.*;
    import flash.net.*;
    import flash.utils.*;
    import flash.geom.*;
    import flash.text.*;
    import flash.system.*;
    import flash.ui.*;
    import flash.media.*;
    import net.hires.debug.Stats;
    import com.bit101.components.PushButton;
    
    [SWF(width=465,height=465,backgroundColor=0x222222,frameRate=30)]
    public class movieProjector extends Sprite
    {
        // 3d
        private var focal          :Number                = 0;
        private var viewport       :Shape                 = new Shape();
        private var world          :Matrix3D              = new Matrix3D();
        private var projected      :Vector.<Number>       = new Vector.<Number>;
        private var projection     :PerspectiveProjection = new PerspectiveProjection();
        
        //objects
        private var _faces         :Array                 = [];
        private var trans          :Matrix3D              = new Matrix3D();
        private var cubes          :Vector.<Cube>         = new Vector.<Cube>;
        private var _indices       :Vector.<int>          = new Vector.<int>;
        private var _sortedIndices :Vector.<int>          = new Vector.<int>;
        private var _uvNorms       :Vector.<Number>       = new Vector.<Number>;
        private var _statics       :Vector.<Number>       = new Vector.<Number>;
        private var _verts         :Vector.<Number>       = new Vector.<Number>;
        
        //graphics
        private var FILE_PATH      :String                = "http://our-work.com.my/livetesting/";
        private var urls           :Vector.<String>       = new Vector.<String>;
        private var images         :Vector.<BitmapData>   = new Vector.<BitmapData>;
        private var framePrj       :BitmapData;
        private var skin           :BitmapData;
        
        //interaction
        private var dragging       :Boolean               = false;
        private var drag_mode      :Boolean               = false;
        private var ct             :ColorTransform        = new ColorTransform(1,1,1,0.7);
        private var old_mouse      :Point                 = new Point();
        private var new_mouse      :Point                 = new Point();
        
        //video
        private var playing        :Boolean               = false;
        private var VIDEO_URL      :String                = "thisishalloween3.flv";
        private var VIDEO_WIDTH    :int                   = 320;
        private var VIDEO_HEIGHT   :int                   = 240;
        private var ns             :NetStream;
        private var nc             :NetConnection;
        private var video          :Video;
        private var video_bmpd     :BitmapData;
        private var video_pos      :Point                 = new Point();
        
        public function movieProjector()
        {
            //(in case we need more images)
            urls.push(
                "wall.jpg",
                "thisishalloween.jpg"
            );
            beginLoad();
        }
        private function beginLoad():void{
            var ld:Loader = new Loader();
            ld.contentLoaderInfo.addEventListener(Event.COMPLETE , loadComplete );
            var url:String = urls.shift();
            ld.load( new URLRequest(FILE_PATH+url) , new LoaderContext(true));
        }
        private function loadComplete(e:Event):void{
            try
            {
                images.push(Bitmap(e.target.content).bitmapData);
            } catch(e:Error) {}
            if(urls.length >0){
                beginLoad();
            }else{
                init();
            }
        }
        private function init(e:Event = null):void
        {
            skin        = images[0];
            framePrj    = new BitmapData(stage.stageWidth, stage.stageHeight, true, 0x0);
            video_bmpd  = new BitmapData(VIDEO_WIDTH, VIDEO_HEIGHT, false, 0x0);
            video_pos.x = (framePrj.width  - video_bmpd.width )/2;
            video_pos.y = (framePrj.height - video_bmpd.height)/2;
            video_bmpd.copyPixels(images[1], images[1].rect, new Point());
            init3D();
        }
        private function init3D():void
        {
            viewport.x = stage.stageWidth / 2;
            viewport.y = stage.stageHeight / 2;

            projection.fieldOfView = 45;
            focal = projection.focalLength;

            var i:int = 0;
            var j:int = 0;
            var temp_length:int = 0;
            for(i = 0; i < 16; i++)
            {
                cubes.push(new Cube(i, -150 + (i%4)*100, -150 + int(i/4)*100 ,0, 80, 80, 80));
                temp_length += cubes[i]._uvts.length;
                _indices = _indices.concat(cubes[i]._indices);
            }
            
            var panel:Sprite = new Sprite;
            new PushButton(panel, stage.stageWidth - 125, 5, "switch drag mode", onSDM).setSize(120, 16);
            new PushButton(panel, stage.stageWidth - 250, 5, "play/pause video", onPV ).setSize(120, 16);
            
            addChild(viewport);
            addChild(panel);
            addChild(new Stats());
            stage.addEventListener(Event.ENTER_FRAME, processing);
            stage.addEventListener(MouseEvent.MOUSE_DOWN, onmouseDown);
            stage.addEventListener(MouseEvent.MOUSE_UP, onmouseUp);
            stage.addEventListener(MouseEvent.MOUSE_MOVE, onmouseMove);
        }
        
        private function playVideo():void
        {
            if(!nc)
            {
                nc = new NetConnection();
                nc.connect(null);
                
                ns = new NetStream(nc);
                ns.addEventListener(NetStatusEvent.NET_STATUS, videoNetStatusHandler);
                ns.client = {
                    onMetaData:function(param:Object):void{}
                };
                ns.checkPolicyFile = true;
                ns.play(FILE_PATH+VIDEO_URL);
                
                video = new Video();
                video.attachNetStream(ns);                
            } else { ns.resume(); playing = !playing;}
            
        }
        
        private function videoNetStatusHandler(e:NetStatusEvent):void 
        {
            switch(e.info.code) {                    
                case "NetStream.Play.Start":
                    playing = !playing;
                break;
                case "NetStream.Play.Stop":
                    ns.seek(0); //replay
                break;
            }
        }
        
        private function processing(e:Event):void
        {
            update();
            render();
        }
        
        private function update():void
        {
            var i:int = 0;
            var j:int = 0;
            var face:Face;
            var inc:int = 0;
            var matrix:Matrix3D = new Matrix3D();
            
            //flush
            _sortedIndices.splice(0,_sortedIndices.length);
            //_indices.splice(0, _indices.length); //not sorting indices for now
            _faces.splice(0, _faces.length);
            _uvNorms.splice(0, _uvNorms.length);
            _statics.splice(0, _statics.length);
            _verts.splice(0, _verts.length);
            
            for(i = 0; i < cubes.length; i++)
            {
                cubes[i].crx = getTimer() * cubes[i].rx;
                cubes[i].cry = getTimer() * cubes[i].ry;
                cubes[i].crz = getTimer() * cubes[i].rz;
                
                matrix.identity();
                
                matrix.appendRotation(cubes[i].crx, Vector3D.X_AXIS);
                matrix.appendRotation(cubes[i].cry, Vector3D.Y_AXIS);
                matrix.appendRotation(cubes[i].crz, Vector3D.Z_AXIS);
                matrix.transformVectors(cubes[i]._vNorms, cubes[i]._uvNorms);

                matrix.appendTranslation(cubes[i].x, cubes[i].y, 0); //ignore z
                matrix.transformVectors(cubes[i]._verts, cubes[i]._mverts);
                
                for(j = 0; j < cubes[i]._uvNorms.length; j+=3)
                {
                    cubes[i]._uvNorms[j    ] = cubes[i].x/stage.stageWidth  + 0.5 + cubes[i]._uvNorms[j    ] * 0.15;
                    cubes[i]._uvNorms[j + 1] = cubes[i].y/stage.stageHeight + 0.5 + cubes[i]._uvNorms[j + 1] * 0.15;
                    //cubes[i]._uvNorms[j + 2] = 0.5 + cubes[i]._uvNorms[j + 2] * 0.15; // redundant
                }

                _sortedIndices = _sortedIndices.concat(cubes[i]._indices);
                _faces = _faces.concat(cubes[i]._faces);
                _uvNorms = _uvNorms.concat(cubes[i]._uvNorms);
                _statics = _statics.concat(cubes[i]._static);
                _verts = _verts.concat(cubes[i]._mverts);
            }
            world.identity();
            world.append(trans);
            world.appendTranslation(0, 0, focal);
            world.append(projection.toMatrix3D());
            
            Utils3D.projectVectors(world, _verts, projected, _uvNorms);
            Utils3D.projectVectors(world, _verts, projected, _statics);

            for (i = 0; i<_indices.length; i+=3){
                face = _faces[inc];
                face.i0 = _indices[i];
                face.i1 = _indices[int(i + 1)];
                face.i2 = _indices[int(i + 2)];
                var i3:int = i * 3;
                face.z = (_uvNorms[int(face.i0*3 + 2)] + _uvNorms[int(face.i1*3 + 2)] + _uvNorms[int(face.i2*3 + 2)]) * 0.333333;
                inc++;
            }
            _faces.sortOn("z", Array.NUMERIC);
            inc = 0;
            for each (face in _faces){
                _sortedIndices[inc++] = face.i0;
                _sortedIndices[inc++] = face.i1;
                _sortedIndices[inc++] = face.i2;
            }
        }
        
        private function render():void
        {
            if(playing) video_bmpd.draw(video); //update video bitmapdata
            framePrj.fillRect(framePrj.rect, 0x0);
            framePrj.copyPixels(video_bmpd, video_bmpd.rect, video_pos);
            framePrj.colorTransform(framePrj.rect, ct);
            
            viewport.graphics.clear();
            viewport.graphics.beginBitmapFill(skin, null, false, false);
            //viewport.graphics.drawTriangles(projected, _sortedIndices, _uvNorms, TriangleCulling.NEGATIVE);
            viewport.graphics.drawTriangles(projected, _indices, _statics, TriangleCulling.NEGATIVE); //_indices will not be sorted for now
            viewport.graphics.endFill();
            
            viewport.graphics.beginBitmapFill(framePrj, null, false, false);
            viewport.graphics.drawTriangles(projected, _sortedIndices, _uvNorms, TriangleCulling.NEGATIVE);
            //viewport.graphics.drawTriangles(projected, _indices, _statics, TriangleCulling.NEGATIVE);
            viewport.graphics.endFill();
        }
        
        /////events
        private function onSDM(...arg):void
        {
            drag_mode = !drag_mode;
        }
        
        private function onPV(...arg):void
        {
            if(!playing)
            {
                playVideo();
            } else {
                ns.pause();
                playing = !playing;
            }
        }
        
        private function onmouseDown(e:MouseEvent):void
        {
            old_mouse.x = mouseX;
            old_mouse.y = mouseY;
            dragging = true;
        }
        
        private function onmouseMove(e:MouseEvent):void
        {
            if(dragging)
            {
                if(!drag_mode)
                {
                    video_pos.x = mouseX-150;
                    video_pos.y = mouseY-100;
                } else {
                    new_mouse.x = mouseX
                    new_mouse.y = mouseY;
                    
                    var difference:Point = new_mouse.subtract(old_mouse);
                    var vector:Vector3D = new Vector3D(difference.x, difference.y, 0);
     
                    var rotationAxis:Vector3D = vector.crossProduct(new Vector3D(0,0,1));
                    rotationAxis.normalize();
     
                    var distance:Number = Point.distance(new_mouse, old_mouse);
                    var rotationMatrix:Matrix3D = new Matrix3D();
                    rotationMatrix.appendRotation(distance, rotationAxis);
                    
                    trans.append(rotationMatrix);
     
                    old_mouse.x = new_mouse.x;
                    old_mouse.y = new_mouse.y;
                }
            }
        }
        
        private function onmouseUp(e:MouseEvent):void
        {
            dragging = false;
        }
    }
    
}

class Cube
{
    public var x         :Number          = 0;
    public var y         :Number          = 0;
    public var z         :Number          = 0;
    public var rx        :Number          = 0;
    public var ry        :Number          = 0;
    public var rz        :Number          = 0;
    public var crx       :Number          = 0;
    public var cry       :Number          = 0;
    public var crz       :Number          = 0;
    public var _faces    :Array           = new Array();
    public var _indices  :Vector.<int>    = new Vector.<int>;
    public var _verts    :Vector.<Number> = new Vector.<Number>;
    public var _mverts   :Vector.<Number> = new Vector.<Number>;
    public var _vNorms   :Vector.<Number> = new Vector.<Number>;
    public var _uvts     :Vector.<Number> = new Vector.<Number>;
    public var _uvNorms  :Vector.<Number> = new Vector.<Number>;
    public var _static   :Vector.<Number> = new Vector.<Number>;
    
    public function Cube(id:int, px:Number, py:Number, pz:Number, w:Number, h:Number, leng:Number):void{
        x = px;
        y = py;
        z = pz;
        rx =  Math.random()*0.05;
        ry =  Math.random()*0.05;
        rz =  Math.random()*0.05;
        rx = (Math.random()< 0.5)?-rx:rx;
        ry = (Math.random()< 0.5)?-ry:ry;
        rz = (Math.random()< 0.5)?-rz:rz;
        var hw    :Number = w    * 0.5;
        var hh    :Number = h    * 0.5;
        var hl    :Number = leng * 0.5;
        var xA    :Number = -hw;
        var xB    :Number =  hw;
        var yA    :Number = -hh;
        var yB    :Number =  hh;
        var zA    :Number = -hl;
        var zB    :Number =  hl;
        var index :int    = id   * 24; // each cube has 24 indices
        var i     :int    = 0;
        /*
        *             4_________5
        *            /\         /\
        *           /  \       /  \
        *          0____\_____1    \
        *          \     6____\_____7
        *           \    /     \   /       ^" ,,, ^"
        *            \  /       \ /       (<o>_._<o>)  < modified from http://actionsnippet.com/?p=2158
        *             2/_________3         `u---u--c)~                 http://wonderfl.net/c/dy0Z/
        *                                                                             thanks @shapevent
        **************************************************************************************************/
        //////////////////////id..    index..      face..
        _verts.push(
                    xA, yA, zA, //0        //0         //FRONT
                    xB, yA, zA, //1        //1
                    xA, yB, zA, //2        //2
                    xB, yB, zA, //3        //3
                    
                    xA, yB, zB, //6        //4         //BACK
                    xB, yB, zB, //7        //5
                    xA, yA, zB, //4        //6
                    xB, yA, zB, //5        //7
                    
                    xB, yA, zA, //1        //8         //RIGHT
                    xB, yA, zB, //5        //9
                    xB, yB, zA, //3        //10
                    xB, yB, zB, //7        //11
                    
                    xA, yA, zB, //4        //12        //TOP
                    xB, yA, zB, //5        //13
                    xA, yA, zA, //0        //14
                    xB, yA, zA, //1        //15
                    
                    xA, yB, zA, //2        //16        //LEFT
                    xA, yB, zB, //6        //17
                    xA, yA, zA, //0        //18
                    xA, yA, zB, //4        //19
                    
                    xA, yB, zA, //2        //20        //BOTTOM
                    xB, yB, zA, //3        //21
                    xA, yB, zB, //6        //22
                    xB, yB, zB  //7        //23
        );
        
        for(i = 0; i < _verts.length; i+=3)
        {
            _vNorms.push(0, 0, 0);
        }
        calculateNormal();
        
        var  i0:int = index     ,  i1:int = index +  1,  i2:int = index +  2;
        var  i3:int = index +  3,  i4:int = index +  4,  i5:int = index +  5;
        var  i6:int = index +  6,  i7:int = index +  7,  i8:int = index +  8;
        var  i9:int = index +  9, i10:int = index + 10, i11:int = index + 11;
        var i12:int = index + 12, i13:int = index + 13, i14:int = index + 14;
        var i15:int = index + 15, i16:int = index + 16, i17:int = index + 17;
        var i18:int = index + 18, i19:int = index + 19, i20:int = index + 20;
        var i21:int = index + 21, i22:int = index + 22, i23:int = index + 23;
        
        _indices.push( i0,  i1,  i2, // 3  //FRONT
                       i1,  i3,  i2, // 6
                      
                       i4,  i5,  i6, // 9  //BACK
                       i5,  i7,  i6, //12
                      
                       i8,  i9, i10, //15  //RIGHT
                      i11, i10,  i9, //18
                      
                      i12, i13, i14, //21  //TOP
                      i15, i14, i13, //24
                      
                      i16, i17, i18, //27  //LEFT
                      i18, i17, i19, //30
                      
                      i20, i21, i22, //33  //BOTTOM
                      i21, i23, i22  //36
        );
        
        _faces.push(
            new Face(), new Face(), new Face(), 
            new Face(), new Face(), new Face(), 
            new Face(), new Face(), new Face(),
            new Face(), new Face(), new Face()
        );
        
        _uvts.push(
            0, 0, 0, //FRONT
            1, 0, 0, 
            0, 1, 0,
            1, 1, 0,
            
            0, 0, 0, //BACK
            1, 0, 0, 
            0, 1, 0,
            1, 1, 0,
            
            0, 0, 0, //RIGHT
            1, 0, 0, 
            0, 1, 0,
            1, 1, 0,
            
            0, 0, 0, //TOP
            1, 0, 0, 
            0, 1, 0,
            1, 1, 0,
            
            0, 0, 0, //LEFT
            1, 0, 0, 
            0, 1, 0,
            1, 1, 0,
            
            0, 0, 0, //BOTTOM
            1, 0, 0, 
            0, 1, 0,
            1, 1, 0
        );
        for(i = 0; i < _uvts.length; i++)
        {
            _static.push(_uvts[i]);
        }
    }
    
    public function calculateNormal():void
    {
        var i     :int    = 0;
        var vx    :Number = 0;
        var vy    :Number = 0;
        var vz    :Number = 0;
        var vlen  :Number = 0;
        for(i = 0; i < _verts.length; i+=3)
        {
            vx   = _verts[i    ];
            vy   = _verts[i + 1];
            vz   = _verts[i + 2];
            vlen = Math.sqrt(vx*vx + vy*vy + vz*vz);
            _vNorms[i    ] = vx/vlen;
            _vNorms[i + 1] = vy/vlen;
            _vNorms[i + 2] = vz/vlen;
        }
    }
}

class Face{
    public var i0:Number;
    public var i1:Number;
    public var i2:Number;
    public var z :Number;
}