Dynamics/ColorDynamics.cs
using System;
using Sandbox;
namespace Andicraft.SecondOrderDynamics;
/// <summary>
/// Helper class that lets you run dynamics on a Color.
/// </summary>
public class ColorDynamics
{
private FloatDynamics _h;
private Vector2Dynamics _sv;
private FloatDynamics _alpha;
private Vector3 _currentHsv;
private Color _currentColor;
public Color CurrentValue => _currentColor;
public float CurrentAlpha => _currentColor.a;
public ColorDynamics(float frequency, float damping, float response, Color startingValue)
{
_currentHsv = startingValue.ToOkHsv();
_h = new(frequency, damping, response, _currentHsv.x)
{
MinWrapValue = 0f,
MaxWrapValue = 1f
};
_sv = new Vector2Dynamics(frequency, damping, response, new Vector2(_currentHsv.z, _currentHsv.y));
_alpha = new FloatDynamics(frequency, damping, response, startingValue.a);
}
public void SetFrequency(float f)
{
_h.SetFrequency(f);
_sv.SetFrequency(f);
_alpha.SetFrequency(f);
}
public void SetDamping(float d)
{
_h.SetDamping(d);
_sv.SetDamping(d);
_alpha.SetDamping(d);
}
public void SetResponse(float r)
{
_h.SetResponse(r);
_sv.SetResponse(r);
_alpha.SetResponse(r);
}
public void Reset(Color value)
{
var targetColor = value.ToOkHsv();
_currentColor = value;
_currentHsv = targetColor;
_h.Reset(_currentHsv.x);
_sv.Reset(new Vector2(_currentHsv.y, _currentHsv.z));
_alpha.Reset(value.a);
}
public Color Update(float deltaTime, Color target, bool setVelocity = false, Vector4 velocity = default)
{
var targetHsv = target.ToOkHsv();
var h = _h.Update(deltaTime, targetHsv.x, setVelocity, velocity.x);
var sv = _sv.Update(deltaTime, new Vector2(targetHsv.y, targetHsv.z), setVelocity,
new Vector2(velocity.y, velocity.z));
var a = _alpha.Update(deltaTime, target.a, setVelocity, velocity.w);
_currentHsv = new Vector3(h, sv.x.Saturate(), sv.y.Saturate());
var col = OkColor.OkHsvToColor(_currentHsv);
col.a = a.Saturate();
_currentColor = col;
return _currentColor;
}
}