スポンサーサイト

-------- | --:--

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

[ActionScript 3.0] PaperVision3Dで流体 #2

2007-11-21 | 19:47

前回のものは端が固定されていましたが、端も動くようにしました。
マウスクリックで波が立ちます。
波が立ち始める位置はランダムに決まります。(クリックする位置とは無関係です)
マウスを上下に動かすとズームの変更、左右に動かすと視点を回転します。

package {
    import flash.display.*;
    import flash.events.*;
    import flash.text.*;
    import flash.filters.*;
    import flash.geom.*;
    import flash.utils.*;

    import org.papervision3d.core.*;
    import org.papervision3d.core.geom.*;
    import org.papervision3d.scenes.*;
    import org.papervision3d.objects.*;
    import org.papervision3d.cameras.*;
    import org.papervision3d.materials.*;

    [SWF(width="600", height="400", backgroundColor="#ffffff")]
        public class Fluid2 extends Sprite{

            private var canvas : Sprite;
            private var scene     : MovieScene3D;
            private var camera    : Camera3D;

            private var theta:Number = 0;
            private var linesX:Array= new Array();
            private var linesZ:Array= new Array();

            private var w:int;
            private var h:int;

            private var buffer:Array = new Array();
            private var renderBuffer:int = 0;

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

            private var depth:Number = 10;

            public function Fluid2():void
            {
                stage.frameRate = 20;
                stage.quality   = "MEDIUM";
                stage.scaleMode = "noScale";
                stage.align = StageAlign.TOP_LEFT;

                canvas = new Sprite();
                canvas.x = 300;
                canvas.y = 200;
                stage.addChild( canvas );

                scene = new MovieScene3D( canvas );

                var range:int = 60;

                var x:int,y:int,z:int;
               
                scene.addChild( new Line3D([ new Vertex3D(-range,0,0), new Vertex3D(range,0,0)],
                            0xff0000, 0.5, w));
                scene.addChild( new Line3D([ new Vertex3D(0,-range,0), new Vertex3D(0,range,0)],
                            0xff00, 0.5, w));
                scene.addChild( new Line3D([ new Vertex3D(0,0,-range), new Vertex3D(0,0,range)],
                            0xff, 0.5, w));
              

                camera = new Camera3D();
                camera.x = 100;
                camera.y = 100;
                camera.z = -400;
                camera.focus = 100;
                camera.zoom = 50;
                /*
                var mList:MaterialsList = new MaterialsList();

                mList.addMaterial( new ColorMaterial(0x000000 , 0.1) , "face1" );
                mList.addMaterial( new ColorMaterial(0x00ff0f , 0.1) , "face2" );
                mList.addMaterial( new ColorMaterial(0x00fff0 , 0.1) , "face3" );
                mList.addMaterial( new ColorMaterial(0xff0000 , 0.1) , "face4" );
                mList.addMaterial( new ColorMaterial(0x00ffff , 0.1) , "face5" );
                mList.addMaterial ( new ColorMaterial(0x0000ff , 0.1) , "face6" );

                var cube:Cube = new Cube(mList, range,range,depth );
                scene.addChild( cube );
                 */

                //stage.addEventListener( Event.ENTER_FRAME, onEnterFrame);
                var tm:Timer = new Timer(100);
                tm.addEventListener(TimerEvent.TIMER, loop);
                tm.start();

                scene.renderCamera( camera );

                w = h = range;

                for(x= -range/2 ; x < range/2+1; x++){
                    var vertexes:Array = new Array();
                    for (z= -range/2 ; z < range/2+1 ; z++){
                        vertexes.push(new Vertex3D(x,0,z));
                    }
                    var line:Line3D = new Line3D(vertexes, 0xff, 0.3, 0.05);
                    linesZ.push(line);
                    scene.addChild(line);
                }
                for(z= -range/2 ; z < range/2+1; z++){
                    vertexes = new Array();
                    for (x= -range/2 ; x < range/2+1 ; x++){
                        vertexes.push(new Vertex3D(x,0,z));
                    }
                    line = new Line3D(vertexes, 0xff, 0.3, 0.05);
                    linesX.push(line);
                    scene.addChild (line);
                }

                clearBuffer();

                var d:Number = 1;
                var t:Number = 0.1;
                var c:Number = 2.2;
                var mu:Number = 0.0001;

                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;

                stage.addEventListener(MouseEvent.CLICK, function(e:*):void{
                        clearBuffer();
                        var x:int = Math.random()*range;
                        var y:int = Math.random()*range;
                        for(var i:int=x; i < Math.min(range, x+8); i++){
                        for(var j:int=y; j < Math.min(range, y+8) ; j++){
                        buffer[1-renderBuffer][j][i] -= 0.3;
                        }
                        }
                        });
                stage.addEventListener(MouseEvent.MOUSE_MOVE, function(e:*):void{
                        var rad:Number = (300- stage.mouseX)/300*(Math.PI);
                        camera.x = Math.cos(rad)*100 - Math.sin(rad)*(-400);
                        camera.z = Math.sin(rad)*100 + Math.cos(rad)*(-400);

                        camera.zoom = Math.max((400-stage.mouseY),0) +40;
                        });
            }

            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 < h+1; j++){
                        var aa:Array = new Array();
                        for(var k:int = 0 ; k < w+1; k++)
                            aa.push(0);
                        a.push(aa);
                    }

                    buffer.push(a);
                }
            }

            private function evaluate():void{
                for(var j:int = 0 ; j < h+1; j++){
                    var crnt:Array = buffer[renderBuffer][j];
                    var prev:Array = buffer[1-renderBuffer][j];
                    for(var i:int = 0 ; i < w+1; i++){
                        var ii:int = i;
                        var jj:int = j;
                        if(i == 0)
                            ii = 1
                        else if (i == w)
                            ii = i - 1;
                        if(j == 0)
                            jj = 1
                        else if (j == h)
                            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;
            }

            private function rotateCamera(rad:Number):void{
                var x:Number = camera.x;
                var y:Number = camera.y;
                var z:Number = camera.z;
                camera.x = Math.cos(rad)*x - Math.sin(rad)*z;
                //camera.y = Math.cos(rad)*x - Math.sin (rad)*z;
                camera.z = Math.sin(rad)*x + Math.cos(rad)*z;
            }

            private function loop( event:Event ):void
            {
                trace( buffer[renderBuffer][1][0]);
                var scale:Number = 1;
                theta += 0.05;

                for(var x:int = 0 ; x < linesZ.length ; x++){
                    for(var z:int = 0 ; z < h ; z++){
                        linesZ[x].segments[z].vertex1.y = buffer[renderBuffer][x][z]*scale;
                        /*
                        linesZ[x].segments[z].color =
                            ( buffer[renderBuffer][x][z] >= 0) ? 0xff0000 : 0xff;
                         */
                    }
                    linesZ[x].segments[z-1].vertex2.y = buffer[renderBuffer][x][z]*scale;
                }
                for(z = 0 ; z < linesX.length ; z++){
                    for(x = 0 ; x < w ; x++){
                        linesX[z].segments[x].vertex1.y = buffer[renderBuffer][x][z]*scale;
                        /*
                        linesX[z].segments[x].color =
                            ( buffer[renderBuffer][x][z] >= 0) ? 0xff0000 : 0xff;
                         */
                    }
                    linesX[z].segments[x-1].vertex2.y = buffer[renderBuffer][x][z]*scale;
                }


                //rotateCamera(0.002);

                evaluate();

                scene.renderCamera(camera);
            }
        }
}
スポンサーサイト

Comment

Post a comment

Secret

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。