public PrimitiveParticleSystem(PrimitiveParticleSystemInfo psi) { for (int i = 0; i < MAX_PARTICLES; i++) { particles[i] = new ParticlePrimitive(); } info = psi; vecLocation.X=vecPrevLocation.X=0.0f; vecLocation.Y=vecPrevLocation.Y=0.0f; fTx=fTy=0; fScale = 1.0f; fEmissionResidue=0.0f; nParticlesAlive=0; fAge=-2.0f; }
public ParticlePrimitive(ParticlePrimitive o) { this.vecLocation = o.vecLocation; this.vecVelocity = o.vecVelocity; this.fGravity = o.fGravity; this.fRadialAccel = o.fRadialAccel; this.fTangentialAccel = o.fTangentialAccel; this.fSpin = o.fSpin; this.fSpinDelta = o.fSpinDelta; this.fSize = o.fSize; this.fSizeDelta = o.fSizeDelta; this.colColour = o.colColour; // + alpha this.colColourStart = o.colColourStart; this.colColourEnd = o.colColourEnd; this.fAge = o.fAge; this.fTerminalAge = o.fTerminalAge; }
public void Update(float fDeltaTime) { int i; float ang; ParticlePrimitive par = null; Vector2 vecAccel, vecAccel2; if(fAge >= 0) { fAge += fDeltaTime; if(fAge >= info.fLifetime) fAge = -2.0f; } // update all alive particles if (bUpdateBoundingBox) rectBoundingBox.Clear(); for(i=0; i<nParticlesAlive; i++) { par=particles[i]; par.fAge += fDeltaTime; //need to kill this particle if(par.fAge >= par.fTerminalAge) { nParticlesAlive--; particles[i] = new ParticlePrimitive (particles[nParticlesAlive]); i--; continue; } vecAccel = par.vecLocation-vecLocation; vecAccel.Normalise (); vecAccel2 = vecAccel; vecAccel *= par.fRadialAccel; // vecAccel2.Rotate(M_PI_2); // the following is faster ang = vecAccel2.X; vecAccel2.X = -vecAccel2.Y; vecAccel2.X = ang; vecAccel2 *= par.fTangentialAccel; par.vecVelocity += (vecAccel+vecAccel2)*fDeltaTime; par.vecVelocity.Y += par.fGravity*fDeltaTime; par.vecLocation += par.vecVelocity*fDeltaTime; par.fSpin += par.fSpinDelta*fDeltaTime; par.fSize += par.fSizeDelta*fDeltaTime; float factor = par.fAge / par.fTerminalAge; par.colColour = Rgba32.Lerp(par.colColourStart, par.colColourEnd, factor); //par.colColour = new Rgba32(par.colColour.ToVector4() + (par.colColourEnd.ToVector4() * fDeltaTime)); } if (bUpdateBoundingBox) rectBoundingBox.Encapsulate(par.vecLocation.X, par.vecLocation.Y); // generate new particles if(fAge != -2.0f) { float fParticlesNeeded = ((float)info.nEmission)*fDeltaTime + fEmissionResidue; int nParticlesCreated = (int) fParticlesNeeded; fEmissionResidue=fParticlesNeeded-((float)nParticlesCreated); for(i=0; i<nParticlesCreated; i++) { if(nParticlesAlive>=MAX_PARTICLES) break; par = particles[nParticlesAlive]; par.fAge = 0.0f; par.fTerminalAge = RandomGenerator.Default.GetRandomSingle(info.fParticleLifeMin, info.fParticleLifeMax); par.vecLocation = vecPrevLocation + (vecLocation - vecPrevLocation) * RandomGenerator.Default.GetRandomSingle(0.0f, 1.0f); par.vecLocation.X += RandomGenerator.Default.GetRandomSingle(-2.0f, 2.0f); par.vecLocation.Y += RandomGenerator.Default.GetRandomSingle(-2.0f, 2.0f); ang = info.fDirection - ((float)Math.PI / 2.0f) + RandomGenerator.Default.GetRandomSingle(0.0f, info.fSpread) - info.fSpread / 2.0f; if(info.bRelative) ang += ( (float) Math.Atan2( (vecPrevLocation-vecLocation).Y, (vecPrevLocation-vecLocation).X ) )+( (float)Math.PI / 2.0f ); par.vecVelocity.X = (float) Math.Cos(ang); par.vecVelocity.Y = (float) Math.Sin(ang); par.vecVelocity *= info.fSpeed; par.fGravity = info.fGravity; par.fRadialAccel = info.fRadialAccel; par.fTangentialAccel = info.fTangentialAccel; par.fSize = RandomGenerator.Default.GetRandomSingle(info.fSizeStart, info.fSizeStart + (info.fSizeEnd - info.fSizeStart) * info.fSizeVar); par.fSizeDelta = (info.fSizeEnd-par.fSize) / par.fTerminalAge; par.fSpin = RandomGenerator.Default.GetRandomSingle(info.fSpinStart, info.fSpinStart + (info.fSpinEnd - info.fSpinStart) * info.fSpinVar); par.fSpinDelta = (info.fSpinEnd-par.fSpin) / par.fTerminalAge; //Vector4 start = info.colColourStart.ToVector4(); //Vector4 finish = info.colColourEnd.ToVector4(); //Vector4 colColourV = new Vector4( // Euclid.RandomHelper.Random_Float(start.W, finish.W + (finish.W - start.W) * info.fColourEndVar), // Euclid.RandomHelper.Random_Float(start.X, start.X + (finish.X - start.X) * info.fColourStartVar), // Euclid.RandomHelper.Random_Float(start.Y, finish.Y + (finish.Y - start.Y) * info.fColourStartVar), // Euclid.RandomHelper.Random_Float(start.Z, finish.Z + (finish.Z - start.Z) * info.fColourStartVar) // ); //par.colColourStart = new Rgba32(colColourV); //Vector4 colColourDeltaV = new Vector4(); //colColourDeltaV.W = (finish.W - start.W) / par.fTerminalAge; //colColourDeltaV.X = (finish.X - start.X) / par.fTerminalAge; //colColourDeltaV.Y = (finish.Y - start.Y) / par.fTerminalAge; //colColourDeltaV.Z = (finish.Z - start.Z) / par.fTerminalAge; //par.colColourEnd = new Rgba32(colColourDeltaV); par.colColourStart = RandomGenerator.Default.GetRandomColourNearby(info.colColourStart, info.fColourStartVar); par.colColourEnd = RandomGenerator.Default.GetRandomColourNearby(info.colColourEnd, info.fColourEndVar); if (bUpdateBoundingBox) rectBoundingBox.Encapsulate(par.vecLocation.X, par.vecLocation.Y); nParticlesAlive++; } } vecPrevLocation=vecLocation; }