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

Planet Harmony

Color research for 3d planet generator. 
http://3dflashlo.free.fr/planet/index.html
Get Adobe Flash player
by loth_2013 10 Apr 2013

    Talk

    Glidias at 11 Apr 2013 18:50
    You should check out my LOD terrain engine at https://github.com/Glidias/alternterrain . But the difference it seems is yr 3d generator at http://3dflashlo.free.fr/planet/index.html is created on the-fly while mine is generated once only with pre-processing for LOD.
    loth_2013 at 11 Apr 2013 21:35
    your LOD is very interesting but i wan't keep simple process and i aslo use awayphysics on terrain mesh http://3dflashlo.free.fr/demos/index2.html

    Tags

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

package {
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.BlendMode;
    import flash.display.Shape;
    import flash.display.SimpleButton;
    import flash.display.StageQuality;
    import flash.display.StageAlign;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Matrix;
    import flash.geom.Vector3D;
    import flash.text.TextField;
    import flash.text.TextFormat;
    import flash.geom.Point;
    import flash.filters.ColorMatrixFilter;
    import flash.geom.ColorTransform;
    import flash.filters.BlurFilter;
    import flash.filters.GlowFilter;
    import flash.filters.BevelFilter;
    
    public class FlashTest extends Sprite {
        private const GOLD:Number = 1.618;
        private var _display:Bitmap;
        private var _canvas:BitmapData;
        private var _txt:TextField;
        private var _groundColors:Vector.<uint>;
        private var _skyColors:Vector.<uint>;
        public function FlashTest() {
            var c:Shape = new Shape();
            c.graphics.beginFill(0x808080);
            c.graphics.drawRect(0, 0, 465, 465);
            c.graphics.endFill();
            addChild(c);
            
            _canvas = new BitmapData(360, 360, false, 0x000000);
            _display = new Bitmap(_canvas);
            addChild(_display);
            _display.x = _display.y = 52;

            var v:Vector.<SimpleButton> = new Vector.<SimpleButton>();
            v[0] = button(360 + 52 + 2, 52, "Linear", 48);
            v[1] = button(360 + 52 + 2, 52 + 32, "Radial", 48);
            v[2] = button(52, 362 + 52, "Triad", 70, 30);
            v[3] = button(52 + 72, 362 + 52, "Analogous", 86, 30);
            v[4] = button(52 + 72 + 88, 362 + 52, "Monochrome", 86, 30);
            v[5] = button(52 + 72 + 88 + 88, 362 + 52, "Complementary", 112, 30);
            v[0].addEventListener(MouseEvent.CLICK, drawLinear);
            v[1].addEventListener(MouseEvent.CLICK, drawRadial);
            v[2].addEventListener(MouseEvent.CLICK, triadPlanet);
            v[3].addEventListener(MouseEvent.CLICK, analogPlanet);
            v[4].addEventListener(MouseEvent.CLICK, monoPlanet);
            v[5].addEventListener(MouseEvent.CLICK, complementPlanet);
            for (var i:uint; i < v.length; i++) {
                addChild(v[i]);
            }

            addText();
            randomPlanet(null);
        }
        
        private function addText():void {
            _txt = new TextField();
            var s:Sprite = new Sprite();
            _txt.defaultTextFormat = new TextFormat("Verdana", 12, 0xaaaaaa, false, null, null, null, null, "center");
            _txt.text = "Planet Harmony Research";
            addChild(_txt);
            _txt.y = 20;
            _txt.width = 450;
            _txt.height = 50;
        }

        private function button(x:int = 0, y:int = 0, name:String = "Yoo", w:int = 50, h:int = 30):SimpleButton {
            var im1:BitmapData = new BitmapData(w, h, false, 0x000000);
            var im2:BitmapData = new BitmapData(w, h, false, 0x000000);
            var im3:BitmapData = new BitmapData(w, h, false, 0x000000);
            var txt:TextField = new TextField();
            var s:Sprite = new Sprite();
            txt.defaultTextFormat = new TextFormat("Verdana", 10, 0xaaaaaa, false, null, null, null, null, "center");
            txt.text = name;
            txt.width = w;
            txt.height = 20;
            txt.y = (h >> 1) - 10;
            s.addChild(txt);
            s.graphics.lineStyle(2, 0x757575);
            s.graphics.beginFill(0x808080);
            s.graphics.drawRect(0, 0, w, h);
            s.graphics.endFill();
            im1.draw(s);
            s.graphics.clear();
            s.graphics.beginFill(0x707070);
            s.graphics.drawRect(0, 0, w, h);
            s.graphics.endFill();
            im2.draw(s);
            s.graphics.clear();
            s.graphics.beginFill(0xaa7070);
            s.graphics.drawRect(0, 0, w, h);
            s.graphics.endFill();
            im3.draw(s);
            var bitm1:Bitmap = new Bitmap(im1);
            var bitm2:Bitmap = new Bitmap(im2);
            var bitm3:Bitmap = new Bitmap(im3);
            var b:SimpleButton = new SimpleButton(bitm1, bitm2, bitm3, bitm1);
            b.x = x;
            b.y = y;
            return b;
        }

        private function randomPlanet(e:MouseEvent = null):void {
           planetColor( int(Math.random() * 4) );
        }

        private function triadPlanet(e:MouseEvent = null):void {
           planetColor( 0 );
        }

        private function complementPlanet(e:MouseEvent = null):void {
           planetColor( 1 );
        }

        private function analogPlanet(e:MouseEvent = null):void {
           planetColor( 2 );
        }

        private function monoPlanet(e:MouseEvent = null):void {
           planetColor( 3 );
        }

        private function planetColor(n:int):void {
            _groundColors = new Vector.<uint>(3, true);
            _skyColors = new Vector.<uint>(6, true);
            var name:String;
            var sat:Number = randomNumber(0.4, 0.8);
            var dist:Number = randomNumber(0.6, 1);
            var ang1:int = randomNumber(0, 360);
            var baseColor:uint = hsvToHex(ang1, sat, dist);
            var a2:int, a3:int, ang2:int, ang3:int;
            var n2:int = int(Math.random() * 2);

            switch (n) {
                case 0: 
                    name = "Triad Planet Harmony";
                    if (ang1 < 120) {
                        a2 = ang1 + 120;
                        a3 = ang1 + 240
                    } else if (ang1 > 120 && ang1 < 240) {
                        a2 = ang1 + 120;
                        a3 = ang1 - 120
                    } else {
                        a2 = ang1 - 120;
                        a3 = ang1 - 240
                    }
                    // switch dominant 2
                    if (n2 == 0) {
                        ang2 = a2;
                        ang3 = a3;
                    } else {
                        ang3 = a2;
                        ang2 = a3;
                    }
                    _groundColors[0] = hsvToHex(ang2, sat, dist);
                    _groundColors[1] = hsvToHex(ang3, sat, dist);
                    _groundColors[2] = hsvToHex(ang3, sat, dist/2);
                    _skyColors[0] = hsvToHex(ang2, sat, dist); // fog
                    _skyColors[1] = hsvToHex(ang1, sat, dist); // sky
                    _skyColors[2] = hsvToHex(ang1, sat, dist/2); // top sky
                    _skyColors[3] = hsvToHex(ang1, 0.1, 1); // clound white
                    _skyColors[4] = hsvToHex(ang1, sat, 0.1); // clound black
                    _skyColors[5] = hsvToHex(ang1, 0.1, 1); // sun
                    break;
                case 1: 
                    name = "Complementary Planet Harmony";
                    if (ang1 < 180) ang2 = ang1 + 180;
                    else ang2 = ang1 - 180;
                    _groundColors[0] = hsvToHex(ang2, sat, dist);
                    _groundColors[1] = hsvToHex(ang2, sat, (dist/3)*2);
                    _groundColors[2] = hsvToHex(ang2, sat, (dist/3));
                    _skyColors[0] = hsvToHex(ang2, sat, dist); // fog
                    _skyColors[1] = hsvToHex(ang1, sat, dist); // sky
                    _skyColors[2] = hsvToHex(ang1, sat, dist/2); // top sky
                    _skyColors[3] = hsvToHex(ang1, 0.1, 1); // clound white
                    _skyColors[4] = hsvToHex(ang1, sat, 0.1); // clound black
                    _skyColors[5] = hsvToHex(ang1, 0.1, 1); // sun
                    break;
                case 2: 
                    name = "Analogous Planet Harmony";
                    if (ang1 < 300){ ang2 = ang1 + 30; ang3 = ang1 + 60; }
                    else { ang2 = ang1 - 30; ang3 = ang1 - 60; }
                    _groundColors[0] = hsvToHex(ang2, sat, dist);
                    _groundColors[1] = hsvToHex(ang3, sat, dist);
                    _groundColors[2] = hsvToHex(ang3, sat, dist / 2);
                     _skyColors[0] = _groundColors[0]// fog
                    _skyColors[1] = hsvToHex(ang1, sat, dist); // sky
                    _skyColors[2] = hsvToHex(ang1, sat, dist/2); // top sky
                    _skyColors[3] = hsvToHex(ang1, 0.1, 1); // clound white
                    _skyColors[4] = hsvToHex(ang1, sat, 0.1); // clound black
                    _skyColors[5] = hsvToHex(ang1, 0.1, 1); // sun
                    break;
                case 3: 
                    name = "Monochrome Planet Harmony";
                    _groundColors[0] = hsvToHex(ang1, sat, dist);
                    _groundColors[1] = hsvToHex(ang1, sat, (dist/3)*2);
                    _groundColors[2] = hsvToHex(ang1, sat, (dist/3));
                    _skyColors[0] = _groundColors[0] // fog
                    _skyColors[1] = hsvToHex(ang1, sat/2, dist); // sky
                    _skyColors[2] = hsvToHex(ang1, sat/2, dist/2); // top sky
                    _skyColors[3] = hsvToHex(ang1, 0.1, 1); // clound white
                    _skyColors[4] = hsvToHex(ang1, sat/2, 0.1); // clound black
                    _skyColors[5] = hsvToHex(ang1, 0.1, 1); // sun
                    break;
            }
            if (_txt)
                _txt.text = name;
            drawPlanet(_groundColors, _skyColors);
        }

        private function drawPlanet(gc:Vector.<uint>, gs:Vector.<uint>):void {
            _canvas.lock();
            var m:Matrix = new Matrix();
            m.createGradientBox(360, 360, -Math.PI / 2);
            var s:Sprite = new Sprite();
            s.graphics.beginGradientFill("linear", [gc[0], gs[1] , gs[1],  gs[2]], [1, 1, 1, 1], [0x22,0x66, 0xAA, 0xff], m);
            s.graphics.drawRect(0, 0, 360, 360);
            s.graphics.endFill();
            var min:int = 180
            var max:int = 300;
            var middle:int = 222;
            m = new Matrix();
            m.createGradientBox(360, 138, -Math.PI / 2, 0, 222);
            var py:int = 0
            var mont:Vector.<int> = new Vector.<int>();
            mont[0] = randomNumber(min, max);
            mont[1] = randomNumber(min, max);
            mont[2] = randomNumber(min, max);
            mont[3] = randomNumber(min, max);
            mont[4] = randomNumber(min, max);
            mont[5] = randomNumber(min, max);
            mont[6] = randomNumber(min, max);
            mont[7] = randomNumber(min, max);
            mont[8] = randomNumber(min, max);
            mont[9] = randomNumber(min, max);
            mont[10] = randomNumber(min, max);
            mont[11] = randomNumber(min, max);
            var g:Sprite = new Sprite();
            g.graphics.beginFill(gc[0]);
            g.graphics.moveTo(380, 380);
            g.graphics.lineTo(-30, 380);
            g.graphics.lineTo(-30, 222);
            g.graphics.curveTo(30, mont[0], 60, mont[6]);
            g.graphics.curveTo(90, mont[1], 120, mont[7]);
            g.graphics.curveTo(140, mont[2], 180, mont[8]);
            g.graphics.curveTo(210, mont[3], 240, mont[9]);
            g.graphics.curveTo(270, mont[4], 300, mont[10]);
            g.graphics.curveTo(330, mont[5], 380, mont[11]);
            g.graphics.lineTo(380, 200);
            g.filters = [new BevelFilter(10, 45,  gs[5], 1,  gs[1], 1, 30, 30, 1, 2), new BlurFilter(6, 6, 3)]

            py = 50;
            var h:Sprite = new Sprite();
            h.graphics.beginFill(gc[1]);
            h.graphics.moveTo(380, 380);
            h.graphics.lineTo(-30, 380);
            h.graphics.lineTo(-30, 280);
            h.graphics.curveTo(30, mont[0] + py, 60, mont[6] + py);
            h.graphics.curveTo(90, mont[1] + py, 120, mont[7] + py);
            h.graphics.curveTo(140, mont[2] + py, 180, mont[8] + py);
            h.graphics.curveTo(210, mont[3] + py, 240, mont[9] + py);
            h.graphics.curveTo(270, mont[4] + py, 300, mont[10] + py);
            h.graphics.curveTo(330, mont[5] + py, 380, mont[11] + py);
            h.graphics.lineTo(380, 200);
            h.filters = [new BevelFilter(10, 45 + 180, gc[0], 1, gc[0], 1, 30, 30, 1, 2), new BlurFilter(12, 12, 3)]

            py = 100;
            var h2:Sprite = new Sprite();
            h2.graphics.beginFill(gc[2]);
            h2.graphics.moveTo(380, 380);
            h2.graphics.lineTo(-30, 380);
            h2.graphics.lineTo(-30, 280);
            h2.graphics.curveTo(30, mont[0] + py, 60, mont[6] + py);
            h2.graphics.curveTo(90, mont[1] + py, 120, mont[7] + py);
            h2.graphics.curveTo(140, mont[2] + py, 180, mont[8] + py);
            h2.graphics.curveTo(210, mont[3] + py, 240, mont[9] + py);
            h2.graphics.curveTo(270, mont[4] + py, 300, mont[10] + py);
            h2.graphics.curveTo(330, mont[5] + py, 380, mont[11] + py);
            h2.graphics.lineTo(380, 200);
            h2.filters = [new BevelFilter(10, 45 + 180, gc[1], 1, gc[1], 1, 30, 30, 1, 2), new BlurFilter(8, 8, 3)]

            _canvas.draw(s);
            _canvas.draw(sunColor( gs[5]));
            _canvas.draw(createCloud(360, 360 / GOLD, Math.random() * 0xffffffff, 1,  gs[3],  gs[1],  gs[4]));
            _canvas.draw(g);
            _canvas.draw(h);
            _canvas.draw(h2);
            
            _canvas.unlock();
        }

        private function drawLinear(e:MouseEvent):void {
            palette("linear");
        }

        private function drawRadial(e:MouseEvent):void {
            palette("radial");
        }

        private function palette(type:String = "linear"):void {
            _canvas.lock();
            var size:int = _canvas.width * _canvas.height;
            var xp:int, yp:int, c:uint, i:int;

            if (type == "linear") {
                for (i = 0; i < size; i++) {
                    xp = i % 360;
                    yp = i / 360;
                    c = hsvToHex(xp, 1, yp / 360);
                    _canvas.setPixel(xp, yp, c);
                }
            } else {
                // radial 
                var dx:Number, dy:Number, dist:Number, ang:Number;
                for (i = 0; i < size; i++) {
                    xp = i % 360;
                    yp = i / 360;
                    dx = xp - 180;
                    dy = yp - 180;
                    dist = 1 - Math.sqrt((dx * dx) + (dy * dy)) / 360;
                    ang = Math.atan2(dy, dx) / Math.PI * 180;
                    if (ang < 0) {
                        ang += 360;
                    }
                    c = hsvToHex(ang, 1, dist);
                    _canvas.setPixel(xp, yp, c);
                }
            }
            _canvas.unlock();
        }

        private function hsvToHex(h:Number, s:Number, v:Number):uint {
            var n:Vector3D = new Vector3D();
            var i:int, f:Number, p:Number, q:Number, t:Number, c:Array;
            if (h > 360)
                h = 360 - h;
            if (s == 0) {
                n.x = n.y = n.z = v;
                c = [Math.round(n.x * 255), Math.round(n.y * 255), Math.round(n.z * 255)];
                return c[0] << 16 | c[1] << 8 | c[2];
            }
            h /= 60;
            i = Math.floor(h);
            f = h - i;
            p = v * (1 - s);
            q = v * (1 - s * f);
            t = v * (1 - s * (1 - f));
            switch (i) {
                case 0: 
                    n = new Vector3D(v, t, p);
                    break;
                case 1: 
                    n = new Vector3D(q, v, p);
                    break;
                case 2: 
                    n = new Vector3D(p, v, t);
                    break;
                case 3: 
                    n = new Vector3D(p, q, v);
                    break;
                case 4: 
                    n = new Vector3D(t, p, v);
                    break;
                default: 
                    n = new Vector3D(v, p, q);
                    break;
            }
            c = [Math.round(n.x * 255), Math.round(n.y * 255), Math.round(n.z * 255)];
            return c[0] << 16 | c[1] << 8 | c[2];
        }

        public function randomNumber(min:Number, max:Number):Number {
            return (min + Math.random() * (max - min));
        }
        
        private function sunColor(c:uint):BitmapData {
            var b:BitmapData = new BitmapData(128, 128, true, 0x00000000);
            var s:Sprite = new Sprite();
            var mtx:Matrix = new Matrix();
            mtx.createGradientBox(128, 128, 0, 0, 0);
            s.graphics.beginGradientFill("radial", [c, c, c, c, c], [1, .95, .4, .1, 0], [0, 20, 50, 150, 255], mtx);
            s.graphics.drawCircle(64, 64, 64);
            s.graphics.endFill();
            b.draw(s);
            return b;
        }

        public function createCloud(width:int, height:int, seed:int, contrast:Number = 1, color:uint = 0x0080FF, light:uint = 0xFFFFFF, shadow:uint = 0xDDDDDD):BitmapData {
            var gradiation:Sprite = new Sprite();
            var drawMatrix:Matrix = new Matrix();
            drawMatrix.createGradientBox(width, height);
            gradiation.graphics.beginGradientFill("radial", [0x000000, 0x000000], [0, 1], [0, 255], drawMatrix);
            gradiation.graphics.drawRect(0, 0, width, height);
            gradiation.graphics.endFill();
            var alphaBmp:BitmapData = new BitmapData(width, height);
            alphaBmp.perlinNoise(width / 3, height / 2.5, 5, seed, false, true, 1 | 2 | 4, true);
            var zoom:Number = 1 + (contrast - 0.1) / (contrast + 0.9);
            if (contrast < 0.1)
                zoom = 1;
            if (contrast > 2.0)
                zoom = 2;
            var ctMatrix:Array = [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];
            alphaBmp.draw(gradiation, new Matrix(zoom, 0, 0, zoom, -(zoom - 1) / 2 * width, -(zoom - 1) / 2 * height));
            alphaBmp.applyFilter(alphaBmp, alphaBmp.rect, new Point(), new ColorMatrixFilter(ctMatrix));
            var image:BitmapData = new BitmapData(width, height, true, 0xFF << 24 | color);
            image.copyChannel(alphaBmp, alphaBmp.rect, new Point(), 4, 8);
            image.applyFilter(image, image.rect, new Point(), new GlowFilter(light, 1, 4, 4, 1, 3, true));
            var bevelSize:Number = Math.min(width, height) / 30;
            image.applyFilter(image, image.rect, new Point(), new BevelFilter(bevelSize, 45, light, 1, shadow, 1, bevelSize / 5, bevelSize / 5, 1, 3));
            var image2:BitmapData = new BitmapData(width, height, true, 0);
            image2.draw(createGradientRect(width, height, [light, color, shadow], [1, 0.2, 1], null, 90), null, null, BlendMode.MULTIPLY);
            image2.copyChannel(alphaBmp, alphaBmp.rect, new Point(), 4, 8);
            image.draw(image2, null, null, BlendMode.MULTIPLY);
            alphaBmp.dispose();
            return image;
        }
        
        public function createGradientRect(width:Number, height:Number, colors:Array, alphas:Array, ratios:Array = null, rotation:Number = 0):Sprite {
            var i:int, rts:Array = new Array();
            if (ratios == null)
                for (i = 0; i < colors.length; i++)
                    rts.push(int(255 * i / (colors.length - 1)));
            else
                for (i = 0; i < ratios.length; i++)
                    rts[i] = Math.round(ratios[i] * 255);
            var sp:Sprite = new Sprite();
            var mtx:Matrix = new Matrix();
            mtx.createGradientBox(width, height, Math.PI / 180 * rotation, 0, 0);
            if (colors.length == 1 && alphas.length == 1)
                sp.graphics.beginFill(colors[0], alphas[0]);
            else
                sp.graphics.beginGradientFill("linear", colors, alphas, rts, mtx);
            sp.graphics.drawRect(0, 0, width, height);
            sp.graphics.endFill();
            return sp;
        }
    }
}