Beautifl - Flash Gallery

Thumbnail : Metatunnel
Metatunnel
rect 2010-12-02 MIT License

再生するにはFlash Playerが必要です。デスクトップのブラウザでご覧ください。

/*
    Metatunnel AS3 port
    
    Original by FRequency
    http://www.pouet.net/prod.php?which=52777
    
    Reference : Shader Toy v0.2 by iq
    http://www.iquilezles.org/apps/shadertoy/
*/

package
{
    import flash.display.*;
    import flash.events.Event;
    import flash.geom.Point;
    import flash.geom.Vector3D;
    import flash.utils.getTimer;

    [SWF(backgroundColor="#000000",width="465", height="465")]

    public class metatunnel extends Sprite
    {
        private const IMAGE_WIDTH:int = 128;
        private const IMAGE_HEIGHT:int = 128;
        private const FRAGMENTS:int = IMAGE_WIDTH*IMAGE_HEIGHT;
        private var p:Point = new Point();
        
        private var bitmapData:BitmapData;
        private var bitmap : Bitmap;
        private var buffer:BitmapData;
        
        private var n:Vector3D = new Vector3D();
        private var o:Vector3D = new Vector3D();
        private var d:Vector3D = new Vector3D();
        private var ds:Vector3D = new Vector3D();
        private var odt:Vector3D = new Vector3D();
        private var odte:Vector3D = new Vector3D();
        private const cc1:Vector3D = new Vector3D(0, 0, -0.5);
        private const cc2:Vector3D = new Vector3D(0, -0.5, 0.5);
        private var a:Vector3D = new Vector3D();
        private var b:Vector3D = new Vector3D();
        private var c:Vector3D = new Vector3D();
        private var vecCache:Vector3D = new Vector3D();
        private var ca1:Number = 0;
        private var ca2:Number = 0;
        private var ca3:Number = 0;
        private var ca4:Number = 0;
        private var ca5:Number = 0;
        
        private var frame:int = 0;
        private var dt:Number = 1;

        public function metatunnel()
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        protected function init():void
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.quality = StageQuality.LOW;
            stage.frameRate = 15;

            buffer = new BitmapData(IMAGE_WIDTH, IMAGE_HEIGHT,false,0x000000);
            bitmap = new Bitmap(buffer);
            addChild(bitmap);

            bitmap.width = 512, bitmap.height = 512;
            bitmap.x = (stage.stageWidth-bitmap.width) * 0.5;
            bitmap.y = (stage.stageHeight-bitmap.height) * 0.5;
            
            addEventListener(Event.ENTER_FRAME, enterFrameHandler);
        }


        private function enterFrameHandler(event : Event = null) : void
        {
            frame ++;
            dt += 0.09;
            
            var cosdt:Number = Math.cos(dt);
            var sindt02:Number = Math.sin(dt*0.2);
            a.x = cosdt + sindt02, a.y = 0.3, a.z = 2 + Math.cos(dt*0.5) * 0.5;
            b.x =-Math.cos(dt*0.7), b.y = 0.3, b.z = 2 + Math.sin(dt*0.5);
            c.x =-sindt02 * 0.5, c.y = Math.sin(dt), c.z = 2.0;
            
            var chk:Boolean = true;
            for (var f:int = 0; f < FRAGMENTS; f++)
            {
                var fx:int = int(f%IMAGE_WIDTH);
                var fy:int = int(f/IMAGE_WIDTH);
                
                if (frame %2 == 0) if (fx%2 != 0 && fy%2 != 0) chk = true; else chk = false;
                else if (fx%2 == 0 && fy%2 == 0) chk = true; else chk = false;
                
                if(chk)
                {
                    p.x = -1 + 2*fx/IMAGE_WIDTH;
                    p.y = 1 + -2*fy/IMAGE_HEIGHT;
                    
                    o.x = p.x, o.y = p.y*1.25-0.3, o.z = 0;
                    d.z = 0.015625, d.x = (p.x + cosdt * 0.3) * d.z, d.y = p.y * d.z;
                    
                    var t:Number = 0;
                    var r:Number = 0, g:Number = 0, b:Number = 0;
                    
                    for(var i:int = 0; i < 75; i++)
                    {
                        odt.x = o.x, odt.y = o.y, odt.z = o.z;
                        ds.x = d.x, ds.y = d.y, ds.z = d.z;
                        ds.scaleBy(t);
                        odt.incrementBy(ds);
                        
                        if(calc(odt) < 0.4)
                        {
                            t -= 5;
                            
                            for(var j:int = 0; j < 5; j++)
                            {
                                odt.x = o.x, odt.y = o.y, odt.z = o.z;
                                ds.x = d.x, ds.y = d.y, ds.z = d.z;
                                ds.scaleBy(t);
                                odt.incrementBy(ds);
                                if( calc(odt) < 0.4) break;
                                t += 1;
                            }
                            
                            odt.x = o.x, odt.y = o.y, odt.z = o.z;
                            ds.x = d.x, ds.y = d.y, ds.z = d.z;
                            ds.scaleBy(t);
                            odt.incrementBy(ds);
                            
                            var codt:Number = calc(odt);
                            odte.x = odt.x, odte.y = odt.y, odte.z = odt.z;
                            odte.x += 0.01;
                            n.x = codt - calc(odte);
                            odte.x = odt.x, odte.y = odt.y, odte.z = odt.z;
                            odte.y += 0.01;
                            n.y = codt - calc(odte);
                            odte.x = odt.x, odte.y = odt.y, odte.z = odt.z;
                            odte.z += 0.01;
                            n.z = codt - calc(odte);
                            n.normalize();
                            
                            var c:Number = ((n.dotProduct(cc1)>0)?n.dotProduct(cc1):0) + ((n.dotProduct(cc2)>0)?n.dotProduct(cc2):0) * 0.5;
                            r += c, g += c, b += c;
                            break;
                        }
                        t += 5;
                    }
                    
                    var cv:Number = t * 0.025;
                    r = (r + 0.1 * cv) * 0xff, g = (g + 0.2 * cv) * 0xff, b = (b + 0.5 * cv) * 0xff;
                    var col:uint = (((0xff < r)? 0xff:r) << 16) + (((0xff < g)? 0xff:g) << 8) + ((0xff < b)? 0xff:b);
                    buffer.setPixel(fx,fy,col);
                }
            }
        }

        private function calc(vec3:Vector3D):Number
        {
            var q:Vector3D = vec3;
            if (q.x != vecCache.x) ca2 = Math.cos(q.x), ca4 = Math.cos(q.x*3), vecCache.x = q.x;
            if (q.y != vecCache.y) ca1 = Math.cos(q.y), ca5 = Math.cos(q.y*4), vecCache.y = q.y;
            if (q.z != vecCache.z) ca3 = Math.cos(q.z*7+dt*7), vecCache.z = q.z;
            
            var val:Number = distance(q,a);
            val *= distance(q,b);
            val *= distance(q,c);
            val *= ca1 * ca2 - 0.1 - ca3 * ca4 * ca5 * 0.1;
            return val;
        }
        
        private function distance(q:Vector3D, w:Vector3D):Number
        {
            return Math.sqrt((q.x - w.x)*(q.x - w.x) + (q.y - w.y)*(q.y - w.y) + (q.z - w.z)*(q.z - w.z));
        }
    }
}