How To: Clamp a Particle Parameter |
This topic shows how you can limit particle parameter values at runtime, e.g. to limit the alpha value of particles.
This topic contains the following sections:
You can use a custom ParticleEffector to change particle parameters. See How To: Create a Particle Effector.
Here is a code snippet of a particle effector that clamps a value between a min and max value:
using System; using DigitalRune.Mathematics; using DigitalRune.Particles; namespace Samples.Particles { public class ClampValueEffector<T> : ParticleEffector where T : IComparable<T> { private IParticleParameter<T> _parameter; [ParticleParameter(ParticleParameterUsage.InOut)] public string Parameter { get; set; } public T Min { get; set; } public T Max { get; set; } protected override ParticleEffector CreateInstanceCore() { return new ClampValueEffector<T>(); } protected override void CloneCore(ParticleEffector source) { base.CloneCore(source); var sourceTyped = (ClampValueEffector<T>)source; Parameter = sourceTyped.Parameter; } protected override void OnRequeryParameters() { _parameter = ParticleSystem.Parameters.Get<T>(Parameter); } protected override void OnUninitialize() { _parameter = null; } protected override void OnBeginUpdate(TimeSpan deltaTime) { if (_parameter == null) return; T[] values = _parameter.Values; if (values == null) { // Value is a uniform parameter. _parameter.DefaultValue = MathHelper.Clamp(_parameter.DefaultValue, Min, Max); } } protected override void OnUpdateParticles(TimeSpan deltaTime, int startIndex, int count) { if (_parameter == null) return; T[] values = _parameter.Values; if (values == null) { // Value is a uniform parameter. Uniform parameters are handled in OnBeginUpdate(). return; } // Value is a varying parameter. for (int i = startIndex; i < startIndex + count; i++) values[i] = MathHelper.Clamp(values[i], Min, Max); } } }
You need to add the new ClampValueEffecto to the particle system, for example:
_particleSystem.Effectors.Add(new ClampValueEffector<float> { Parameter = ParticleParameterNames.Alpha, Min = 0.2f, Max = 0.8f, });
Alternatively, you can use the FuncEffectorT, TResult:
particleSystem.Effectors.Add(new FuncEffector<float, float> { InputParameter = "Alpha", OutputParameter = "Alpha", Func = x => MathHelper.Clamp(x, 0.2f, 0.8f), });