fc2ブログ

Flag

2008-03-22 | 00:20


package
{
    import flash.display.*;
    import flash.events.*;

    import org.papervision3d.view.BasicView;
    import org.papervision3d.core.geom.TriangleMesh3D;
    import org.papervision3d.core.geom.renderables.Triangle3D;
    import org.papervision3d.core.geom.renderables.Vertex3D;
    import org.papervision3d.core.math.NumberUV;
    import org.papervision3d.lights.*;
    import org.papervision3d.materials.*;
    import org.papervision3d.materials.special.*;
    import org.papervision3d.materials.shadematerials.* ;
    import org.papervision3d.materials.utils.*;
    import org.papervision3d.objects.primitives.*;

    [SWF(width=600, height=400, backgroundColor=0x111111)]

        public class MeshBitmap3 extends BasicView
        {
            private var mesh:TriangleMesh3D;

            [Embed(source="flag.jpg")]
                private var myImage:Class;

            private var range:int = 60;
            private var renderBuffer:int = 0;
            private var buffer:Array=[];

            private var k1:Number;
            private var k2:Number;
            private var k3:Number;

            private var bm:Bitmap;

            public function MeshBitmap3()
            {
                stage.frameRate = 5;
                stage.align = StageAlign.TOP_LEFT;
                stage.scaleMode = StageScaleMode.NO_SCALE;
                stage.quality = StageQuality.MEDIUM;

                super (0,0,true,false,"CAMERA3D");
                init3D();

                var d:Number = 1;
                var t:Number = 0.1;
                var c:Number = 3.8;
                var mu:Number = 0.0000001;

                var f1:Number = c*c*t*t/(d*d);
                var f2:Number = 1/(mu*t+2);

                k1 = (4 - 8*f1)*f2;
                k2 = (mu*t-2)*f2;
                k3 = 2*f1*f2;

                clearBuffer();
                splash();

                stage.addEventListener(MouseEvent.MOUSE_MOVE, function(e:*):void{
                        if(stage.mouseY > 0 && stage.mouseY < 400){
                        var t:Number = stage.mouseY / 400 * Math.PI / 2.5;
                        camera.y = Math.cos(t) * 500;
                        camera.z = Math.sin(t) * (-500);
                        }
                        });

                stage.addEventListener(MouseEvent.MOUSE_DOWN, splash);
            }

            private function splash(e:* = null):void{
                for(var i:int=8; i < Math.min(range, 14); i++){
                    for(var j:int=8; j < Math.min(range, 14) ; j++){
                        var diff:int = (mesh.geometry.vertices[y*(range+1) + x].z > 0) ? -5 : 5;
                        buffer[1-renderBuffer][j][i] += diff;
                    }
                }
            }

            public function init3D():void
            {
                camera.y = 400;
                camera.z = -400;
                camera.x = 0;
                camera.focus = 300;
                camera.zoom = 2;

                bm = new myImage();

                mesh=  new Plane(new BitmapMaterial(bm.bitmapData), bm.width, bm.height,range,range);
                mesh.rotationX = -90;
                scene.addChild(mesh);

                startRendering();
            }

            override protected function onRenderTick(event:Event=null):void
            {
                for(var y:int = 0 ; y < range+1 ; y++){
                    for(var x:int = 0 ; x < range+1 ; x++){
                        mesh.geometry.vertices[y*(range+1) + x].z = buffer[renderBuffer][x][y];
                    }
                }
                evaluate();

                super.onRenderTick(event);
            }

            private function clearBuffer():void{
                buffer = [];
                // 変位が格納される3次元配列(2*w*h)
                for(var i:int = 0 ; i < 2; i++){
                    var a:Array = new Array();
                    for(var j:int = 0 ; j < range+1; j++){
                        var aa:Array = new Array();
                        for(var k:int = 0 ; k < range+1; k++)
                            aa.push(0);
                        a.push(aa);
                    }

                    buffer.push(a);
                }
            }

            private function evaluate():void{
                for(var j:int = 0 ; j < range+1; j++){
                    var crnt:Array = buffer[renderBuffer][j];
                    var prev:Array = buffer[1-renderBuffer][j];
                    for(var i:int = 0 ; i < range+1; i++){
                        var ii:int = i;
                        var jj:int = j;
                        if(i == 0)
                            ii = 1
                        else if (i == range)
                            ii = i - 1;
                        if(j == 0)
                            jj = 1
                        else if (j == range)
                            jj = j - 1;
                        var currentN:Number = buffer[renderBuffer][jj + 1][ii];
                        var currentP:Number = buffer[renderBuffer][jj - 1][ii];
                        prev[i] =
                            k1*(crnt[ii]) + k2*prev[ii] +
                            k3*(crnt[ii+1] + crnt[ii-1] + currentN + currentP);

                    }
                }

                renderBuffer = 1-renderBuffer;
            }

        }
}

スポンサーサイト