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;
	}