FLUID~MAFIA~+
Mouse Position ==> Gravity
+ [ update : lil debug + optimization ]
ref. http://grantkot.com/newfluid/
/**
* Copyright FLASHMAFIA ( http://wonderfl.net/user/FLASHMAFIA )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/oTEF
*/
package {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
[SWF(width='465', height='465')]
public class GKFluidS01 extends Sprite {
private const NUM_P : 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>;
function GKFluidS01()
{
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 = NUM_P;
while (i-- != 0) {
var id : uint = (i >> 2) & 3;
if (id == 0) {
p.color = 0x0F0804;
p.mass = 10.0;
p.k = 0.2;
p.rd = 1.0;
p.gas = false;
} else if (id == 1) {
p.color = 0x8F8884;
p.mass = 1.25;
p.k = 1.0;
p.rd = 1.0;
p.gas = false;
} else if (id == 2) {
p.color = 0xCFC8C4;
p.mass = 1.50;
p.k = 1.0;
p.rd = 1.0;
p.gas = false;
} else if (id == 3) {
p.color = 0xFFF8F4;
p.mass = 1.5;
p.gas = true;
}
p.x = 0.1 + 0.9 * (i & 127);
p.y = 0.1 + 0.9 * ((i >> 7) & 127);
p.id = id;
p = p.next = new Particle();
}
stage.addEventListener(Event.ENTER_FRAME, oef);
}
private function oef(e : Event) : void {
var mgx : Number = (stage.mouseX / 512) - 0.5;
var mgy : Number = (stage.mouseY / 512) - 0.5;
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) {
p.cx = (p.x - 0.5) >> 0;
p.cy = (p.y - 0.5) >> 0;
var pcx : uint = p.cx;
var pcy : uint = p.cy;
var d : Number = p.cx - 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 = p.cy - 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;
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - PRESSURE */
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.9;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
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);
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - CURVATURE */
var phi : Number = p.x0 * p.y0;
var dx : Number = p.gx0 * p.y0;
var dy : Number = p.x0 * p.gy0;
n00.ax += -(dx * pressure) + fx * phi;
n00.ay += -(dy * 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;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
var gravX : Number = 0.11 * mgx;
var gravY : Number = 0.11 * mgy;
n = nnn;
while (n != null) {
if (n.active == true) {
n.ax /= n.m;
n.ay /= n.m;
n.ax += gravX;
n.ay += gravY;
}
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] = 0x5F5854;
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;
}
/* draw */
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;
var pos0 : uint = px0 + (py0 << 9);
var pos1 : uint = ((px0 + px1) >> 1) + (((py0 + py1) >> 1) << 9);
var pos2 : uint = px1 + (py1 << 9);
buf[pos0] = c;
buf[(pos0 - 1) & 262143] = c;
buf[(pos0 + 1) & 262143] = c;
buf[(pos0 + 512) & 262143] = c;
buf[(pos0 - 512) & 262143] = c;
buf[pos1] = c;
buf[pos2] = c;
p = p.next;
}
bmd.setVector(bmd.rect, buf);
}
}
}
internal class Node {
public var next : Node;
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 active : Boolean;
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 id : uint;
public var color : uint = 0x0000FF;
public var mass : Number;
public var rd : Number;
public var k : Number;
public var gas : Boolean;
public var cx : uint;
public var cy : uint;
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() {
}
}