// 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 System.Collections.Generic;
using MonoGame.Extended.Particles.Data;
using MonoGame.Extended.Particles.Modifiers.Interpolators;
namespace MonoGame.Extended.Particles.Modifiers;
///
/// A modifier that applies interpolators to particles based on their velocity magnitude.
///
///
/// The controls how particle properties change based on their speed
/// by applying a collection of objects to each particle. The intensity
/// of the effect is determined by comparing the particle's velocity magnitude to a threshold value.
///
public class VelocityModifier : Modifier
{
///
/// Gets or sets the collection of interpolators that will be applied to particles.
///
public List Interpolators { get; set; } = new List();
///
/// Gets or sets the velocity magnitude at which particles reach the maximum interpolation effect.
///
///
/// This value defines the speed threshold that determines when a particle should
/// receive the full interpolation effect (amount = 1.0). Particles moving slower than this
/// threshold will receive a proportionally reduced effect based on their velocity magnitude.
///
public float VelocityThreshold;
///
/// Updates all particles by applying interpolators with an amount based on each particle's velocity.
///
///
protected internal override unsafe void Update(float elapsedSeconds, ParticleIterator iterator, int particleCount)
{
if (!Enabled) { return; }
float velocityThreshold2 = VelocityThreshold * VelocityThreshold;
for (int i = 0; i < particleCount && iterator.HasNext; i++)
{
Particle* particle = iterator.Next();
float velocitySquared = particle->Velocity[0] * particle->Velocity[0] +
particle->Velocity[1] * particle->Velocity[1];
if (velocitySquared >= velocityThreshold2)
{
for (int j = 0; j < Interpolators.Count; j++)
{
Interpolator interpolator = Interpolators[j];
interpolator.Update(1, particle);
}
}
else
{
float t = (float)Math.Sqrt(velocitySquared) / VelocityThreshold;
for (int j = 0; j < Interpolators.Count; j++)
{
Interpolator interpolator = Interpolators[j];
interpolator.Update(t, particle);
}
}
}
}
}