MULTI~FLUID~2.0
Grant Kot's Multiphase Fluid 2.0
..Multi~Cleaned, Multi~Optimized, from Java code : http://grantkot.com/Multiphase/Liquid.html
+ great optimizations from : http://wonderfl.net/c/2lgo#code_forked
/**
* Copyright FLASHMAFIA ( http://wonderfl.net/user/FLASHMAFIA )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/7EAn
*/
package {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
[SWF(width='465', height='465')]
public class GKFluidW02 extends Sprite
{
private const P_NUM : uint = 200 * 100;
/* */
private var ppp : Particle;
private var grid : Vector.<Vector.<Node>>;
private var nnn : Node;
private var bmd : BitmapData;
private var buf : Vector.<uint>;
private var mx0 : Number;
private var my0 : Number;
function GKFluidW02()
{
stage.stageFocusRect = tabChildren = tabEnabled = mouseChildren = mouseEnabled = false;
stage.scaleMode = 'noScale';
stage.align = 'TL';
stage.quality = 'low';
stage.frameRate = 64;
opaqueBackground = 0x0;
var bm : Bitmap = new Bitmap(bmd = new BitmapData(512, 512, false, 0x0));
bm.x = bm.y = (465 - 512) / 2;
bm.opaqueBackground = 0x0;
addChild(bm);
buf = new Vector.<uint>(512 * 512, true);
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - */
grid = new Vector.<Vector.<Node>>(128, true);
var node : Node;
var gx : int;
var gy : int;
for (gx = 0; gx < 128; gx++)
{
grid[gx] = new Vector.<Node>(128, true);
for (gy = 0; gy < 128; gy++)
{
if (nnn != null) grid[gx][gy] = node = node.next = new Node();
else grid[gx][gy] = node = nnn = new Node();
}
}
for (gx = 0; gx < (128 - 2); gx++)
{
for (gy = 0; gy < (128 - 2); gy++)
{
grid[gx][gy].n10 = grid[gx + 1][gy + 0];
grid[gx][gy].n20 = grid[gx + 2][gy + 0];
grid[gx][gy].n01 = grid[gx + 0][gy + 1];
grid[gx][gy].n11 = grid[gx + 1][gy + 1];
grid[gx][gy].n21 = grid[gx + 2][gy + 1];
grid[gx][gy].n02 = grid[gx + 0][gy + 2];
grid[gx][gy].n12 = grid[gx + 1][gy + 2];
grid[gx][gy].n22 = grid[gx + 2][gy + 2];
}
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - */
var p : Particle = ppp = new Particle();
var i : uint = P_NUM;
while (i-- != 0)
{
gx = 0.1 + 0.9 * (i & 127);
gy = 0.1 + 0.9 * ((i >> 7) & 127);
if (gx < 25)
{
p.color = 0xFF0080;
p.gas = false;
p.mass = 4.0;
}
else if (gx < 50)
{
p.color = 0xFFFF00;
p.gas = true;
p.mass = 3.0;
}
else if (gx < 75)
{
p.color = 0x00D0FF;
p.gas = false;
p.mass = 2.0;
}
else
{
p.color = 0xA0FF00;
p.gas = false;
p.mass = 1.0;
}
p.rd = 1.0;
p.k = 1.0;
p.x = gx + Math.random() + 4.0;
p.y = gy + Math.random() + 4.0;
p = p.next = new Particle();
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - */
stage.addEventListener(Event.ENTER_FRAME, oef);
}
private function oef(e : Event) : void
{
var mx : Number = stage.mouseX * 0.25;
var my : Number = stage.mouseY * 0.25;
var mdx : Number = mx - mx0;
var mdy : Number = my - my0;
mx0 = mx;
my0 = my;
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - */
var n : Node = nnn;
while (n != null)
{
if (n.active)
{
n.m = 0;
n.d = 0;
n.gx = 0;
n.gy = 0;
n.u = 0;
n.v = 0;
n.ax = 0;
n.ay = 0;
n.active = false;
}
n = n.next;
}
var p : Particle = ppp;
while (p != null)
{
var pcx : uint = (p.x - 0.5) >> 0;
var pcy : uint = (p.y - 0.5) >> 0;
var d : Number = pcx - p.x;
p.x0 = 0.5 * d * d + 1.5 * d + 1.125;
p.gx0 = d + 1.5;
d += 1.0;
p.x1 = -d * d + 0.75;
p.gx1 = -2.0 * d;
d += 1.0;
p.x2 = 0.5 * d * d - 1.5 * d + 1.125;
p.gx2 = d - 1.5;
d = pcy - p.y;
p.y0 = 0.5 * d * d + 1.5 * d + 1.125;
p.gy0 = d + 1.5;
d += 1.0;
p.y1 = -d * d + 0.75;
p.gy1 = -2.0 * d;
d += 1.0;
p.y2 = 0.5 * d * d - 1.5 * d + 1.125;
p.gy2 = d - 1.5;
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - */
n = p.node = grid[pcx][pcy];
var n00 : Node = n;
var n01 : Node = n.n01;
var n02 : Node = n.n02;
var n10 : Node = n.n10;
var n11 : Node = n.n11;
var n12 : Node = n.n12;
var n20 : Node = n.n20;
var n21 : Node = n.n21;
var n22 : Node = n.n22;
n00.active = true;
n01.active = true;
n02.active = true;
n10.active = true;
n11.active = true;
n12.active = true;
n20.active = true;
n21.active = true;
n22.active = true;
p.p00 = p.x0 * p.y0;
p.p10 = p.x1 * p.y0;
p.p20 = p.x2 * p.y0;
p.p01 = p.x0 * p.y1;
p.p11 = p.x1 * p.y1;
p.p21 = p.x2 * p.y1;
p.p02 = p.x0 * p.y2;
p.p12 = p.x1 * p.y2;
p.p22 = p.x2 * p.y2;
var pm : Number = p.mass;
n00.m += p.p00 * pm;
n00.d += p.p00;
n00.gx += p.gx0 * p.y0;
n00.gy += p.x0 * p.gy0;
n10.m += p.p10 * pm;
n10.d += p.p10;
n10.gx += p.gx1 * p.y0;
n10.gy += p.x1 * p.gy0;
n20.m += p.p20 * pm;
n20.d += p.p20;
n20.gx += p.gx2 * p.y0;
n20.gy += p.x2 * p.gy0;
n01.m += p.p01 * pm;
n01.d += p.p01;
n01.gx += p.gx0 * p.y1;
n01.gy += p.x0 * p.gy1;
n11.m += p.p11 * pm;
n11.d += p.p11;
n11.gx += p.gx1 * p.y1;
n11.gy += p.x1 * p.gy1;
n21.m += p.p21 * pm;
n21.d += p.p21;
n21.gx += p.gx2 * p.y1;
n21.gy += p.x2 * p.gy1;
n02.m += p.p02 * pm;
n02.d += p.p02;
n02.gx += p.gx0 * p.y2;
n02.gy += p.x0 * p.gy2;
n12.m += p.p12 * pm;
n12.d += p.p12;
n12.gx += p.gx1 * p.y2;
n12.gy += p.x1 * p.gy2;
n22.m += p.p22 * pm;
n22.d += p.p22;
n22.gx += p.gx2 * p.y2;
n22.gy += p.x2 * p.gy2;
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - */
var pressure : Number;
if (p.gas == false)
{
d = n10.d - n00.d;
var C20 : Number = 3.0 * d - n10.gx - 2.0 * n00.gx;
var C30 : Number = -2.0 * d + n10.gx + n00.gx;
d = n01.d - n00.d;
var C02 : Number = 3.0 * d - n01.gy - 2.0 * n00.gy;
var C03 : Number = -2.0 * d + n01.gy + n00.gy;
var csum1 : Number = n00.d + n00.gy + C02 + C03;
var csum2 : Number = n00.d + n00.gx + C20 + C30;
var C21 : Number = 3.0 * n11.d - 2.0 * n01.gx - n11.gx - 3.0 * csum1 - C20;
var C31 : Number = -2.0 * n11.d + n01.gx + n11.gx + 2.0 * csum1 - C30;
var C12 : Number = 3.0 * n11.d - 2.0 * n10.gy - n11.gy - 3.0 * csum2 - C02;
var C13 : Number = -2.0 * n11.d + n10.gy + n11.gy + 2.0 * csum2 - C03;
var C11 : Number = n01.gx - C13 - C12 - n00.gx;
var u : Number = p.x - pcx;
var u2 : Number = u * u;
var u3 : Number = u * u2;
var v : Number = p.y - pcy;
var v2 : Number = v * v;
var v3 : Number = v * v2;
var density : Number = n00.d + n00.gx * u + n00.gy * v + C20 * u2 + C02 * v2 + C30 * u3 + C03 * v3 + C21 * u2 * v + C31 * u3 * v + C12 * u * v2 + C13 * u * v3 + C11 * u * v;
pressure = p.k * (density - p.rd);
if (pressure > 2.0) pressure = 2.0;
pressure *= pm;
}
else
{
pressure = 1.5;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - */
var fx : Number = 0.0;
var fy : Number = 0.0;
if (p.x < 8) fx = pm * (8 - p.x);
else if (p.x > 128 - 8) fx = pm * (128 - 8 - p.x);
if (p.y < 8) fy = pm * (8 - p.y);
else if (p.y > 128 - 8) fy = pm * (128 - 8 - p.y);
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - */
var vx : Number = (p.x - mx);
var vy : Number = (p.y - my);
if (vx < 0) vx = -vx;
if (vy < 0) vy = -vy;
if ((vx < 10.0) && (vy < 10.0))
{
var weight : Number = p.mass * (1.0 - (vx / 10.0)) * (1.0 - (vy / 10.0));
fx += weight * (mdx - p.u);
fy += weight * (mdy - p.v);
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - */
var phi : Number = p.x0 * p.y0;
n00.ax += -((p.gx0 * p.y0) * pressure) + fx * phi;
n00.ay += -((p.x0 * p.gy0) * pressure) + fy * phi;
phi = (p.x0 * p.y1);
n01.ax += -((p.gx0 * p.y1) * pressure) + fx * phi;
n01.ay += -((p.x0 * p.gy1) * pressure) + fy * phi;
phi = (p.x0 * p.y2);
n02.ax += -((p.gx0 * p.y2) * pressure) + fx * phi;
n02.ay += -((p.x0 * p.gy2) * pressure) + fy * phi;
phi = (p.x1 * p.y0);
n10.ax += -((p.gx1 * p.y0) * pressure) + fx * phi;
n10.ay += -((p.x1 * p.gy0) * pressure) + fy * phi;
phi = (p.x1 * p.y1);
n11.ax += -((p.gx1 * p.y1) * pressure) + fx * phi;
n11.ay += -((p.x1 * p.gy1) * pressure) + fy * phi;
phi = (p.x1 * p.y2);
n12.ax += -((p.gx1 * p.y2) * pressure) + fx * phi;
n12.ay += -((p.x1 * p.gy2) * pressure) + fy * phi;
phi = (p.x2 * p.y0);
n20.ax += -((p.gx2 * p.y0) * pressure) + fx * phi;
n20.ay += -((p.x2 * p.gy0) * pressure) + fy * phi;
phi = (p.x2 * p.y1);
n21.ax += -((p.gx2 * p.y1) * pressure) + fx * phi;
n21.ay += -((p.x2 * p.gy1) * pressure) + fy * phi;
phi = (p.x2 * p.y2);
n22.ax += -((p.gx2 * p.y2) * pressure) + fx * phi;
n22.ay += -((p.x2 * p.gy2) * pressure) + fy * phi;
p = p.next;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
n = nnn;
while (n != null)
{
if (n.active == true)
{
n.ax /= n.m;
n.ay /= n.m;
n.ay += 0.03;
}
n = n.next;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
p = ppp;
while (p != null)
{
n = p.node;
n00 = n;
n01 = n.n01;
n02 = n.n02;
n10 = n.n10;
n11 = n.n11;
n12 = n.n12;
n20 = n.n20;
n21 = n.n21;
n22 = n.n22;
p.u += (p.p00 * n00.ax + p.p10 * n10.ax + p.p20 * n20.ax + p.p01 * n01.ax + p.p11 * n11.ax + p.p21 * n21.ax + p.p02 * n02.ax + p.p12 * n12.ax + p.p22 * n22.ax);
p.v += (p.p00 * n00.ay + p.p10 * n10.ay + p.p20 * n20.ay + p.p01 * n01.ay + p.p11 * n11.ay + p.p21 * n21.ay + p.p02 * n02.ay + p.p12 * n12.ay + p.p22 * n22.ay);
var mu : Number = p.mass * p.u;
var mv : Number = p.mass * p.v;
n00.u += p.p00 * mu;
n00.v += p.p00 * mv;
n10.u += p.p10 * mu;
n10.v += p.p10 * mv;
n20.u += p.p20 * mu;
n20.v += p.p20 * mv;
n01.u += p.p01 * mu;
n01.v += p.p01 * mv;
n11.u += p.p11 * mu;
n11.v += p.p11 * mv;
n21.u += p.p21 * mu;
n21.v += p.p21 * mv;
n02.u += p.p02 * mu;
n02.v += p.p02 * mv;
n12.u += p.p12 * mu;
n12.v += p.p12 * mv;
n22.u += p.p22 * mu;
n22.v += p.p22 * mv;
p = p.next;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
n = nnn;
while (n != null)
{
if (n.active == true)
{
n.u /= n.m;
n.v /= n.m;
}
n = n.next;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
var buf : Vector.<uint> = this.buf;
var pos : uint = buf.length;
while (pos--) buf[pos] = 0x1F1814;
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
p = ppp;
while (p != null)
{
n = p.node;
var gu : Number = p.p00 * n.u + p.p10 * n.n10.u + p.p20 * n.n20.u + p.p01 * n.n01.u + p.p11 * n.n11.u + p.p21 * n.n21.u + p.p02 * n.n02.u + p.p12 * n.n12.u + p.p22 * n.n22.u;
var gv : Number = p.p00 * n.v + p.p10 * n.n10.v + p.p20 * n.n20.v + p.p01 * n.n01.v + p.p11 * n.n11.v + p.p21 * n.n21.v + p.p02 * n.n02.v + p.p12 * n.n12.v + p.p22 * n.n22.v;
p.x += gu;
p.y += gv;
p.u += gu - p.u;
p.v += gv - p.v;
if (p.x < 2)
{
p.x = 2.2;
p.u = 0.0;
}
else if (p.x > (128 - 2))
{
p.x = 128 - 2.2;
p.u = 0.0;
}
if (p.y < 2)
{
p.y = 2.2;
p.v = 0.0;
}
else if (p.y > (128 - 2))
{
p.y = 128 - 2.2;
p.v = 0.0;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - */
var c : uint = p.color;
var px0 : uint = (p.x * 4) >> 0;
var py0 : uint = (p.y * 4) >> 0;
var px1 : uint = ((p.x - p.u) * 4) >> 0;
var py1 : uint = ((p.y - p.v) * 4) >> 0;
buf[px0 + (py0 << 9)] = c;
buf[((px0 + px1) >> 1) + (((py0 + py1) >> 1) << 9)] = c;
buf[px1 + (py1 << 9)] = c;
p = p.next;
}
bmd.setVector(bmd.rect, buf);
}
}
}
internal class Node
{
public var next : Node;
public var active : Boolean;
public var m : Number = 0;
public var d : Number = 0;
public var gx : Number = 0;
public var gy : Number = 0;
public var u : Number = 0;
public var v : Number = 0;
public var ax : Number = 0;
public var ay : Number = 0;
public var n10 : Node;
public var n20 : Node;
public var n01 : Node;
public var n11 : Node;
public var n21 : Node;
public var n02 : Node;
public var n12 : Node;
public var n22 : Node;
function Node()
{
}
}
internal class Particle
{
public var next : Particle;
public var node : Node;
public var color : uint = 0x808080;
public var mass : Number = 1.0;
public var rd : Number = 1.0;
public var k : Number = 1.0;
public var gas : Boolean;
public var x : Number = 0.0;
public var y : Number = 0.0;
public var u : Number = 0.0;
public var v : Number = 0.0;
public var gx0 : Number;
public var gx1 : Number;
public var gx2 : Number;
public var gy0 : Number;
public var gy1 : Number;
public var gy2 : Number;
public var x0 : Number;
public var x1 : Number;
public var x2 : Number;
public var y0 : Number;
public var y1 : Number;
public var y2 : Number;
public var p00 : Number;
public var p10 : Number;
public var p20 : Number;
public var p01 : Number;
public var p11 : Number;
public var p21 : Number;
public var p02 : Number;
public var p12 : Number;
public var p22 : Number;
function Particle()
{
}
}