public void LoadFumeFrame(MegaFlow flow, string filename)
	{
		if ( flow.frames.Count > 0 )
		{
			if ( !EditorUtility.DisplayDialog("Add to or Replace", "Add new frame to existing frames", "Add", "Replace") )
				flow.DestroyFrames();
		}
		flow.AddFrame(MegaFlowFumeFX.LoadFrame(filename));
	}
	public void LoadFGASeq(MegaFlow flow, string filename, int first, int last, int step)
	{
		if ( flow.frames.Count > 0 )
		{
			if ( !EditorUtility.DisplayDialog("Add to or Replace", "Add new frames to existing frames, or Replace All", "Add", "Replace") )
				flow.DestroyFrames();
		}

		for ( int i = first; i <= last; i += step )
		{
			float a = (float)(i + 1 - first) / (last - first);
			if ( !EditorUtility.DisplayCancelableProgressBar("Loading Fluid Frames", "Frame " + i, a) )
				flow.AddFrame(MegaFlowFGA.LoadFrame(filename, i, flow.namesplit, flow.decform));
			else
				break;
		}

		EditorUtility.ClearProgressBar();
	}
Exemple #3
0
    public void DrawMoveGizmo()
    {
        if (source)
        {
            flow = source.frames[framenum];
        }

        if (flow)
        {
            Matrix4x4 offtm = Matrix4x4.TRS(-flow.size * 0.5f, Quaternion.identity, Vector3.one);
            framegizmotm = transform.localToWorldMatrix * offtm;

            Gizmos.matrix = framegizmotm;

            Vector3 min = Vector3.zero;
            Vector3 max = flow.size;
            MegaFlow.DrawBox(min, max);
            Gizmos.matrix = Matrix4x4.identity;
        }
    }
Exemple #4
0
    public override void OnInspectorGUI()
    {
        MegaFlowCreateFromSplines mod = (MegaFlowCreateFromSplines)target;

        serializedObject.Update();

        if (GUILayout.Button("Create Flow"))
        {
            CreateFlow(mod, mod.flow);
        }

#if !UNITY_5 && !UNITY_2017 && !UNITY_2018 && !UNITY_2019 && !UNITY_2020
        EditorGUIUtility.LookLikeControls();
#endif

        if (GUILayout.Button("Preview Flow"))
        {
            CreatePreview(mod);
        }

        if (mod.preview)
        {
            if (GUILayout.Button("Clear Preview"))
            {
                ClearPreview(mod);
            }
        }

        mod.size   = EditorGUILayout.Vector3Field("Size", mod.size);
        mod.square = EditorGUILayout.Toggle("Square Cells", mod.square);

        mod.gridx = EditorGUILayout.IntField("Grid X", mod.gridx);
        mod.gridy = EditorGUILayout.IntField("Grid Y", mod.gridy);
        mod.gridz = EditorGUILayout.IntField("Grid Z", mod.gridz);

        EditorGUILayout.PropertyField(_prop_startval, new GUIContent("Start Value"));

        mod.velocity      = EditorGUILayout.FloatField("Velocity", mod.velocity);
        mod.vellen        = EditorGUILayout.FloatField("Vel Len", mod.vellen);
        mod.flow          = (MegaFlow)EditorGUILayout.ObjectField("Flow", mod.flow, typeof(MegaFlow), true);
        mod.emtyspacemode = (MegaFlowMode)EditorGUILayout.EnumPopup("Empty Space", mod.emtyspacemode);
        mod.shownotsel    = EditorGUILayout.Toggle("Gizmo Always Show", mod.shownotsel);

        //mod.showvelmag = EditorGUILayout.BeginToggleGroup("Show Vel Mag", mod.showvelmag);
        EditorGUILayout.PropertyField(_prop_velcols, new GUIContent("Colors"));
        mod.minvel = EditorGUILayout.FloatField("Min Vel", mod.minvel);
        mod.maxvel = EditorGUILayout.FloatField("Max Vel", mod.maxvel);
        //EditorGUILayout.EndToggleGroup();

        mod.texture      = (Texture3D)EditorGUILayout.ObjectField("Texture3D", mod.texture, typeof(Texture3D), true);
        mod.texturescale = EditorGUILayout.FloatField("Texture Scale", mod.texturescale);

        if (mod.preview)
        {
            //bool changed = GUI.changed;

            MegaFlow modp = mod.preview;
            modp.showdisplayparams = EditorGUILayout.Foldout(modp.showdisplayparams, "Data Display Params");

            if (modp.showdisplayparams)
            {
                EditorGUILayout.BeginVertical("box");
                modp.Scale = EditorGUILayout.FloatField("Scale Frc", modp.Scale);

                modp.Plane = (MegaFlowAxis)EditorGUILayout.EnumPopup("Plane", modp.Plane);

                if (modp.flow != null)
                {
                    switch (modp.Plane)
                    {
                    case MegaFlowAxis.X:
                    {
                        int pos = EditorGUILayout.IntSlider("Position", modp.Position, 0, modp.flow.gridDim2[0] - 1);
                        if (pos != modp.Position)
                        {
                            modp.Position    = pos;
                            modp.handlepos.x = pos * modp.flow.spacing.x;
                        }
                        modp.Thickness = EditorGUILayout.IntSlider("Thickness", modp.Thickness, 0, modp.flow.gridDim2[0]);
                    }
                    break;

                    case MegaFlowAxis.Y:
                    {
                        int pos = EditorGUILayout.IntSlider("Position", modp.Position, 0, modp.flow.gridDim2[1] - 1);
                        if (pos != modp.Position)
                        {
                            modp.Position    = pos;
                            modp.handlepos.y = pos * modp.flow.spacing.y;
                        }
                        modp.Thickness = EditorGUILayout.IntSlider("Thickness", modp.Thickness, 0, modp.flow.gridDim2[1]);
                    }
                    break;

                    case MegaFlowAxis.Z:
                    {
                        int pos = EditorGUILayout.IntSlider("Position", modp.Position, 0, modp.flow.gridDim2[2] - 1);
                        if (pos != modp.Position)
                        {
                            modp.Position    = pos;
                            modp.handlepos.z = pos * modp.flow.spacing.z;
                        }
                        modp.Thickness = EditorGUILayout.IntSlider("Thickness", modp.Thickness, 0, modp.flow.gridDim2[2]);
                    }
                    break;
                    }
                }

                modp.velScl = EditorGUILayout.FloatField("Vel Visual Magnitude", modp.velScl);
                if (modp.velScl < 0.01f)
                {
                    modp.velScl = 0.01f;
                }

                modp.showvelmag = EditorGUILayout.BeginToggleGroup("Show Vel Mag", modp.showvelmag);
                EditorGUILayout.PropertyField(_prop_velcols, new GUIContent("Colors"));
                modp.velcols = mod.velcols;
                //modp.velcols.alphaKeys = mod.velcols.alphaKeys;
                //modp.velcols.colorKeys = mod.velcols.colorKeys;
                modp.minvel = EditorGUILayout.FloatField("Min Vel", modp.minvel);
                modp.maxvel = EditorGUILayout.FloatField("Max Vel", modp.maxvel);
                EditorGUILayout.EndToggleGroup();

                EditorGUILayout.BeginVertical("Box");
                if (modp.flow && (modp.flow.vel.Count > 0 || modp.flow.optvel.Count > 0))
                {
                    modp.showVel = EditorGUILayout.BeginToggleGroup("Show Vel", modp.showVel);
                    modp.velLen  = EditorGUILayout.FloatField("Vel Vector Len", modp.velLen);
                    if (modp.velLen < 0.01f)
                    {
                        modp.velLen = 0.01f;
                    }
                    modp.skip         = EditorGUILayout.IntField("Vel Skip", modp.skip);
                    modp.velThreshold = EditorGUILayout.Slider("Vel Threshold", modp.velThreshold, 0.0f, 1.0f);
                    modp.velAlpha     = EditorGUILayout.Slider("Vel Alpha", modp.velAlpha, 0.0f, 1.0f);
                    EditorGUILayout.EndToggleGroup();
                }
                EditorGUILayout.EndVertical();

                modp.showgrid   = EditorGUILayout.Toggle("Show Grid", modp.showgrid);
                modp.gridColor  = EditorGUILayout.ColorField("Grid Color", modp.gridColor);
                modp.gridColor1 = EditorGUILayout.ColorField("Grid Color1", modp.gridColor1);

                modp.showcells   = EditorGUILayout.BeginToggleGroup("Show Cells", modp.showcells);
                modp.showcellmag = EditorGUILayout.Toggle("Show Cell Mag", modp.showcellmag);
                modp.cellalpha   = EditorGUILayout.Slider("Cell Alpha", modp.cellalpha, 0.0f, 1.0f);
                EditorGUILayout.EndToggleGroup();

                EditorGUILayout.EndVertical();

                //if ( !changed && GUI.changed )
                //{
                //EditorUtility.SetDirty(modp);
                //}
            }
        }

        mod.showsplines = EditorGUILayout.Foldout(mod.showsplines, "Splines");

        if (mod.showsplines)
        {
            if (GUILayout.Button("Add Spline"))
            {
                MegaFlowSpline spl = new MegaFlowSpline();
                mod.splines.Add(spl);
            }
            //mod.splinepos = EditorGUILayout.BeginScrollView(mod.splinepos, GUILayout.Height(200));

            for (int i = 0; i < mod.splines.Count; i++)
            {
                MegaFlowSpline spl = mod.splines[i];

                string name = "Empty";
                if (spl.shape)
                {
                    name = spl.shape.name;
                }

                EditorGUILayout.BeginVertical("box");
                spl.show = EditorGUILayout.Foldout(spl.show, name);

                if (spl.show)
                {
                    spl.include     = EditorGUILayout.BeginToggleGroup("Include", spl.include);
                    spl.shape       = (MegaShape)EditorGUILayout.ObjectField("Shape", spl.shape, typeof(MegaShape), true);
                    spl.weight      = EditorGUILayout.FloatField("Weight", spl.weight);
                    spl.velocity    = EditorGUILayout.FloatField("Velocity", spl.velocity);
                    spl.falloffdist = EditorGUILayout.FloatField("Falloff Dist", spl.falloffdist);
                    spl.falloffcrv  = EditorGUILayout.CurveField("Falloff Crv", spl.falloffcrv);
                    spl.velcrv      = EditorGUILayout.CurveField("Vel Crv", spl.velcrv);
                    spl.distcrv     = EditorGUILayout.CurveField("Dist Crv", spl.distcrv);
                    spl.mode        = (MegaFlowMode)EditorGUILayout.EnumPopup("Mode", spl.mode);
                    spl.visrings    = EditorGUILayout.IntSlider("Rings", spl.visrings, 1, 50);
                    spl.ringalpha   = EditorGUILayout.Slider("Ring Alpha", spl.ringalpha, 0.0f, 1.0f);
                    EditorGUILayout.EndToggleGroup();

                    if (GUILayout.Button("Delete"))
                    {
                        mod.splines.RemoveAt(i);
                    }
                }
                EditorGUILayout.EndVertical();
            }
            //EditorGUILayout.EndScrollView();
        }

        mod.showmods = EditorGUILayout.Foldout(mod.showmods, "Modifiers");

        if (mod.showmods)
        {
            if (GUILayout.Button("Add Modifier"))
            {
                MegaFlowModifier fmod = new MegaFlowModifier();
                mod.modifiers.Add(fmod);
            }

            //mod.modpos = EditorGUILayout.BeginScrollView(mod.modpos, GUILayout.Height(150));

            for (int i = 0; i < mod.modifiers.Count; i++)
            {
                MegaFlowModifier fmod = mod.modifiers[i];

                string name = "Empty";
                if (fmod.obj)
                {
                    name = fmod.obj.name;
                }

                EditorGUILayout.BeginVertical("box");
                fmod.show = EditorGUILayout.Foldout(fmod.show, name);

                if (fmod.show)
                {
                    fmod.include = EditorGUILayout.BeginToggleGroup("Include", fmod.include);
                    fmod.type    = (MegaFlowModType)EditorGUILayout.EnumPopup("Type", fmod.type);
                    fmod.obj     = (Collider)EditorGUILayout.ObjectField("Object", fmod.obj, typeof(Collider), true);
                    fmod.amount  = EditorGUILayout.FloatField("Amount", fmod.amount);
                    EditorGUILayout.EndToggleGroup();

                    if (GUILayout.Button("Delete"))
                    {
                        mod.modifiers.RemoveAt(i);
                    }
                }

                EditorGUILayout.EndVertical();
            }
            //EditorGUILayout.EndScrollView();
        }

        if (GUI.changed)
        {
            serializedObject.ApplyModifiedProperties();
            EditorUtility.SetDirty(target);
        }
    }
Exemple #5
0
    public void CreateFlow(MegaFlowCreateFromSplines mod, MegaFlow flow)
    {
        int gx = mod.gridx;
        int gy = mod.gridy;
        int gz = mod.gridz;

        if (mod.square)
        {
            int axis = 0;
            if (Mathf.Abs(mod.size.x) > Mathf.Abs(mod.size.y))
            {
                if (Mathf.Abs(mod.size.x) > Mathf.Abs(mod.size.z))
                {
                    axis = 0;
                }
                else
                {
                    axis = 2;
                }
            }
            else
            {
                if (Mathf.Abs(mod.size.y) > Mathf.Abs(mod.size.z))
                {
                    axis = 1;
                }
                else
                {
                    axis = 2;
                }
            }

            float csize = mod.size[axis] / mod.gridx;

            mod.cellsize = new Vector3(csize, csize, csize);
        }
        else
        {
            mod.cellsize.x = mod.size.x / mod.gridx;
            mod.cellsize.y = mod.size.y / mod.gridy;
            mod.cellsize.z = mod.size.z / mod.gridz;
        }

        gx = (int)(mod.size.x / mod.cellsize.x);
        gy = (int)(mod.size.y / mod.cellsize.y);
        gz = (int)(mod.size.z / mod.cellsize.z);

        Vector3[] cells = new Vector3[gx * gy * gz];

        for (int i = 0; i < cells.Length; i++)
        {
            cells[i] = mod.startval;
        }

        Vector3 pos = Vector3.zero;

        Vector3 half  = mod.cellsize * 0.5f;
        Vector3 tan   = Vector3.zero;
        int     kn    = 0;
        float   alpha = 0.0f;

        List <MegaFlowContrib> contrib = new List <MegaFlowContrib>();

        Matrix4x4 offtm = Matrix4x4.TRS(-mod.size * 0.5f, Quaternion.identity, Vector3.one);

        Matrix4x4 tm = mod.transform.localToWorldMatrix * offtm;

        if (mod.texture)
        {
            Vector3 p;
            Color[] cols = mod.texture.GetPixels();

            for (int z = 0; z < gz; z++)
            {
                int tz = (int)(((float)z / (float)gz) * mod.texture.depth);                     // * f.size.z;

                for (int y = 0; y < gy; y++)
                {
                    int ty = (int)(((float)y / (float)gy) * mod.texture.height);                        // * f.size.y;

                    for (int x = 0; x < gx; x++)
                    {
                        int tx = (int)(((float)x / (float)gx) * mod.texture.width);                             // * f.size.x;

                        Color cvel = cols[(tz * mod.texture.width * mod.texture.height) + (ty * mod.texture.width) + tx];

                        p.x = (cvel.r - 0.5f) * 2.0f;
                        p.y = (cvel.g - 0.5f) * 2.0f;
                        p.z = (cvel.b - 0.5f) * 2.0f;
                        cells[(x * gz * gy) + (z * gy) + y] = p * mod.texturescale;
                    }
                }
            }
        }

        for (int z = 0; z < gz; z++)
        {
            pos.z = (z * mod.cellsize.z) + half.z;

            EditorUtility.DisplayProgressBar("Building Vector Field", "Building", (float)z / (float)gz);

            for (int y = 0; y < gy; y++)
            {
                pos.y = (y * mod.cellsize.y) + half.y;

                for (int x = 0; x < gx; x++)
                {
                    pos.x = (x * mod.cellsize.x) + half.x;

                    contrib.Clear();
                    float   nearest   = float.MaxValue;
                    Vector3 neardelta = Vector3.zero;

                    for (int i = 0; i < mod.splines.Count; i++)
                    {
                        MegaFlowSpline fs = mod.splines[i];

                        if (fs.include)
                        {
                            Vector3 wp = tm.MultiplyPoint3x4(pos);
                            Vector3 np = fs.shape.FindNearestPointWorld(wp, 5, ref kn, ref tan, ref alpha);

                            Vector3 delta = np - wp;

                            float dist  = delta.magnitude;
                            float fdist = fs.distcrv.Evaluate(alpha) * fs.falloffdist;

                            if (dist < nearest)
                            {
                                nearest   = dist;
                                neardelta = delta;
                            }

                            if (dist < fdist)
                            {
                                MegaFlowContrib con = new MegaFlowContrib();
                                con.src   = fs;
                                con.dist  = dist;
                                con.vel   = (tan - np).normalized * fs.velocity;
                                con.delta = delta.normalized;
                                con.alpha = alpha;
                                con.fdist = fdist;
                                contrib.Add(con);
                            }
                        }
                    }

                    if (contrib.Count > 0)
                    {
                        float tweight = 0.0f;
                        for (int c = 0; c < contrib.Count; c++)
                        {
                            tweight += contrib[c].src.weight;
                        }

                        Vector3 vel = cells[(x * gz * gy) + (z * gy) + y];                              //Vector3.zero;

                        for (int c = 0; c < contrib.Count; c++)
                        {
                            float a    = contrib[c].dist / contrib[c].fdist;
                            float lerp = contrib[c].src.falloffcrv.Evaluate(a);

                            float v = mod.velocity * contrib[c].src.velcrv.Evaluate(contrib[c].alpha);

                            switch (contrib[c].src.mode)
                            {
                            case MegaFlowMode.Attract:
                                vel += Vector3.Lerp(contrib[c].delta, contrib[c].vel, lerp) * v * (contrib[c].src.weight / tweight);
                                break;

                            case MegaFlowMode.Repulse:
                                vel += Vector3.Lerp(-contrib[c].delta, contrib[c].vel, lerp) * v * (contrib[c].src.weight / tweight);
                                break;

                            case MegaFlowMode.Flow:
                                vel += Vector3.Lerp(Vector3.zero, contrib[c].vel, lerp) * v * (contrib[c].src.weight / tweight);
                                break;
                            }
                        }

                        cells[(x * gz * gy) + (z * gy) + y] = vel;
                    }
                    else
                    {
                        Vector3 vl = cells[(x * gz * gy) + (z * gy) + y];                               //Vector3.zero;

                        switch (mod.emtyspacemode)
                        {
                        case MegaFlowMode.Attract:
                            vl = (neardelta.normalized * mod.velocity) + mod.startval;
                            break;

                        case MegaFlowMode.Repulse:
                            vl = (-neardelta.normalized * mod.velocity) + mod.startval;
                            break;

                        case MegaFlowMode.Flow:
                            break;
                        }

                        cells[(x * gz * gy) + (z * gy) + y] = vl;
                    }
                }
            }
        }
        EditorUtility.ClearProgressBar();

        for (int i = 0; i < mod.modifiers.Count; i++)
        {
            EditorUtility.DisplayProgressBar("Adding Modifiers", "Building", (float)i / (float)mod.modifiers.Count);

            MegaFlowModifier fmod = mod.modifiers[i];

            if (fmod.include && fmod.obj)
            {
                Ray ray = new Ray(Vector3.zero, Vector3.zero);

                for (int z = 0; z < gz; z++)
                {
                    pos.z = (z * mod.cellsize.z) + half.z;

                    for (int y = 0; y < gy; y++)
                    {
                        pos.y = (y * mod.cellsize.y) + half.y;

                        for (int x = 0; x < gx; x++)
                        {
                            pos.x = (x * mod.cellsize.x) + half.x;

                            Vector3 wpos = tm.MultiplyPoint3x4(pos);

                            Vector3 origin = wpos;
                            origin.y += 1000.0f;

                            ray.origin    = origin;
                            ray.direction = Vector3.down;

                            RaycastHit hit;

                            if (fmod.obj.Raycast(ray, out hit, 1000.0f))
                            {
                                ray.direction = Vector3.up;
                                origin.y     -= 2000.0f;
                                ray.origin    = origin;

                                if (fmod.obj.Raycast(ray, out hit, 1000.0f))
                                {
                                    switch (fmod.type)
                                    {
                                    case MegaFlowModType.VelChange:
                                        Vector3 vel = cells[(x * gz * gy) + (z * gy) + y];
                                        vel *= fmod.amount;
                                        cells[(x * gz * gy) + (z * gy) + y] = vel;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        EditorUtility.ClearProgressBar();

        if (flow)
        {
            MegaFlowFrame newf = ScriptableObject.CreateInstance <MegaFlowFrame>();

            newf.gridDim2[0] = gx;
            newf.gridDim2[1] = gy;
            newf.gridDim2[2] = gz;

            newf.size  = mod.size;
            newf.gsize = newf.size;

            newf.spacing.x = newf.size.x / newf.gridDim2[0];
            newf.spacing.y = newf.size.y / newf.gridDim2[1];
            newf.spacing.z = newf.size.z / newf.gridDim2[2];

            newf.oos.x = 1.0f / newf.spacing.x;
            newf.oos.y = 1.0f / newf.spacing.y;
            newf.oos.z = 1.0f / newf.spacing.z;

            newf.vel.AddRange(cells);
            flow.AddFrame(newf);
        }
    }
	public void CreateFlow(MegaFlowCreateFromSplines mod, MegaFlow flow)
	{
		int gx = mod.gridx;
		int gy = mod.gridy;
		int gz = mod.gridz;

		if ( mod.square )
		{
			int axis = 0;
			if ( Mathf.Abs(mod.size.x) > Mathf.Abs(mod.size.y) )
			{
				if ( Mathf.Abs(mod.size.x) > Mathf.Abs(mod.size.z) )
					axis = 0;
				else
					axis = 2;
			}
			else
			{
				if ( Mathf.Abs(mod.size.y) > Mathf.Abs(mod.size.z) )
					axis = 1;
				else
					axis = 2;
			}

			float csize = mod.size[axis] / mod.gridx;

			mod.cellsize = new Vector3(csize, csize, csize);
		}
		else
		{
			mod.cellsize.x = mod.size.x / mod.gridx;
			mod.cellsize.y = mod.size.y / mod.gridy;
			mod.cellsize.z = mod.size.z / mod.gridz;
		}

		gx = (int)(mod.size.x / mod.cellsize.x);
		gy = (int)(mod.size.y / mod.cellsize.y);
		gz = (int)(mod.size.z / mod.cellsize.z);

		Vector3[] cells = new Vector3[gx * gy * gz];

		for ( int i = 0; i < cells.Length; i++ )
			cells[i] = mod.startval;

		Vector3 pos = Vector3.zero;

		Vector3 half = mod.cellsize * 0.5f;
		Vector3 tan = Vector3.zero;
		int kn = 0;
		float alpha = 0.0f;

		List<MegaFlowContrib>	contrib = new List<MegaFlowContrib>();

		Matrix4x4 offtm = Matrix4x4.TRS(-mod.size * 0.5f, Quaternion.identity, Vector3.one);

		Matrix4x4 tm = mod.transform.localToWorldMatrix * offtm;

		if ( mod.texture )
		{
			Vector3 p;
			Color[] cols = mod.texture.GetPixels();

			for ( int z = 0; z < gz; z++ )
			{
				int tz = (int)(((float)z / (float)gz) * mod.texture.depth);	// * f.size.z;

				for ( int y = 0; y < gy; y++ )
				{
					int ty = (int)(((float)y / (float)gy) * mod.texture.height);	// * f.size.y;

					for ( int x = 0; x < gx; x++ )
					{
						int tx = (int)(((float)x / (float)gx) * mod.texture.width);	// * f.size.x;

						Color cvel = cols[(tz * mod.texture.width * mod.texture.height) + (ty * mod.texture.width) + tx];

						p.x = (cvel.r - 0.5f) * 2.0f;
						p.y = (cvel.g - 0.5f) * 2.0f;
						p.z = (cvel.b - 0.5f) * 2.0f;
						cells[(x * gz * gy) + (z * gy) + y] = p * mod.texturescale;
					}
				}
			}
		}

		for ( int z = 0; z < gz; z++ )
		{
			pos.z = (z * mod.cellsize.z) + half.z;

			EditorUtility.DisplayProgressBar("Building Vector Field", "Building", (float)z / (float)gz);

			for ( int y = 0; y < gy; y++ )
			{
				pos.y = (y * mod.cellsize.y) + half.y;

				for ( int x = 0; x < gx; x++ )
				{
					pos.x = (x * mod.cellsize.x) + half.x;

					contrib.Clear();
					float nearest = float.MaxValue;
					Vector3 neardelta = Vector3.zero;

					for ( int i = 0; i < mod.splines.Count; i++ )
					{
						MegaFlowSpline fs = mod.splines[i];

						if ( fs.include )
						{
							Vector3 wp = tm.MultiplyPoint3x4(pos);
							Vector3 np = fs.shape.FindNearestPointWorld(wp, 5, ref kn, ref tan, ref alpha);

							Vector3 delta = np - wp;

							float dist = delta.magnitude;
							float fdist = fs.distcrv.Evaluate(alpha) * fs.falloffdist;

							if ( dist < nearest )
							{
								nearest = dist;
								neardelta = delta;
							}

							if ( dist < fdist )
							{
								MegaFlowContrib con = new MegaFlowContrib();
								con.src = fs;
								con.dist = dist;
								con.vel = (tan - np).normalized * fs.velocity;
								con.delta = delta.normalized;
								con.alpha = alpha;
								con.fdist = fdist;
								contrib.Add(con);
							}
						}
					}

					if ( contrib.Count > 0 )
					{
						float tweight = 0.0f;
						for ( int c = 0; c < contrib.Count; c++ )
							tweight += contrib[c].src.weight;

						Vector3 vel = cells[(x * gz * gy) + (z * gy) + y];	//Vector3.zero;

						for ( int c = 0; c < contrib.Count; c++ )
						{
							float a = contrib[c].dist / contrib[c].fdist;
							float lerp = contrib[c].src.falloffcrv.Evaluate(a);

							float v = mod.velocity * contrib[c].src.velcrv.Evaluate(contrib[c].alpha);

							switch ( contrib[c].src.mode )
							{
								case MegaFlowMode.Attract:
									vel += Vector3.Lerp(contrib[c].delta, contrib[c].vel, lerp) * v * (contrib[c].src.weight / tweight);
									break;

								case MegaFlowMode.Repulse:
									vel += Vector3.Lerp(-contrib[c].delta, contrib[c].vel, lerp) * v * (contrib[c].src.weight / tweight);
									break;

								case MegaFlowMode.Flow:
									vel += Vector3.Lerp(Vector3.zero, contrib[c].vel, lerp) * v * (contrib[c].src.weight / tweight);
									break;
							}
						}

						cells[(x * gz * gy) + (z * gy) + y] = vel;
					}
					else
					{
						Vector3 vl = cells[(x * gz * gy) + (z * gy) + y];	//Vector3.zero;

						switch ( mod.emtyspacemode )
						{
							case MegaFlowMode.Attract:
								vl = (neardelta.normalized * mod.velocity) + mod.startval;
								break;

							case MegaFlowMode.Repulse:
								vl = (-neardelta.normalized * mod.velocity) + mod.startval;
								break;

							case MegaFlowMode.Flow:
								break;

						}

						cells[(x * gz * gy) + (z * gy) + y] = vl;
					}
				}
			}
		}
		EditorUtility.ClearProgressBar();

		for ( int i = 0; i < mod.modifiers.Count; i++ )
		{
			EditorUtility.DisplayProgressBar("Adding Modifiers", "Building", (float)i / (float)mod.modifiers.Count);

			MegaFlowModifier fmod = mod.modifiers[i];

			if ( fmod.include && fmod.obj )
			{
				Ray	ray = new Ray(Vector3.zero, Vector3.zero);

				for ( int z = 0; z < gz; z++ )
				{
					pos.z = (z * mod.cellsize.z) + half.z;

					for ( int y = 0; y < gy; y++ )
					{
						pos.y = (y * mod.cellsize.y) + half.y;

						for ( int x = 0; x < gx; x++ )
						{
							pos.x = (x * mod.cellsize.x) + half.x;

							Vector3 wpos = tm.MultiplyPoint3x4(pos);

							Vector3 origin = wpos;
							origin.y += 1000.0f;

							ray.origin = origin;
							ray.direction = Vector3.down;

							RaycastHit hit;

							if ( fmod.obj.Raycast(ray, out hit, 1000.0f) )
							{
								ray.direction = Vector3.up;
								origin.y -= 2000.0f;
								ray.origin = origin;

								if ( fmod.obj.Raycast(ray, out hit, 1000.0f) )
								{
									switch ( fmod.type )
									{
										case MegaFlowModType.VelChange:
											Vector3 vel = cells[(x * gz * gy) + (z * gy) + y];
											vel *= fmod.amount;
											cells[(x * gz * gy) + (z * gy) + y] = vel;
											break;
									}
								}
							}
						}
					}
				}
			}
		}
		EditorUtility.ClearProgressBar();

		if ( flow )
		{
			MegaFlowFrame newf = ScriptableObject.CreateInstance<MegaFlowFrame>();

			newf.gridDim2[0] = gx;
			newf.gridDim2[1] = gy;
			newf.gridDim2[2] = gz;

			newf.size = mod.size;
			newf.gsize = newf.size;

			newf.spacing.x = newf.size.x / newf.gridDim2[0];
			newf.spacing.y = newf.size.y / newf.gridDim2[1];
			newf.spacing.z = newf.size.z / newf.gridDim2[2];

			newf.oos.x = 1.0f / newf.spacing.x;
			newf.oos.y = 1.0f / newf.spacing.y;
			newf.oos.z = 1.0f / newf.spacing.z;

			newf.vel.AddRange(cells);
			flow.AddFrame(newf);
		}
	}
	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;
	}
	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 void RenderGizmo1(MegaFlow flow, GizmoType gizmoType)
	{
		if ( flow.shownotselected )
		{
			if ( flow.flow != null )
				DisplayFlow(flow, 0.0f, 0);

			flow.DrawGizmo();
		}
	}
	static void RenderGizmo(MegaFlow flow, GizmoType gizmoType)
	{
		if ( flow.flow != null )
			DisplayFlow(flow, 0.0f, 0);

		flow.DrawGizmo();
	}
	static void DisplayRibbons(MegaFlow mod)
	{
		for ( int i = 0; i < mod.ribbons.Count; i++ )
		{
			Ribbon ribbon = mod.ribbons[i];
			for ( int p = 0; p < ribbon.points.Count - 1; p++ )
			{
				Handles.color = ribbon.cols[p];
				DrawLine(ribbon.points[p], ribbon.points[p + 1]);
			}
		}
	}
	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;
	}