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 Gasket 3

w/s: move front/ back
a/d: move right/ left
space/shift: move up/down
e/q: up/down light level
arrows: rotate
Get Adobe Flash player
by Susisu 02 Jul 2013

    Tags

    3d
    Embed
package
{
    
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.geom.Matrix3D;
    import flash.geom.Vector3D;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    
    [SWF(width="512",height="512",backgroundColor="0x000000",frameRate="60")]
    
    public class Gasket4D extends Sprite
    {
        private static const SIZE:Number = 512;
        private static const ZERO:Vector3D = new Vector3D(0, 0, 0);
        
        private static const CAMERA_SPEED:Number = SIZE / 128;
        private static const LIGHT_SPEED:Number = SIZE / 64;
        private static const ROTATION_SPEED:Number = 2;
        
        private static const DOTS_PER_FRAME:Number = 32768;
        
        private var canvas:BitmapData;
        private var bitmap:Bitmap;
        
        private var points:Vector.<Vector3D>;
        private var buffer:Vector.<uint>;
        
        private var camera:Vector3D;
        private var viewAngle:Number;
        private var cameraV:Vector3D;
        
        private var light:Number;
        private var lightV:Number;
        
        private var rotationMatrix:Matrix3D;
        private var rotationV:Vector3D;
        
        private var keyBuffer:Array;
        
        public function Gasket4D()
        {
            graphics.beginFill(0x000000);
            graphics.drawRect(0, 0, SIZE, SIZE);
            graphics.endFill();
            
            canvas = new BitmapData(SIZE, SIZE, false, 0);
            bitmap = new Bitmap(canvas);
            addChild(bitmap);
            
            points=new Vector.<Vector3D>();
            
            points.push(new Vector3D( SIZE / 4, -SIZE / 4,  SIZE / 4));
            points.push(new Vector3D(-SIZE / 4, -SIZE / 4, -SIZE / 4));
            points.push(new Vector3D( SIZE / 4,  SIZE / 4, -SIZE / 4));
            points.push(new Vector3D(-SIZE / 4,  SIZE / 4,  SIZE / 4));
            
            buffer = new Vector.<uint>(SIZE * SIZE, true);
            
            camera = new Vector3D(0, 0, SIZE / 2);
            viewAngle = Math.PI / 3;
            cameraV = new Vector3D(0, 0, 0);
            
            light = 256;
            lightV = 0;
            
            rotationMatrix = new Matrix3D();
            rotationV = new Vector3D(0, 0, 0);
            
            keyBuffer = [];
            
            addEventListener(Event.ENTER_FRAME,onEnterFrame);
            stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
            stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
        }
        
        private function onEnterFrame(e:Event):void
        {
            var numPoints:int = points.length;
            
            // move camera
            cameraV.x = (keyBuffer[68] ? CAMERA_SPEED : 0) - (keyBuffer[65] ? CAMERA_SPEED : 0);
            cameraV.y = (keyBuffer[16] ? CAMERA_SPEED : 0) - (keyBuffer[32] ? CAMERA_SPEED : 0);
            cameraV.z = (keyBuffer[83] ? CAMERA_SPEED : 0) - (keyBuffer[87] ? CAMERA_SPEED : 0);
            
            camera = camera.add(cameraV);
            
            // change light level
            lightV = (keyBuffer[69] ? LIGHT_SPEED : 0) - (keyBuffer[81] ? LIGHT_SPEED : 0);
            
            light += lightV;
            if(light < 0)
            {
                light = 0;
            }
            
            // rotate
            rotationV.x = (keyBuffer[40] ? ROTATION_SPEED : 0) - (keyBuffer[38] ? ROTATION_SPEED : 0);
            rotationV.y = (keyBuffer[37] ? ROTATION_SPEED : 0) - (keyBuffer[39] ? ROTATION_SPEED : 0);
            
            if(!rotationV.equals(ZERO))
            {
                rotationMatrix.identity();
                rotationMatrix.appendRotation(rotationV.x, Vector3D.X_AXIS);
                rotationMatrix.appendRotation(rotationV.y, Vector3D.Y_AXIS);
                for(var j:int = 0; j < numPoints; j++)
                {
                    points[j] = rotationMatrix.transformVector(points[j]);
                }
            }
            
            // if moved, clear buffer
            if(!cameraV.equals(ZERO) || lightV != 0 || !rotationV.equals(ZERO))
            {
                buffer = new Vector.<uint>(SIZE * SIZE, true);
            }
            
            // draw dots
            var dot:Vector3D = new Vector3D(0, 0, 0);
            var screen:Number = Math.tan(Math.PI / 2 - viewAngle / 2) * SIZE / 2;
            for(var i:int = 0; i < DOTS_PER_FRAME; i++)
            {
                // move to the midpoint of the dot and a point chosen at random from four
                var r:int = Math.floor(Math.random() * numPoints);
                var point:Vector3D = points[r];
                
                dot.x = (dot.x + point.x) / 2;
                dot.y = (dot.y + point.y) / 2;
                dot.z = (dot.z + point.z) / 2;
                
                // projection
                if(dot.z < camera.z)
                {
                    var cz:Number = screen / (camera.z - dot.z);
                    var x2D:int = SIZE / 2 + Math.round((dot.x - camera.x) * cz);
                    var y2D:int = SIZE / 2 + Math.round((dot.y - camera.y) * cz);
                    
                    if(x2D >= 0 && x2D < SIZE && y2D >= 0 && y2D < SIZE)
                    {
                        // calculate light level
                        var b:Number = Math.min(255, light * SIZE * SIZE
                            / (4 * Math.PI * (Math.pow(camera.x - dot.x, 2) + Math.pow(camera.y - dot.y, 2) + Math.pow(camera.z - dot.z, 2))));
                        // z-buffer-like
                        if((buffer[x2D + y2D * SIZE] & 0xff) < b)
                        {
                            buffer[x2D + y2D * SIZE] = (b << 16) | (b << 8) | (b << 0);
                        }
                    }
                }
            }
            // set buffer to canvas
            canvas.setVector(canvas.rect, buffer);
        }
        
        private function onKeyDown(e:KeyboardEvent):void
        {
            keyBuffer[e.keyCode] = true;
        }
        
        private function onKeyUp(e:KeyboardEvent):void
        {
            keyBuffer[e.keyCode] = false;
        }
        
    }
    
}