internal void InternalProcess(float deltaTime, EffectInstance instance, Particle[] particles, int begin, int end) { Process(deltaTime, instance, particles, begin, end); }
internal void Update(float deltaTime) { int oldCapacity = m_particles != null ? m_particles.Length : 0; if (oldCapacity != Effect.Capacity || m_oldAlignment != Effect.Alignment) { m_particles = Effect.Capacity != 0 ? new Particle[Effect.Capacity] : null; m_particleLocalFrames = Effect.Capacity != 0 && Effect.Alignment == Alignment.Local ? new LocalFrame[Effect.Capacity] : null; m_liveParticleStart = 0; m_liveParticleEnd = 0; m_newParticleEnd = 0; m_oldAlignment = Effect.Alignment; } if (m_oldEmissionRate != Effect.EmissionRate) { m_emissionReminder = 0; m_oldEmissionRate = Effect.EmissionRate; } Debug.Assert(m_newParticleEnd == m_liveParticleEnd, "New particles have been emitted without a call to EndEmit()."); // update current particles int writePos = m_liveParticleEnd; for (int i = m_liveParticleStart; i != m_liveParticleEnd; i = IncrementIndex(i)) { Particle p = m_particles[i]; p.m_age += deltaTime; if (p.m_age < p.m_life) { p.m_position += p.m_velocity * deltaTime; m_particles[writePos] = p; if (m_particleLocalFrames != null) m_particleLocalFrames[writePos] = m_particleLocalFrames[i]; writePos = IncrementIndex(writePos); } } m_liveParticleStart = m_liveParticleEnd; m_newParticleEnd = m_liveParticleEnd = writePos; BatchProcess((particles, begin, end) => { foreach (var mod in Effect.ModifiersOnUpdate) { mod.InternalProcess(deltaTime, this, particles, begin, end); } }); m_templateParticle = new Particle { m_life = Effect.DefaultParticleLifetime, m_age = 0f, m_position = Effect.DefaultParticlePosition, m_velocity = Effect.DefaultParticleVelocity, m_size = Effect.DefaultParticleSize, m_rotation = Effect.DefaultParticleRotation, m_color = Color.FromXnaColor(Effect.DefaultParticleColor) }; if (IsEmitting) { // emit new particles m_emissionReminder += deltaTime; float interval = 1.0f / Effect.EmissionRate; while (m_emissionReminder > interval) { Emit(Template); m_emissionReminder -= interval; } EndEmit(); } }
protected virtual void Process(float deltaTime, EffectInstance instance, Particle[] particles, int begin, int end) { }
public void Emit(Particle particle) { Debug.Assert(IncrementIndex(m_newParticleEnd) != m_liveParticleStart, "Particle array overflow."); m_particles[m_newParticleEnd] = particle; if (Effect.Alignment == Alignment.Local) { if (SystemInstance.LocalFrameProvider != null) { m_particleLocalFrames[m_newParticleEnd] = SystemInstance.LocalFrameProvider.LocalFrame; } else { m_particleLocalFrames[m_newParticleEnd].Col0 = Vector4.UnitX; m_particleLocalFrames[m_newParticleEnd].Col1 = Vector4.UnitY; m_particleLocalFrames[m_newParticleEnd].Col2 = Vector4.UnitZ; m_particleLocalFrames[m_newParticleEnd].Col3 = Vector4.UnitW; } } m_newParticleEnd = IncrementIndex(m_newParticleEnd); }