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

this is part of larger experiment... don't ask.
Get Adobe Flash player
by makc3d 12 Mar 2009
package
{
    import flash.display.*;
    import flash.events.*;
    import flash.filters.*;
    import flash.geom.*;

    import sandy.core.*;
    import sandy.core.data.*;
    import sandy.core.scenegraph.*;
    import sandy.primitive.*;
    import sandy.materials.*;
    import sandy.view.*;

    // this is part of larger experiment... don't ask.

    [SWF (width=465, height=465, backgroundColor=0, frameRate=20)]
    public class Test extends BasicView
    {
        private const S:int = 150;
        private const Q:int = 10;
        private const Y:Number = 30;

        private var angle:Number = 0;
        private var texture:BitmapData;
        private var lmap:BitmapData, nmap:BitmapData, tmap:BitmapData;
        private var blur:BlurFilter = new BlurFilter (4, 4, 4);

        public function Test()
        {
            super (); init (465, 465); render ();

            // planes suck - use hexagonal grid instead
            var p:Plane3D = addHorizontalPlane (S, S, Q,
                new Point3D (0, -0.6 * S, 0));
            texture = new BitmapData (S, S, false, 0);
            p.appearance = makeBitmapAppearance (texture);

            // build random terrain
            // this is not really smooth terrain, but whatever
            var r:Number = 0;
            for each (var v:Vertex in p.geometry.aVertex) {
                r = 0.5 * (r + Math.random ()); v.y = Y * r;
            }

            // update face normals
            for each (var face:Polygon in p.aPolygons) face.updateNormal ();

            // render terrain heightmap
            renderHeightMap (p, graphics, S);

            // render normal map
            // this is not really normal map, but something close
            var xmap:BitmapData = new BitmapData (S, S, false, 0);
            xmap.draw (this); xmap.applyFilter (xmap, xmap.rect, xmap.rect.topLeft,
                new ConvolutionFilter (3, 3, [0, 0, 0, -1, 0, +1, 0, 0, 0], 1, 128));
            var ymap:BitmapData = new BitmapData (S, S, false, 0);
            ymap.draw (this); ymap.applyFilter (ymap, ymap.rect, ymap.rect.topLeft,
                new ConvolutionFilter (3, 3, [0, -1, 0, 0, 0, 0, 0, +1, 0], 1, 128));
            nmap = new BitmapData (S, S, false, 0);
            nmap.copyChannel (xmap, xmap.rect, nmap.rect.topLeft,
                BitmapDataChannel.RED, BitmapDataChannel.RED); // r<-x
            nmap.copyChannel (ymap, ymap.rect, nmap.rect.topLeft,
                BitmapDataChannel.GREEN, BitmapDataChannel.GREEN); // g<-y
            var zmap:BitmapData = new BitmapData (S, S, false, 0);
            zmap.draw (nmap, null, new ColorTransform ( -1, -1, 1, 1, 255, 255));
            zmap.draw (nmap, null, null, BlendMode.LIGHTEN); // r<-abs(x), g<-abs(y)
            zmap.applyFilter (zmap, zmap.rect, zmap.rect.topLeft, new ColorMatrixFilter (
                [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.5, -0.5, 0, 0, 3*128-1, 0, 0, 0, 1, 0]));
            nmap.copyChannel (zmap, zmap.rect, nmap.rect.topLeft,
                BitmapDataChannel.BLUE, BitmapDataChannel.BLUE); // b<-z
            var b:Bitmap = new Bitmap (nmap); b.x = S; addChild (b);

            // noisy texture
            tmap = new BitmapData (S, S, false, 0);
            tmap.noise (123, 200, 255, 7, true);
            tmap.draw (tmap, null, new ColorTransform (1, 0xEF / 255.0, 0x7F / 255.0));

            // make light map
            lmap = new BitmapData (S, S, false, 0);
            b = new Bitmap (lmap); b.x = 2 * S; addChild (b);

            // "sun"
            graphics.beginFill (0xFFEF7F); graphics.drawCircle (465 * 0.5, 465 * 0.5, 10);
        }

        override public function simpleRender(e:Event = null):void {
            // spin light (map coords)
            angle = mouseX / 100;
            var light:Point3D = new Point3D (Math.sin (angle), Math.cos (angle), 0.25); light.normalize ();

            // face light (real coords)
            camera.x = +2 * S * light.x;
            camera.y = +2 * S * light.z;
            camera.z = -2 * S * light.y;
            camera.lookAt (0, 0, 0);

            // http://wonderfl.kayac.com/code/4e95875560faedfc67621c179095d5c73ce2a594
            lmap.applyFilter(nmap, nmap.rect, nmap.rect.topLeft, 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 
            ]));

            lmap.applyFilter (lmap, lmap.rect, lmap.rect.topLeft, blur);
            texture.draw (tmap); texture.draw (lmap, null, null, BlendMode.MULTIPLY);

            super.simpleRender (e);
        }

        private function renderHeightMap (p:Plane3D, g:Graphics, s:int):void {
            for each (var t:Polygon in p.aPolygons)
                renderHeightMapElement (t, g, s);
        }

        private var m1:Matrix = new Matrix;
        private var m2:Matrix = new Matrix;
        private function renderHeightMapElement (t:Polygon, g:Graphics, s:int):void {
            var h0:Number = t.a.y / Y;
            var h1:Number = t.b.y / Y;
            var h2:Number = t.c.y / Y;

            var v0:Number = -100, v1:Number = 0, v2:Number = 100;
            var u0:Number = (h0 - 0.5) * (32768 * 0.05);
            var u1:Number = (h1 - 0.5) * (32768 * 0.05);
            var u2:Number = (h2 - 0.5) * (32768 * 0.05);

            var uv:UVCoord = UVCoord (t.aUVCoord [0]); m2.tx = uv.u * s; m2.ty = uv.v * s;

            if ( (int (u0 * 0.1) == int (u1 * 0.1)) && (int (u1 * 0.1) == int (u2 * 0.1)) ) {
                // solid color case
                g.beginFill ( 0x10101 * Math.round (0xFF * h0) );
            } else {
                // gradient case
                if ((u2 - u1) * (u1 - u0) > 0) {
                    var tmp:Number = v1; v1 = v2; v2 = tmp;
                }

                m1.a = u1 - u0; m1.b = v1 - v0;
                m1.c = u2 - u0; m1.d = v2 - v0;
                m1.tx = u0; m1.ty = v0;
                m1.invert ();

                uv = UVCoord (t.aUVCoord [1]);
                m2.a = uv.u * s - m2.tx; m2.b = uv.v * s - m2.ty;
                uv = UVCoord (t.aUVCoord [2]);
                m2.c = uv.u * s - m2.tx; m2.d = uv.v * s - m2.ty;
                m1.concat (m2);

                g.beginGradientFill ("linear", [0, 0xFFFFFF], [1, 1], [0, 255], m1);
            }
            g.moveTo (m2.tx, m2.ty); for each (uv in t.aUVCoord) g.lineTo (uv.u * s, uv.v * s);
            g.endFill ();
        }
    }
}