/// <summary> /// Should be called before <see cref="ApplyParticleUpdaters"/> to ensure dead particles are removed before they are updated /// </summary> /// <param name="dt">Delta time, elapsed time since the last call, in seconds</param> private unsafe void MoveAndDeleteParticles(float dt) { // Hardcoded life update if (pool.FieldExists(ParticleFields.RemainingLife) && pool.FieldExists(ParticleFields.RandomSeed)) { var lifeField = pool.GetField(ParticleFields.RemainingLife); var randField = pool.GetField(ParticleFields.RandomSeed); var lifeStep = particleLifetime.Y - particleLifetime.X; var particleEnumerator = pool.GetEnumerator(); while (particleEnumerator.MoveNext()) { var particle = particleEnumerator.Current; var randSeed = *(RandomSeed *)(particle[randField]); var life = (float *)particle[lifeField]; if (*life > 1) { *life = 1; } var startingLife = particleLifetime.X + lifeStep * randSeed.GetFloat(0); if (*life <= 0 || (*life -= (dt / startingLife)) <= 0) { particleEnumerator.RemoveCurrent(ref particle); } } } // Hardcoded position and velocity update if (pool.FieldExists(ParticleFields.Position) && pool.FieldExists(ParticleFields.Velocity)) { // should this be a separate module? // Position and velocity update only var posField = pool.GetField(ParticleFields.Position); var velField = pool.GetField(ParticleFields.Velocity); foreach (var particle in pool) { var pos = ((Vector3 *)particle[posField]); var vel = ((Vector3 *)particle[velField]); *pos += *vel * dt; } } }
/// <summary> /// Should be called before <see cref="ApplyParticleUpdaters"/> to ensure dead particles are removed before they are updated /// </summary> /// <param name="dt">Delta time, elapsed time since the last call, in seconds</param> private unsafe void MoveAndDeleteParticles(float dt) { // Hardcoded life update if (pool.FieldExists(ParticleFields.RemainingLife) && pool.FieldExists(ParticleFields.RandomSeed)) { var lifeField = pool.GetField(ParticleFields.RemainingLife); var randField = pool.GetField(ParticleFields.RandomSeed); var lifeStep = particleLifetime.Y - particleLifetime.X; var particleEnumerator = pool.GetEnumerator(); while (particleEnumerator.MoveNext()) { var particle = particleEnumerator.Current; var randSeed = *(RandomSeed *)(particle[randField]); var life = (float *)particle[lifeField]; if (*life > 1) { *life = 1; } var startingLife = particleLifetime.X + lifeStep * randSeed.GetFloat(0); if (*life <= MathUtil.ZeroTolerance) { particleEnumerator.RemoveCurrent(ref particle); } else if ((*life -= (dt / startingLife)) <= MathUtil.ZeroTolerance) { if (DelayParticleDeath > 0) { *life = MathUtil.ZeroTolerance; } else { particleEnumerator.RemoveCurrent(ref particle); } } } } // Hardcoded position and old position updates // If we have to preserve the particle's old position, do it before updating the position for the first time if (pool.FieldExists(ParticleFields.Position) && pool.FieldExists(ParticleFields.OldPosition)) { var posField = pool.GetField(ParticleFields.Position); var oldField = pool.GetField(ParticleFields.OldPosition); foreach (var particle in pool) { (*((Vector3 *)particle[oldField])) = (*((Vector3 *)particle[posField])); } } // Hardcoded position and velocity update if (pool.FieldExists(ParticleFields.Position) && pool.FieldExists(ParticleFields.Velocity)) { var posField = pool.GetField(ParticleFields.Position); var velField = pool.GetField(ParticleFields.Velocity); foreach (var particle in pool) { var pos = ((Vector3 *)particle[posField]); var vel = ((Vector3 *)particle[velField]); *pos += *vel * dt; } } }