static void DrawCell(MegaFlow mod, Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, Matrix4x4 tm) { Color c1 = Color.black; Color c2 = Color.black; Color c3 = Color.black; Color c4 = Color.black; if ( mod.showcellmag ) { float thresh = mod.velThreshold * mod.velThreshold; float v = 0.0f; if ( v1.sqrMagnitude > thresh ) { v = v1.magnitude * cellrng; c1 = mod.GetCol(v); c1.a = mod.cellalpha; } else c1.a = 0.0f; if ( v2.sqrMagnitude > thresh ) { v = v2.magnitude * cellrng; c2 = mod.GetCol(v); c2.a = mod.cellalpha; } else c2.a = 0.0f; if ( v3.sqrMagnitude > thresh ) { v = v3.magnitude * cellrng; c3 = mod.GetCol(v); c3.a = mod.cellalpha; } else c3.a = 0.0f; if ( v4.sqrMagnitude > thresh ) { v = v4.magnitude * cellrng; c4 = mod.GetCol(v); c4.a = mod.cellalpha; } else c4.a = 0.0f; } else { c1.a = mod.cellalpha; c2.a = mod.cellalpha; c3.a = mod.cellalpha; c4.a = mod.cellalpha; float thresh = mod.velThreshold * mod.velThreshold; if ( v1.sqrMagnitude > thresh ) { v1 *= mod.Scale; c1.r = Mathf.Abs(v1.x); c1.g = Mathf.Abs(v1.y); c1.b = Mathf.Abs(v1.z); } else c1.a = 0.0f; if ( v2.sqrMagnitude > thresh ) { v2 *= mod.Scale; c2.r = Mathf.Abs(v2.x); c2.g = Mathf.Abs(v2.y); c2.b = Mathf.Abs(v2.z); } else c2.a = 0.0f; if ( v3.sqrMagnitude > thresh ) { v3 *= mod.Scale; c3.r = Mathf.Abs(v3.x); c3.g = Mathf.Abs(v3.y); c3.b = Mathf.Abs(v3.z); } else c3.a = 0.0f; if ( v4.sqrMagnitude > thresh ) { v4 *= mod.Scale; c4.r = Mathf.Abs(v4.x); c4.g = Mathf.Abs(v4.y); c4.b = Mathf.Abs(v4.z); } else c4.a = 0.0f; } p1 = tm.MultiplyPoint3x4(p1); p2 = tm.MultiplyPoint3x4(p2); p3 = tm.MultiplyPoint3x4(p3); p4 = tm.MultiplyPoint3x4(p4); GL.Begin(GL.TRIANGLES); GL.Color(c1); GL.Vertex(p1); GL.Color(c2); GL.Vertex(p2); GL.Color(c3); GL.Vertex(p3); GL.Color(c1); GL.Vertex(p1); GL.Color(c3); GL.Vertex(p3); GL.Color(c4); GL.Vertex(p4); GL.End(); }
static public void DisplayFlow(MegaFlow mod, float t, int flagst) { float smokethreshhold = mod.smokeThreshold; float velthreshold = mod.velThreshold; velthreshold *= velthreshold; bool showvel = mod.showVel; bool showsmoke = mod.showSmoke; int xd = mod.flow.gridDim2[0] - 1; int yd = mod.flow.gridDim2[1] - 1; int zd = mod.flow.gridDim2[2] - 1; int xs = 0; int ys = 0; int zs = 0; //Matrix4x4 offtm = Matrix4x4.TRS(-mod.flow.size * 0.5f, Quaternion.identity, Vector3.one); Matrix4x4 offtm = Matrix4x4.TRS((-mod.flow.size * 0.5f) + mod.flow.offset, Quaternion.identity, Vector3.one); Matrix4x4 tm = mod.transform.localToWorldMatrix * offtm; Handles.matrix = tm; //mod.transform.localToWorldMatrix * offtm; //Handles.matrix = mod.transform.localToWorldMatrix; float adjx = mod.flow.spacing.x * 0.5f; float adjy = mod.flow.spacing.y * 0.5f; float adjz = mod.flow.spacing.z * 0.5f; bool inbounds = false; mod.Prepare(); GL.PushMatrix(); CreateCellMaterial(); cellMaterial.SetPass(0); cellrng = 1.0f / (mod.maxvel - mod.minvel); if ( mod.Slice ) { Vector3[] cp = new Vector3[4]; Handles.color = mod.gridColor1; switch ( mod.Plane ) { case MegaFlowAxis.Y: yd = 0; ys = mod.Position; if ( ys >= mod.flow.gridDim2[1] - 1 ) ys = mod.flow.gridDim2[1] - 1; yd = ys + mod.Thickness; if ( yd >= mod.flow.gridDim2[1] - 1 ) yd = mod.flow.gridDim2[1] - 1; if ( mod.showgrid ) { for ( int x = xs; x <= xd + 1; x++ ) { Vector3 p; p.x = (x * mod.flow.spacing.x); p.y = (ys * mod.flow.spacing.y) + adjy; p.z = 0.0f; if ( x == xs || x == (xd + 1) ) Handles.color = Color.black; else Handles.color = mod.gridColor1; Vector3 p1 = p; p1.z = p.z + ((zd + 1) * mod.flow.spacing.z); DrawLine(p, p1); } for ( int z = zs; z <= (zd + 1); z++ ) { Vector3 p; p.x = 0.0f; p.y = (ys * mod.flow.spacing.y) + adjy; p.z = (z * mod.flow.spacing.z); if ( z == zs || z == (zd + 1) ) Handles.color = Color.black; else Handles.color = mod.gridColor1; Vector3 p1 = p; p1.x = p.x + ((xd + 1) * mod.flow.spacing.x); DrawLine(p, p1); } } cp[0] = new Vector3(0.0f, (yd * mod.flow.spacing.y) + adjy, 0.0f); cp[1] = new Vector3((xd + 1) * mod.flow.spacing.x, (yd * mod.flow.spacing.y) + adjy, 0.0f); cp[2] = new Vector3((xd + 1) * mod.flow.spacing.x, (yd * mod.flow.spacing.y) + adjy, (zd + 1) * mod.flow.spacing.z); cp[3] = new Vector3(0.0f, (yd * mod.flow.spacing.y) + adjy, (zd + 1) * mod.flow.spacing.z); Handles.color = mod.gridColor; DrawLine(cp[0], cp[1]); DrawLine(cp[1], cp[2]); DrawLine(cp[2], cp[3]); DrawLine(cp[3], cp[0]); if ( mod.showcells ) { //Matrix4x4 tm = mod.transform.localToWorldMatrix; Vector3 p; for ( int x = xs; x < xd; x++ ) { p.x = x * mod.flow.spacing.x + adjx; for ( int y = ys; y <= yd; y++ ) { p.y = y * mod.flow.spacing.y + adjy; for ( int z = zs; z < zd; z++ ) { p.z = z * mod.flow.spacing.z + adjz; Vector3 v1 = mod.SampleVel(x, y, z) * mod.velScl; Vector3 v2 = mod.SampleVel(x + 1, y, z) * mod.velScl; Vector3 v3 = mod.SampleVel(x + 1, y, z + 1) * mod.velScl; Vector3 v4 = mod.SampleVel(x, y, z + 1) * mod.velScl; Vector3 p1 = new Vector3(p.x, p.y, p.z); Vector3 p2 = new Vector3(p.x + mod.flow.spacing.x, p.y, p.z); Vector3 p3 = new Vector3(p.x + mod.flow.spacing.x, p.y, p.z + mod.flow.spacing.z); Vector3 p4 = new Vector3(p.x, p.y, p.z + mod.flow.spacing.z); DrawCell(mod, v1, v2, v3, v4, p1, p2, p3, p4, tm); } } } } break; case MegaFlowAxis.X: xd = 0; xs = mod.Position; if ( xs >= mod.flow.gridDim2[0] - 1 ) xs = mod.flow.gridDim2[0] - 1; xd = xs + mod.Thickness; if ( xd >= mod.flow.gridDim2[0] - 1 ) xd = mod.flow.gridDim2[0] - 1; if ( mod.showgrid ) { for ( int z = zs; z <= (zd + 1); z++ ) { Vector3 p; p.x = (xs * mod.flow.spacing.x) + adjx; p.y = 0.0f; p.z = (z * mod.flow.spacing.z); if ( z == zs || z == (zd + 1) ) Handles.color = Color.black; else Handles.color = mod.gridColor1; Vector3 p1 = p; p1.y = p.y + ((yd + 1) * mod.flow.spacing.y); DrawLine(p, p1); } for ( int y = ys; y <= (yd + 1); y++ ) { Vector3 p; p.x = (xs * mod.flow.spacing.x) + adjx; p.y = (y * mod.flow.spacing.y); p.z = 0.0f; if ( y == ys || y == (yd + 1) ) Handles.color = Color.black; else Handles.color = mod.gridColor1; Vector3 p1 = p; p1.z = p.z + ((zd + 1) * mod.flow.spacing.z); DrawLine(p, p1); } } cp[0] = new Vector3((xd * mod.flow.spacing.x) + adjx, 0.0f, 0.0f); cp[1] = new Vector3((xd * mod.flow.spacing.x) + adjx, 0.0f, ((zd + 1) * mod.flow.spacing.z)); cp[2] = new Vector3((xd * mod.flow.spacing.x) + adjx, ((yd + 1) * mod.flow.spacing.y), ((zd + 1) * mod.flow.spacing.z)); cp[3] = new Vector3((xd * mod.flow.spacing.x) + adjx, ((yd + 1) * mod.flow.spacing.y), 0.0f); Handles.color = mod.gridColor; DrawLine(cp[0], cp[1]); DrawLine(cp[1], cp[2]); DrawLine(cp[2], cp[3]); DrawLine(cp[3], cp[0]); if ( mod.showcells ) { //Matrix4x4 tm = mod.transform.localToWorldMatrix; Vector3 p; for ( int x = xs; x <= xd; x++ ) { p.x = x * mod.flow.spacing.x + adjx; for ( int y = ys; y < yd; y++ ) { p.y = y * mod.flow.spacing.y + adjy; for ( int z = zs; z < zd; z++ ) { p.z = z * mod.flow.spacing.z + adjz; Vector3 v1 = mod.SampleVel(x, y, z) * mod.velScl; Vector3 v2 = mod.SampleVel(x, y + 1, z) * mod.velScl; Vector3 v3 = mod.SampleVel(x, y + 1, z + 1) * mod.velScl; Vector3 v4 = mod.SampleVel(x, y, z + 1) * mod.velScl; Vector3 p1 = new Vector3(p.x, p.y, p.z); Vector3 p2 = new Vector3(p.x, p.y + mod.flow.spacing.y, p.z); Vector3 p3 = new Vector3(p.x, p.y + mod.flow.spacing.y, p.z + mod.flow.spacing.z); Vector3 p4 = new Vector3(p.x, p.y, p.z + mod.flow.spacing.z); DrawCell(mod, v1, v2, v3, v4, p1, p2, p3, p4, tm); } } } } break; case MegaFlowAxis.Z: zd = 0; zs = mod.Position; if ( zs >= mod.flow.gridDim2[2] - 1 ) zs = mod.flow.gridDim2[2] - 1; zd = zs + mod.Thickness; if ( zd >= mod.flow.gridDim2[2] - 1 ) zd = mod.flow.gridDim2[2] - 1; if ( mod.showgrid ) { for ( int x = xs; x <= (xd + 1); x++ ) { Vector3 p; p.x = (x * mod.flow.spacing.x); p.y = 0.0f; p.z = (zs * mod.flow.spacing.z) + adjz; if ( x == xs || x == (xd + 1) ) Handles.color = Color.black; else Handles.color = mod.gridColor1; Vector3 p1 = p; p1.y = p.y + ((yd + 1) * mod.flow.spacing.y); DrawLine(p, p1); } for ( int y = ys; y <= (yd + 1); y++ ) { Vector3 p; p.x = 0.0f; p.y = (y * mod.flow.spacing.y); p.z = (zs * mod.flow.spacing.z) + adjz; if ( y == ys || y == (yd + 1) ) Handles.color = Color.black; else Handles.color = mod.gridColor1; Vector3 p1 = p; p1.x = p.x + ((xd + 1) * mod.flow.spacing.x); DrawLine(p, p1); } } cp[0] = new Vector3(0.0f, 0.0f, (zd * mod.flow.spacing.z) + adjz); cp[1] = new Vector3(((xd + 1) * mod.flow.spacing.x), 0.0f, (zd * mod.flow.spacing.z) + adjz); cp[2] = new Vector3(((xd + 1) * mod.flow.spacing.x), ((yd + 1) * mod.flow.spacing.y), (zd * mod.flow.spacing.z) + adjz); cp[3] = new Vector3(0.0f, ((yd + 1) * mod.flow.spacing.y), (zd * mod.flow.spacing.z) + adjz); Handles.color = mod.gridColor; DrawLine(cp[0], cp[1]); DrawLine(cp[1], cp[2]); DrawLine(cp[2], cp[3]); DrawLine(cp[3], cp[0]); if ( mod.showcells ) { //Matrix4x4 tm = mod.transform.localToWorldMatrix; Vector3 p; for ( int x = xs; x < xd; x++ ) { p.x = x * mod.flow.spacing.x + adjx; for ( int y = ys; y < yd; y++ ) { p.y = y * mod.flow.spacing.y + adjy; for ( int z = zs; z <= zd; z++ ) { p.z = z * mod.flow.spacing.z + adjz; Vector3 v1 = mod.SampleVel(x, y, z) * mod.velScl; Vector3 v2 = mod.SampleVel(x + 1, y, z) * mod.velScl; Vector3 v3 = mod.SampleVel(x + 1, y + 1, z) * mod.velScl; Vector3 v4 = mod.SampleVel(x, y + 1, z) * mod.velScl; Vector3 p1 = new Vector3(p.x, p.y, p.z); Vector3 p2 = new Vector3(p.x + mod.flow.spacing.x, p.y, p.z); Vector3 p3 = new Vector3(p.x + mod.flow.spacing.x, p.y + mod.flow.spacing.y, p.z); Vector3 p4 = new Vector3(p.x, p.y + mod.flow.spacing.y, p.z); DrawCell(mod, v1, v2, v3, v4, p1, p2, p3, p4, tm); } } } } break; } } GL.PopMatrix(); if ( showvel && (mod.flow.vel.Count > 0 || mod.flow.optvel.Count > 0) ) { if ( mod.skip < 1 ) mod.skip = 1; Color col = Color.white; //mod.GetCol(len * mod.velScl); col.a = mod.velAlpha; if ( !mod.showvelmag ) { // Color shows direction for ( int x = xs; x <= xd; x += mod.skip ) { for ( int y = ys; y <= yd; y += mod.skip ) { for ( int z = zs; z <= zd; z += mod.skip ) { Vector3 p; p.x = x * mod.flow.spacing.x + adjx; p.y = y * mod.flow.spacing.y + adjy; p.z = z * mod.flow.spacing.z + adjz; Vector3 vel = mod.SampleVel(x, y, z); if ( vel.sqrMagnitude > velthreshold ) { //float len = vel.magnitude; col.r = Mathf.Abs(vel.x * mod.velScl); col.g = Mathf.Abs(vel.y * mod.velScl); col.b = Mathf.Abs(vel.z * mod.velScl); Handles.color = col; Vector3 p1 = p + (vel * mod.velLen); //scale); DrawLine(p, p1); } } } } } else { float rng = 1.0f / (mod.maxvel - mod.minvel); // color shows magnitude for ( int x = xs; x <= xd; x += mod.skip ) { for ( int y = ys; y <= yd; y += mod.skip ) { for ( int z = zs; z <= zd; z += mod.skip ) { Vector3 p; p.x = x * mod.flow.spacing.x + adjx; p.y = y * mod.flow.spacing.y + adjy; p.z = z * mod.flow.spacing.z + adjz; Vector3 vel = mod.SampleVel(x, y, z); if ( vel.sqrMagnitude > velthreshold ) { float len = vel.magnitude * mod.velScl; col = mod.GetCol(len * rng); Handles.color = col; Vector3 p1 = p + (vel * mod.velLen); //scale); DrawLine(p, p1); } } } } } } if ( showsmoke && mod.flow.smoke.Count > 0 ) { GUIStyle style = new GUIStyle(); for ( int x = xs; x < xd; x++ ) { for ( int y = ys; y < yd; y++ ) { for ( int z = zs; z < zd; z++ ) { Vector3 p; p.x = x * mod.flow.spacing.x; p.y = y * mod.flow.spacing.y; p.z = z * mod.flow.spacing.z; float s = mod.flow.smoke[(x * mod.flow.gridDim2[2] * mod.flow.gridDim2[1]) + (z * mod.flow.gridDim2[1]) + y]; if ( s > smokethreshhold ) { Color col = mod.GetCol(s); col.a = mod.smokeAlpha; style.normal.textColor = col; Handles.Label(p, "" + s.ToString("0.00"), style); } } } } } Vector3 pos = mod.ribpos; Vector3 vel1 = mod.GetGridVel(pos, ref inbounds); if ( inbounds ) { float len = vel1.magnitude; Color col = mod.GetCol(len); Handles.color = col; Vector3 p1 = pos + vel1; // * scale); DrawLine(pos, p1); } if ( mod.showRibbon ) DisplayRibbons(mod); Handles.matrix = Matrix4x4.identity; }
void RibbonPhysics(MegaFlow mod, float t) { if ( !mod.showRibbon || mod.flow == null ) return; if ( mod.Dt < 0.002f ) mod.Dt = 0.002f; float dt = mod.Dt; mod.Prepare(); mod.calculated = 0; mod.calcTime = Time.realtimeSinceStartup; mod.ribbons.Clear(); bool inbounds = false; float p = mod.Density; float A = mod.Area; float Re = mod.Reynolds; float mass = mod.Mass; int linestep = mod.LineStep; float zs = mod.SizeZ; int zst = mod.StepZ; if ( zst == 0 ) return; float ys = mod.SizeY; int yst = mod.StepY; if ( yst == 0 ) return; float coef = 1.0f * p * A * Mathf.Pow(Re, -0.5f); Vector3 Fgrv = mod.Gravity * mass; for ( int zi = 0; zi < zst; zi++ ) { float z; if ( zst == 1 ) z = 0.0f; else z = (((float)zi / (float)(zst - 1)) - 0.5f) * 2.0f * zs; for ( int yi = 0; yi < yst; yi++ ) { Ribbon ribbon = new Ribbon(); float y; if ( yst == 1 ) y = 0.0f; else y = (((float)yi / (float)(yst - 1)) - 0.5f) * 2.0f * ys; Vector3 pos = mod.ribpos; pos.z += z; pos.y += y; Vector3 vel = mod.GetGridVel(pos, ref inbounds); // * scale; mod.calculated++; if ( inbounds ) { float U = 1.0f; float duration = mod.Duration; Vector3 Fshape = Vector3.zero; // Random force due to particle shape int linecount = 0; while ( duration > 0.0f ) { mod.calculated++; Vector3 airvel = mod.GetGridVel(pos, ref inbounds); // * scale; if ( !inbounds ) { airvel = new Vector3(mod.Scale, 0.0f, 0.0f); break; } Vector3 tvel = airvel - vel; U = tvel.magnitude; //tvel.sqrMagnitude; float df = coef * U; Vector3 dir = tvel.normalized; Vector3 Fdrag = dir * df; Vector3 Fp = Fdrag + Fshape + Fgrv; Vector3 acc = Fp / mass; vel += acc * dt; pos += vel * dt; linecount--; if ( linecount < 0 ) { ribbon.points.Add(pos); Color col = mod.GetCol(vel.magnitude * mod.ribbonscale); col.a = mod.ribbonAlpha; ribbon.cols.Add(col); linecount = linestep; } duration -= dt; } if ( linecount != linestep ) { ribbon.points.Add(pos); Color col = mod.GetCol(vel.magnitude * mod.ribbonscale); col.a = mod.ribbonAlpha; ribbon.cols.Add(col); } } mod.ribbons.Add(ribbon); } } mod.calcTime = Time.realtimeSinceStartup - mod.calcTime; }