コード例 #1
0
    void Update()
    {
        if (Input.GetMouseButton(0))
        {
            smokepos    = transform.position;
            smokepos.z += Input.GetAxis("Mouse X") * xspeed * 0.02f;
            smokepos.y += Input.GetAxis("Mouse Y") * yspeed * 0.02f;
        }

        if (source && source.frames.Count > 0 && emitobjects.Count > 0)
        {
            source.Prepare();

            t += Time.deltaTime;

            if (t > flowrate)
            {
                t -= flowrate;

                for (int i = 0; i < count; i++)
                {
                    GameObject go = Pop();
                    if (go)
                    {
                        MegaFlowEffect      ef  = go.GetComponent <MegaFlowEffect>();
                        MegaFlowSmokeObjDef def = emitobjects[ef.emitindex];

                        float z = (Random.value - 0.5f) * width * 2.0f;
                        float y = (Random.value - 0.5f) * height * 2.0f;
                        float x = (Random.value - 0.5f) * 0.95f;

                        Vector3 pos = Vector3.zero;
                        pos.z = z;
                        pos.y = y;
                        pos.x = x;
                        pos  += offset;

                        Vector3 scl = Vector3.one;

                        scl.x = Random.Range(def.scalelow.x, def.scalehigh.x);                          //Random.value + 0.4f) * 2.0f;
                        scl.y = Random.Range(def.scalelow.y, def.scalehigh.y);                          //Random.value + 0.4f) * 2.0f;
                        scl.z = Random.Range(def.scalelow.z, def.scalehigh.z);                          //Random.value + 0.4f) * 2.0f;
                        //scl.y = (Random.value + 0.4f) * 2.0f;
                        //scl.z = (Random.value + 0.4f) * 2.0f;

                        Vector3 rotspeed = Vector3.zero;
                        rotspeed.x = Random.Range(def.rotspeedlow.x, def.rotspeedhigh.x);
                        rotspeed.y = Random.Range(def.rotspeedlow.y, def.rotspeedhigh.y);
                        rotspeed.z = Random.Range(def.rotspeedlow.z, def.rotspeedhigh.z);

                        Vector3 srot = Vector3.zero;
                        srot.x = Random.Range(def.rotlow.x, def.rothigh.x);
                        srot.y = Random.Range(def.rotlow.y, def.rothigh.y);
                        srot.z = Random.Range(def.rotlow.z, def.rothigh.z);
                        Quaternion rot = Quaternion.Euler(srot);                                //Random.rotation;

                        go.transform.position   = transform.localToWorldMatrix.MultiplyPoint3x4(pos);
                        go.transform.localScale = scl;

                        ef.vel      = transform.right * vel.x;
                        ef.mass     = mass;
                        ef.Gravity  = Gravity;
                        ef.scale    = scale;
                        ef.framenum = framenum;

                        ef.rot      = rot.eulerAngles;
                        ef.rotspeed = rotspeed;                         //Random.insideUnitSphere * 180.0f;

                        Renderer rend = go.GetComponent <Renderer>();

                        if (cols.Count > 0)
                        {
                            if (colindex >= cols.Count)
                            {
                                colindex = 0;
                            }
                            //Renderer rend = go.GetComponent<Renderer>();

                            if (rend && rend.sharedMaterial)
                            {
                                rend.sharedMaterial.color = cols[colindex] * 0.5f;
                            }

                            colindex++;
                        }

                        rend.enabled = false;

                        MegaFlowSmokeObj sobj = new MegaFlowSmokeObj();
                        sobj.obj      = go;
                        sobj.lifetime = lifetime;

                        objects.Add(sobj);
                    }
                }
            }
        }

        for (int i = 0; i < objects.Count; i++)
        {
            objects[i].lifetime -= Time.deltaTime;
            if (objects[i].lifetime < 0.0f)
            {
                GameObject sobj = objects[i].obj;

                Push(sobj);
                objects.RemoveAt(i);
                i--;
            }
        }
    }
コード例 #2
0
	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;
	}
コード例 #3
0
    void Update()
    {
        if (source && particle && source.frames.Count > 0)
        {
            framenum = Mathf.Clamp(framenum, 0, source.frames.Count - 1);
            frame    = source.frames[framenum];

            framenum1 = Mathf.Clamp(framenum1, 0, source.frames.Count - 1);
            frame1    = source.frames[framenum1];

            source.Prepare();
            tdt = Time.deltaTime;

            //Matrix4x4 offtm = Matrix4x4.TRS(frame.size * 0.5f, Quaternion.identity, Vector3.one);
            Matrix4x4 offtm = Matrix4x4.TRS((frame.size * 0.5f) + frame.offset, Quaternion.identity, Vector3.one);

            tm    = offtm * source.transform.worldToLocalMatrix;
            invtm = tm.inverse;

            offtm = Matrix4x4.TRS((frame1.size * 0.5f) + frame1.offset, Quaternion.identity, Vector3.one);

            tm1    = offtm * source.transform.worldToLocalMatrix;
            invtm1 = tm1.inverse;

            float p  = source.Density;
            float A  = area;
            float Re = source.Reynolds;
            oomass = 1.0f / mass;

            coef = 1.0f * p * A * Mathf.Pow(Re, -0.5f);

            t    += Time.deltaTime;
            usedt = dt;
            if (usedt > tdt)
            {
                usedt = tdt;
            }

            int count = particle.particleCount;
            particles = particle.particles;

            if (!UseThreading || Cores < 1 || !Application.isPlaying)
            {
                RunSim(0, count);
            }
            else
            {
                if (Cores == 0)
                {
                    Cores = SystemInfo.processorCount - 1;
                }

                if (tasks == null)
                {
                    MakeThreads();
                }

                int step = count / (Cores + 1);

                if (Cores > 0)
                {
                    int index = step;
                    for (int i = 0; i < tasks.Length; i++)
                    {
                        tasks[i].start = index;
                        tasks[i].end   = index + step;
                        index         += step;
                    }

                    tasks[Cores - 1].end = count;

                    for (int i = 0; i < tasks.Length; i++)
                    {
                        tasks[i].pauseevent.Set();
                    }
                }

                RunSim(0, step);
                WaitJobs();
            }

            particle.particles = particles;
        }
    }
コード例 #4
0
	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;
	}