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

ball with perlin

demo for http://www.meetup.com/Budapest-Flash-Meetup-Group/
Get Adobe Flash player
by ysle 27 Mar 2013
/**
 * Copyright ysle ( http://wonderfl.net/user/ysle )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/7hCu
 */

package  
{
   
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.filters.BevelFilter;
    import flash.filters.DropShadowFilter;
    import flash.filters.GlowFilter;
    import flash.geom.ColorTransform;
    import flash.geom.Matrix3D;
    import flash.geom.Utils3D;
    import flash.geom.Vector3D;
    import flash.text.TextField;
    import flash.text.TextFormat;
    
   [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]          
 
    public class BallLite extends Sprite
    {
        private var screen:Sprite
        private var radius:Number = 175

        private var texture:BitmapData
        private var noise:BitmapData

        private var vertices:Vector.<Number>
        private var indices:Vector.<int>
        private var uvtData:Vector.<Number>
        private var matrix3D:Matrix3D
        private var projectedVertices:Vector.<Number>
        
        private var fold:Number = 0
        
        private var renderMode:int = 0
        
        private var _detail:Number = 5
        private var xDetail:Number = 30
        private var yDetail:Number = 20

        private var rx:Number = 0
        private var ry:Number = 0
        private var _color:Number = 0xff
        
        private var helpTf:TextField
        private var statTf:TextField

        public function BallLite() 
        {
            addChild(screen = new Sprite())
            
            addChild(helpTf = new TextField())
            addChild(statTf = new TextField())
            helpTf.multiline = true
            helpTf.autoSize = statTf.autoSize = 'left'
            helpTf.defaultTextFormat = statTf.defaultTextFormat =  new TextFormat('verdana', 10, 0xffffff)
            helpTf.text = 'click : render mode\nshift + click : color\n\nup / down : detail\nleft / right : fold'
            helpTf.selectable = statTf.selectable = false
            helpTf.x = helpTf.y = statTf.x = 10
            statTf.y = helpTf.y + helpTf.height + 10

            noise = new BitmapData(400, 400, true, 0xff000000)
            noise.perlinNoise(100, 100, 1, int(Math.random() * 100), true, false, 8, true)

            texture = new BitmapData(400, 400, true, 0xff000000)

            color = 0x00ff00
            detail = 8
            initGrid()

            stage.align = 'TL'
            stage.quality= 'LOW'
            stage.scaleMode = 'noScale'
            stage.addEventListener('enterFrame', render)
            stage.addEventListener('mouseDown', onMouseDown)
            stage.addEventListener('keyDown', onKeyDown)
            stage.addEventListener('resize', onStageResize)
            onStageResize()

        }
        
        private function initGrid():void
        {
            vertices = new Vector.<Number>()
            indices = new Vector.<int>()
            uvtData = new Vector.<Number>()
            projectedVertices =  new Vector.<Number>()

            var xr:Number = 0
            var yr:Number = 0

            var xrd:Number = (Math.PI *2) / xDetail
            var yrd:Number = Math.PI  / yDetail

            var i:Number
            var r:Number

            for (var y:Number = 0; y <= yDetail ; y++ )
            {
                xr = 0
                for (var x:Number = 0; x <= xDetail; x++ )
                {
                    r = radius - fold + fold * Math.random()

                    vertices.push
                    (
                        r * Math.sin(yr) * Math.cos(xr),
                        r * Math.sin(yr) * Math.sin(xr),
                        r * Math.cos(yr)
                    )

                    uvtData.push(x / xDetail, y / yDetail, 0)

                    i = y * xDetail + x + y

                    if (x < xDetail && y < yDetail)
                    {
                        indices.push(i, i + 1, i + xDetail + 1)    
                        indices.push(i + 1, i + 1 + xDetail + 1, i + xDetail + 1)
                    }
                    xr += xrd
                }
                yr += yrd
            }

            statTf.text = 'vertices : ' + vertices.length
        }

        private function render(...e):void
        {
            matrix3D = new Matrix3D()
            matrix3D.prependRotation( 90,    Vector3D.X_AXIS)
            matrix3D.appendRotation( rx += screen.mouseX / 10,    Vector3D.Y_AXIS)
            matrix3D.appendRotation( - screen.mouseY / 2,    Vector3D.X_AXIS)

            Utils3D.projectVectors(matrix3D, vertices, projectedVertices, uvtData)

            screen.graphics.clear()
            
            if (renderMode != 2 && texture) screen.graphics.beginBitmapFill(texture)
            if (renderMode > 0) screen.graphics.lineStyle(0, _color, .5)
            screen.graphics.drawTriangles(projectedVertices, indices, uvtData, 'negative')
        }

        public function get color():Number { return _color }
        public function set color(value:Number):void 
        {
            _color = value

            texture.fillRect(texture.rect, 0x00000000)
            texture.draw(noise, null, new ColorTransform((_color >> 16) / 0xff, (_color >> 8 & 0xff) / 0xff, (_color & 0xff) / 0xff, 1), null, noise.rect, false)
            
            screen.filters =
            [
                new DropShadowFilter(0, 0, _color, 1, 4, 4, 1, 3, false),
                new GlowFilter(_color, 1, 20, 20, 2, 3, false),
                new BevelFilter(radius / 2, 45, 0xffffff, .5, 0, 1, radius / 2, radius / 2, 1, 3)
            ]
        }

        public function get detail():Number { return _detail }
        public function set detail(value:Number):void 
        {
            xDetail = 3 * (_detail = value)
            yDetail = 2 * _detail
        }

        private function onMouseDown(e:MouseEvent):void 
        {
            if (e.shiftKey) color = Math.random() * 0xffffff
            else if (renderMode++ > 1) renderMode = 0
        }

        private function onKeyDown(e:KeyboardEvent):void 
        {
            switch(e.keyCode)
            {
                case 37: fold = Math.min(100, fold +10 ); break
                case 39: fold = Math.max(0, fold -10 ); break
                case 38: detail = Math.min(20, _detail + 1); break
                case 40: detail = Math.max(1, _detail - 1); break
                default : return
            }

            initGrid()
        }

        private function onStageResize(...e):void
        {
            screen.x = stage.stageWidth / 2 
            screen.y = stage.stageHeight / 2 
        }
    }
}