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

explosion with bumpmapping

move mouse for light
forked from http://wonderfl.net/c/uLoH @psyark
Get Adobe Flash player
by zob 13 Dec 2010
/**
 * Copyright zob ( http://wonderfl.net/user/zob )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/clRU
 */

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 net.hires.debug.Stats;
    import com.bit101.components.HSlider;
    import com.bit101.components.HUISlider;
    import com.bit101.components.PushButton;
    
    [SWF(width=465,height=465,backgroundColor=0x080808,frameRate=30)]
    public class expokision extends Sprite {
        private var loader:Loader;
        private var surface:MovieClip = new MovieClip();
        private var blender:MovieClip = new MovieClip();
        
        private var expoDots:Array = new Array();
        private var exposNum:int = 30;
        private var particles:Array = new Array();
        private var particlesNum:int = 0;
        private var expoDist:Number = 0.9;
        private var expoRange:Number = 5;
        private var radius:Number = 1;
        private var D2R:Number = Math.PI/180;
        private var R2D:Number = 180/Math.PI;
        private var damp:Number = 0.97;
        private var uncertainFactor:Number = 0.45;
        private var scaleFactor:Number = 0.45;
        private var randomFactor:Number = 0.6;
        private var angDist:Number = 25;
        private var maxlen:Number = 100;
        private var sv:int = 40;
        private var sh:int = 40;
        
        private var tex:BitmapData;
        private var heightMap:BitmapData;
        private var texture:BitmapData;
        private var smoker:Bitmap;
        private var origin:uint = 0xFFFFFF;
        
        private var target0:uint = 0xFFFFFF;
        private var target1:uint = 0xFFFFDD;
        private var target2:uint = 0xFFFF00;
        private var target3:uint = 0xFF9600;
        private var target4:uint = 0x542400;
        private var target5:uint = 0x261200;
        
        private var d:BitmapData;
        
        private var sampler:Number = 0;
        private var sample:Number = 0;
        private var sampleIndex:Number = 0;
        private var sampleTaken:Boolean = false;
        
        private var viewport:Shape = new Shape();
        private var world:Matrix3D = new Matrix3D();
        private var vertices:Vector.<Number>  = new Vector.<Number>(0, false);
        private var projected:Vector.<Number> = new Vector.<Number>(0, false);
        private var indices:Vector.<int>      = new Vector.<int>(0, false);
        private var uvtData:Vector.<Number>   = new Vector.<Number>(0, false);
        private var projection:PerspectiveProjection = new PerspectiveProjection();
        
        private var sortedIndices:Vector.<int>;
        private var faces:Array = [];
        private var org_vecs:Vector.<Number> = new Vector.<Number>(0 , false);
        private var vec_vecs:Vector.<Number> = new Vector.<Number>(0 , false);
        
        private var sort_count:int = 0;
        private var rotate:Number = 0;
        private var normalMap:BitmapData;
        private var tmp1:BitmapData = new BitmapData(500, 500, true, 0);
        private var tempHeightMap:BitmapData;
        private var ctMatrix:Array;
        
        private var baseXHSlider      :HUISlider;
        private var baseYHSlider      :HUISlider;
        private var octavesHSlider    :HUISlider;
        private var multiplierHSlider :HUISlider;
        
        // settings
        private var baseX         :Number  = 40;
        private var baseY         :Number  = 40;
        private var Octaves       :Number  = 80;
        private var multiplicer   :Number  = 25;
        private var blend         :Boolean = false;
        private var updateNormMap :Boolean = true;
        
        public function expokision() {
            addChild(new Bitmap(new BitmapData(stage.stageWidth, stage.stageHeight, false, 0x080808)));
            loader = new Loader();
            var requestPic:URLRequest = new URLRequest()
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
            requestPic.url = "http://assets.wonderfl.net/images/related_images/0/0b/0bf9/0bf9825c56a8027ac80186ed182457c566d5a4c3";
            loader.load(requestPic, new LoaderContext(true));
        }

        public function completeHandler(e:Event):void
        {
            init3D();
        }
        
        public function init3D():void
        {
            var i:int = 0;
            smoker = Bitmap(loader.content);
            surface.addChild(smoker);
            d = new BitmapData(500, 500, true, 0x0)
            heightMap = new BitmapData(500, 500, false);
            texture   = new BitmapData(500, 500, false);
            tex = new BitmapData(500, 500, false, 0xFFFFFFFF);
            normalMap = new NormalMap(smoker.bitmapData, 0x80, 5);
            tempHeightMap = new BitmapData(500, 500, true, 0x0);
            
            surface.addChild(blender);
            blender.blendMode = BlendMode.HARDLIGHT;
            reset();
            
            viewport.x = stage.stageWidth / 2;
            viewport.y = stage.stageHeight / 2;
            addChild(viewport);
            projection.fieldOfView = 45;
            createGeometry();
            
            var panel:Sprite = new Sprite();
            //addChild(mouse);
            addChild(panel);
            addChild(new Stats());
            baseXHSlider = new HUISlider(panel, 80, 10, "baseX", updateBaseX);
            baseXHSlider.value = baseX;
            baseYHSlider = new HUISlider(panel, 80, 25, "baseY", updateBaseY);
            baseYHSlider.value = baseY;
            octavesHSlider = new HUISlider(panel, 80, 40, "Octaves", updateOctaves);
            octavesHSlider.value = Octaves;
            multiplierHSlider = new HUISlider(panel, 80, 55, "Multiplier", updateMultiplier);
            multiplierHSlider.value = multiplicer;
            
            new PushButton(panel, 270, 15, "regenerate", regenerateMap).setSize(120, 16);
            new PushButton(panel, 270, 40, "change blendmode", changeBlendMode).setSize(120, 16);
            regenerateMap();
            
            stage.addEventListener(Event.ENTER_FRAME, processing);
        }
        
        private function updateBaseX(...arg):void
        {
            baseX = baseXHSlider.value;
        }
        
        private function updateBaseY(...arg):void
        {
            baseY = baseYHSlider.value;
        }
        
        private function updateOctaves(...arg):void
        {
            Octaves = octavesHSlider.value;
        }
        
        private function updateMultiplier(...arg):void
        {
            multiplicer = multiplierHSlider.value;
            updateNormMap = true;
        }
        
        private function changeBlendMode(...arg):void
        {
            blend = !blend;
        }
        
        private function createGeometry():void {
            var xDiv:uint = sv;
            var yDiv:uint = sh;
            for (var y:uint=0; y<=yDiv; y++) {
                var yr:Number = y / yDiv;
                var cy:Number = Math.cos(yr * Math.PI);
                var sy:Number = Math.sin(yr * Math.PI);
                for (var x:uint=0; x<=xDiv; x++) {
                    var xr:Number = x / xDiv;
                    var cx:Number = Math.cos(xr * Math.PI * 2);
                    var sx:Number = Math.sin(xr * Math.PI * 2);
                    org_vecs.push(cx * sy * radius, cy * radius, sx * sy * radius);
                    vertices.push(cx * sy * radius, cy * radius, sx * sy * radius);
                    vec_vecs.push(0, 0, 0);
                    uvtData.push(xr, yr, 0);
                    if (y < yDiv) {
                        var i1:uint = y       * (xDiv + 1) + x;
                        var i2:uint = y       * (xDiv + 1) + ((x + 1) % (xDiv + 1));
                        var i3:uint = (y + 1) * (xDiv + 1) + x;
                        var i4:uint = (y + 1) * (xDiv + 1) + ((x + 1) % (xDiv + 1));
                        indices.push(i1, i2, i3, i3, i2, i4);

                        faces.push(new Vector3D(), new Vector3D());
                    }
                }
            }
            sortedIndices= new Vector.<int>(indices.length, true);
        }

        private function regenerateMap(...arg):void
        {
            reset();
            var i:uint = 0;
            var j:uint = 0;
            var evx:Number = 0;
            var evy:Number = 0;
            var evz:Number = 0;
            var evlen:Number = 0;
            var speed:Number = 0;
            var pvx:Number = 0;
            var pvy:Number = 0;
            var pvz:Number = 0;
            var pvlen:Number = 0;
            var eradian:Number = 0;
            var jradian:Number = 0;
            var sinwave:Number = 0;
            var sinwave2:Number = 0;
            var coswave:Number = 0;
            var coswave2:Number = 0;
            var rand:Number = 0;
            var ang:Number = 0;

            var hheight:uint = 0x0;

            sampleTaken = false;
            var rad:Number = 0;
            var rad2:Number = 0;
            
            var x_d:int = 0;
            var y_d:int = 0;
            var x_d_b:int = 0;
            var y_d_b:int = 0;
            
            for(i = 0; i < vertices.length; i+=3)
            {
                y_d = ((i / 3) / (sv+1));
                x_d = ((i / 3) % (sh+1));
                pvx = org_vecs[i];
                pvy = org_vecs[i+1];
                pvz = org_vecs[i+2];
                pvlen = Math.sqrt(pvx * pvx + pvy * pvy + pvz * pvz);
                x_d_b = x_d * heightMap.width / sv;
                if(x_d_b == heightMap.width)
                    x_d_b = 0;
                y_d_b = y_d * heightMap.height / sh;
                if(y_d_b == heightMap.height)
                    y_d_b = 0;
                    
                hheight = heightMap.getPixel(x_d_b, y_d_b) & 0xFF;
                
                if(hheight<0x20)
                    hheight = 0x20;
                
                vec_vecs[i] += pvx/pvlen * expoRange * ( Number(hheight) / 256 );
                vec_vecs[i+1] += pvy/pvlen * expoRange * ( Number(hheight) / 256 );
                vec_vecs[i+2] += pvz/pvlen * expoRange * ( Number(hheight) / 256 );
                if(!sampleTaken)
                {
                    if(Math.abs(vec_vecs[i]) != 0)
                    {
                        sampler = Math.abs(vec_vecs[i]);
                        sample = Math.abs(vec_vecs[i]);
                        sampleTaken = true;
                    }
                }
            }
        }
        
        public function reset():void
        {
            sample = 0;
            sampler = 0;
            for(var i:int = 0; i < vertices.length; i+=3){
                vec_vecs[i] = 0;
                vec_vecs[i+1] = 0;
                vec_vecs[i+2] = 0;
                vertices[i] = 0;
                vertices[i+1] = 0;
                vertices[i+2] = 0;
            }
            heightMap.perlinNoise(baseX*3, baseY*3, Octaves/4, Math.random() * 1000, true, true, 5, true);
            heightMap.colorTransform(heightMap.rect, new ColorTransform(1.5, 1.5, 1.5, 1, -0x40, -0x40, -0x40));
            
            if(updateNormMap)
            {
                normalMap.dispose();
                normalMap = new NormalMap(smoker.bitmapData, 0x80, multiplicer/4);
                updateNormMap = false;
            }
                
            
            var contrast:Number = 1.9;
            var zoom:Number = 1 + (contrast - 0.1) / (contrast + 0.9);
            if (contrast < 0.1) zoom = 1;
            if (contrast > 2.0) zoom = 2;
            tempHeightMap.copyPixels(heightMap, heightMap.rect, new Point());
            ctMatrix = [contrast + 1, 0, 0, 0, -128 * contrast, 0, contrast + 1, 0, 0, -128 * contrast, 0, 0, contrast + 1, 0, -128 * contrast, 0, 0, 0, 1, 0];
            tempHeightMap.applyFilter(tempHeightMap, tempHeightMap.rect, new Point(), new ColorMatrixFilter(ctMatrix));
        }
        
        public function processing(e:Event):void
        {
            update();
            paint();
        }
        
        public function update():void
        {
            var i:int = 0;
            for( i = 0; i < vertices.length; i+=3)
            {
                vec_vecs[i] *= damp;
                vec_vecs[i+1] *= damp;
                vec_vecs[i+2] *= damp;
                
                vertices[i] += vec_vecs[i];
                vertices[i+1] += vec_vecs[i+1];
                vertices[i+2] += vec_vecs[i+2];
            }
            sampler *= damp;
        }
        
        public function paint():void
        {
            var i:int = 0;
            var light:Vector3D = new Vector3D();
            if(blend)
            {
                light.x = viewport.mouseX / (465 / 2) / Math.SQRT2;
                light.y = viewport.mouseY / (465 / 2) / Math.SQRT2;
            } else {
                light.x = -viewport.mouseX / (465 / 2) / Math.SQRT2;
                light.y = -viewport.mouseY / (465 / 2) / Math.SQRT2;
            }
            light.z = Math.sqrt(1 - light.x * light.x - light.y * light.y);
            
            var seaHeight:uint = 0x00;
            var paletteR:Array = [];
            var paletteG:Array = [];
            var paletteB:Array = [];
            var r:Number;
            
            for (i=0; i<256; i++) {
                if(sample != 0)
                    r = (i - seaHeight) / (256 - seaHeight) * (1 - sampler/sample);
                
                if (r > 9999999.8) {
                    
                    paletteR[i] = (0x26 - (0x26 - 0x00) * (r - 0.8) / 0.2) << 16;
                    paletteG[i] = (0x12 - (0x12 - 0x00) * (r - 0.8) / 0.2) << 8;
                    paletteB[i] = (0x00 - (0x00 - 0x00) * (r - 0.8) / 0.2);
                } else if (r > 999999.7) {
                    paletteR[i] = (0x54 - (0x54 - 0x26) * (r - 0.7) / 0.3) << 16;
                    paletteG[i] = (0x32 - (0x32 - 0x12) * (r - 0.7) / 0.3) << 8;
                    paletteB[i] = (0x00 - (0x00 - 0x00) * (r - 0.7) / 0.3);
                } else if (r > 0.6) {
                    paletteR[i] = (0xFF - (0xFF - 0x54) * (r - 0.6) / 0.4) << 16;
                    paletteG[i] = (0x96 - (0x96 - 0x32) * (r - 0.6) / 0.4) << 8;
                    paletteB[i] = (0x00 - (0x00 - 0x00) * (r - 0.6) / 0.4);
                } else if (r > 0.45) {
                    paletteR[i] = (0xFF - (0xFF - 0xFF) * (r - 0.45) / 0.15) << 16;
                    paletteG[i] = (0xFF - (0xFF - 0x96) * (r - 0.45) / 0.15) << 8;
                    paletteB[i] = (0x00 - (0x00 - 0x00) * (r - 0.45) / 0.15);
                } else if (r > 0.35) {
                    paletteR[i] = (0xFF - (0xFF - 0xFF) * (r - 0.35) / 0.10) << 16;
                    paletteG[i] = (0xFF - (0xFF - 0xFF) * (r - 0.35) / 0.10) << 8;
                    paletteB[i] = (0xDD - (0xDD - 0x00) * (r - 0.35) / 0.10);
                } else {
                    paletteR[i] = (0xFF - (0xFF - 0xFF) * r / 0.35) << 16;
                    paletteG[i] = (0xFF - (0xFF - 0xFF) * r / 0.35) << 8;
                    paletteB[i] = (0xFF - (0xFF - 0xDD) * r / 0.35);
                }
            }
                
            world.identity();
            world.appendRotation(getTimer() * -0.03, Vector3D.Y_AXIS);
            light = world.transformVector(light);
            texture.paletteMap(heightMap, texture.rect, texture.rect.topLeft, paletteR, paletteG, paletteB);
            
            var lighting:ColorMatrixFilter = new ColorMatrixFilter([
                2 * light.x, 2 * light.y, 2 * light.z, 0, (light.x + light.y + light.z) * -0xFF,
                2 * light.x, 2 * light.y, 2 * light.z, 0, (light.x + light.y + light.z) * -0xFF,
                2 * light.x, 2 * light.y, 2 * light.z, 0, (light.x + light.y + light.z) * -0xFF,
                0,           0,           0,           1, 0
            ]);
            
            tmp1.applyFilter(normalMap, normalMap.rect, normalMap.rect.topLeft, lighting);
            
            d.lock();
            d.draw(texture);
            d.unlock();
            
            blender.graphics.clear();
            blender.graphics.beginBitmapFill(d);
            blender.graphics.drawRect(0, 0, 500, 500);
            blender.graphics.endFill();
            tmp1.copyChannel(tempHeightMap, tempHeightMap.rect, new Point(), 4, 8);
            
            tex.lock();
            tex.draw(surface);

            if(blend)
                tex.draw(tmp1, null, null, BlendMode.MULTIPLY);
            else
                tex.draw(tmp1, null, null, BlendMode.SUBTRACT);
            
            tex.unlock();

            world.appendRotation(90, Vector3D.Y_AXIS);
            world.appendTranslation(0, 0, 700);
            world.append(projection.toMatrix3D());
            Utils3D.projectVectors(world, vertices, projected, uvtData);
            
            rotate = getTimer() * -0.03;
            
            if((rotate-60)/-60>sort_count)
            {
                resort();
                sort_count++;
            }
            viewport.graphics.clear();
            viewport.graphics.beginBitmapFill(tex, null, false, false);
            viewport.graphics.drawTriangles(projected, sortedIndices, uvtData, TriangleCulling.POSITIVE);
            viewport.graphics.endFill();
        }
        
        private function resort():void
        {
            var i:int = 0;
            var face:Vector3D;
            var inc:int = 0;
            var i1:uint = 0x0;
            var i2:uint = 0x0;
            var i3:uint = 0x0;
            for (i = 0; i<indices.length; i+=3){
                i1 = indices[ i+0 ];
                i2 = indices[ i+1 ];
                i3 = indices[ i+2 ];
                face = faces[inc];
                face.x = i1;
                face.y = i2;
                face.z = i3;
                face.w = Math.min(uvtData[i1 * 3 + 2], uvtData[i2 * 3 + 2], uvtData[i3 * 3 + 2]);
                inc++;
            }
            faces.sortOn("w", Array.NUMERIC);
            inc = 0;
            for each (face in faces){
                sortedIndices[inc++] = face.x;
                sortedIndices[inc++] = face.y;
                sortedIndices[inc++] = face.z;
            }
        }
    }
}

import flash.display.BitmapData;
import flash.geom.ColorTransform;
import flash.geom.Vector3D;
import flash.geom.Matrix3D;

class NormalMap extends BitmapData {
    public function NormalMap(heightMap:BitmapData, seaHeight:uint, multiplier:Number) {
        super(heightMap.width, heightMap.height, false);
        var vec:Vector3D = new Vector3D();
        var mtx:Matrix3D = new Matrix3D();
        for (var y:int=0; y<heightMap.height; y++) {
            for (var x:int=0; x<heightMap.width; x++) {
                var height:uint = heightMap.getPixel(x, y) & 0xFF;
                
                if (height >= seaHeight || true/**/) {
                    vec.x = (height - (heightMap.getPixel((x + 1) % heightMap.width, y) & 0xFF)) / 0xFF * multiplier;
                    vec.y = (height - (heightMap.getPixel(x, (y + 1) % heightMap.height) & 0xFF)) / 0xFF * multiplier;
                } else {
                    vec.x = vec.y = 0;
                }

                vec.y *= -1;
                vec.z = 0;
                if (vec.lengthSquared > 1) {
                    vec.normalize();
                }
                vec.z = Math.sqrt(1 - vec.lengthSquared);
                mtx.identity();
                mtx.appendRotation(y / heightMap.height * 180 - 90, Vector3D.X_AXIS);
                mtx.appendRotation(x / heightMap.width * 360, Vector3D.Y_AXIS);
                vec = mtx.transformVector(vec);
                setPixel(x, y,
                    (vec.x * 0x7F + 0x80) << 16 |
                    (vec.y * 0x7F + 0x80) << 8 |
                    (vec.z * 0x7F + 0x80)
                );
            }
        }
    }
}