/// <summary>
/// Spawn new particles based on free quota and emitter requirements.
/// </summary>
/// <param name="timeElapsed"></param>
protected void TriggerEmitters(float timeElapsed)
{
// Add up requests for emission
requested.Capacity = emitterList.Count;
while (requested.Count < emitterList.Count)
{
requested.Add(0);
}
int totalRequested, emitterCount, emissionAllowed;
emitterCount = emitterList.Count;
emissionAllowed = freeParticles.Count;
totalRequested = 0;
ParticleEmitter emitter = null;
// Count up total requested emissions
for (int i = 0; i < emitterList.Count; ++i)
{
emitter = emitterList[i];
requested[i] = emitter.GetEmissionCount(timeElapsed);
totalRequested += requested[i];
}
// Check if the quota will be exceeded, if so reduce demand
if (totalRequested > emissionAllowed)
{
// Apportion down requested values to allotted values
float ratio = (float)emissionAllowed / (float)totalRequested;
for (int i = 0; i < emitterCount; ++i)
{
requested[i] = (int)(requested[i] * ratio);
}
}
// Emit
// For each emission, apply a subset of the motion for the frame
// this ensures an even distribution of particles when many are
// emitted in a single frame
for (int i = 0; i < emitterCount; ++i)
{
float timePoint = 0.0f;
float timeInc = timeElapsed / requested[i];
for (int j = 0; j < requested[i]; ++j)
{
// Create a new particle & init using emitter
Particle p = CreateParticle();
emitterList[i].InitParticle(p);
// if this particle system has a color, whack the particle's color
if (color != null)
{
p.Color.a = color.a;
p.Color.r = color.r;
p.Color.g = color.g;
p.Color.b = color.b;
}
if (!localSpace)
{
p.Position =
(parentNode.DerivedOrientation *
(parentNode.DerivedScale * p.Position)) +
parentNode.DerivedPosition;
p.Direction =
(parentNode.DerivedOrientation * p.Direction);
}
// apply partial frame motion to this particle
p.Position += (p.Direction * timePoint);
// apply particle initialization by the affectors
foreach (ParticleAffector affector in affectorList)
{
affector.InitParticle(ref p);
}
// Increment time fragment
timePoint += timeInc;
}
}
}