// Copyright (c) Craftwork Games. All rights reserved. // Licensed under the MIT license. // See LICENSE file in the project root for full license information. using System; using Microsoft.Xna.Framework; using MonoGame.Extended.Particles.Data; namespace MonoGame.Extended.Particles.Modifiers; /// /// A modifier that changes particle colors based on their velocity. /// /// /// The adjusts particle colors dynamically according to their /// movement speed. Particles can transition smoothly between two defined colors: /// /// A color for stationary or slow-moving particles () /// A color for fast-moving particles () /// /// /// The color values are represented in HSL (Hue, Saturation, Lightness) format as a Vector3. /// public class VelocityColorModifier : Modifier { /// /// Gets or sets the color for particles that are stationary or moving slowly. /// /// /// This color is applied to particles with zero velocity and serves as the starting /// point for color interpolation. The Vector3 components represent HSL values /// (Hue, Saturation, Lightness). /// public Vector3 StationaryColor; /// /// Gets or sets the color for particles that have reached or exceeded the velocity threshold. /// /// /// This color is applied to fast-moving particles and serves as the end point /// for color interpolation. The Vector3 components represent HSL values /// (Hue, Saturation, Lightness). /// public Vector3 VelocityColor; /// /// Gets or sets the velocity magnitude at which particles fully transition to the velocity color. /// /// /// This value defines the speed threshold that determines when a particle should /// display the full . Particles moving slower than this /// threshold will display a color interpolated between and /// based on their speed relative to this threshold. /// public float VelocityThreshold; /// /// Updates all particles by changing their colors based on their current velocity. /// /// public override unsafe void Update(float elapsedSeconds, ParticleIterator iterator) { if (!Enabled) { return; } float velocityThreshold2 = VelocityThreshold * VelocityThreshold; while (iterator.HasNext) { Particle* particle = iterator.Next(); float velocitySquared = particle->Velocity[0] * particle->Velocity[0] + particle->Velocity[1] * particle->Velocity[1]; if (velocitySquared >= velocityThreshold2) { particle->Color[0] = VelocityColor.X; particle->Color[1] = VelocityColor.Y; particle->Color[2] = VelocityColor.Z; } else { Vector3 deltaColor = VelocityColor - StationaryColor; float t = MathF.Sqrt(velocitySquared) / VelocityThreshold; float h = deltaColor.X * t + StationaryColor.X; float s = deltaColor.Y * t + StationaryColor.Y; float l = deltaColor.Z * t + StationaryColor.Z; particle->Color[0] = h; particle->Color[1] = s; particle->Color[2] = l; } } } }