Development Merge 2025.10.18 #4
@@ -37,39 +37,9 @@ public readonly struct ColorHSV(float hue, float saturation, float value)
 | 
				
			|||||||
    public static bool operator ==(ColorHSV left, ColorHSV right) => left.Hue == right.Hue && left.Saturation == right.Saturation && left.Value == right.Value;
 | 
					    public static bool operator ==(ColorHSV left, ColorHSV right) => left.Hue == right.Hue && left.Saturation == right.Saturation && left.Value == right.Value;
 | 
				
			||||||
    public static bool operator !=(ColorHSV left, ColorHSV right) => left.Hue != right.Hue || left.Saturation != right.Saturation || left.Value != right.Value;
 | 
					    public static bool operator !=(ColorHSV left, ColorHSV right) => left.Hue != right.Hue || left.Saturation != right.Saturation || left.Value != right.Value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static implicit operator ColorHSV(ColorRGBA rgba) => (ColorRGB)rgba;
 | 
					    public static implicit operator ColorHSV(ColorHSVA hsva) => new(hsva.Hue, hsva.Saturation, hsva.Value);
 | 
				
			||||||
    public static implicit operator ColorHSV(ColorRGB rgb)
 | 
					    public static implicit operator ColorHSV(ColorRGBA rgba) => (ColorHSVA)rgba;
 | 
				
			||||||
    {
 | 
					    public static implicit operator ColorHSV(ColorRGB rgb) => (ColorHSVA)rgb;
 | 
				
			||||||
        float hue;
 | 
					 | 
				
			||||||
        float saturation;
 | 
					 | 
				
			||||||
        float value;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        float rd = rgb.R / 255f;
 | 
					 | 
				
			||||||
        float gd = rgb.G / 255f;
 | 
					 | 
				
			||||||
        float bd = rgb.B / 255f;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        float max = Math.Max(rd, Math.Max(gd, bd));
 | 
					 | 
				
			||||||
        float min = Math.Min(rd, Math.Min(gd, bd));
 | 
					 | 
				
			||||||
        float delta = max - min;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (delta.ApproximatelyEquals(0))
 | 
					 | 
				
			||||||
            hue = 0f;
 | 
					 | 
				
			||||||
        else if (max.ApproximatelyEquals(rd))
 | 
					 | 
				
			||||||
            hue = 60f * ((gd - bd) / delta % 6f);
 | 
					 | 
				
			||||||
        else if (max.ApproximatelyEquals(gd))
 | 
					 | 
				
			||||||
            hue = 60f * (((bd - rd) / delta) + 2f);
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
            hue = 60f * (((rd - gd) / delta) + 4f);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (hue < 0f)
 | 
					 | 
				
			||||||
            hue += 360f;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        hue /= 360f;
 | 
					 | 
				
			||||||
        saturation = max.ApproximatelyEquals(0f) ? 0f : delta / max;
 | 
					 | 
				
			||||||
        value = max;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return new(hue, saturation, value);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// <summary>
 | 
					    /// <summary>
 | 
				
			||||||
    /// Inverts the given <see cref="ColorHSV"/>.
 | 
					    /// Inverts the given <see cref="ColorHSV"/>.
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										189
									
								
								Engine.Core/Primitives/ColorHSVA.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										189
									
								
								Engine.Core/Primitives/ColorHSVA.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,189 @@
 | 
				
			|||||||
 | 
					namespace Syntriax.Engine.Core;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// Represents an HSV color.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					/// <param name="hue">Hue of the <see cref="ColorHSVA"/>.</param>
 | 
				
			||||||
 | 
					/// <param name="saturation">Saturation of the <see cref="ColorHSVA"/>.</param>
 | 
				
			||||||
 | 
					/// <param name="value">Value of the <see cref="ColorHSVA"/>.</param>
 | 
				
			||||||
 | 
					/// <param name="alpha">Alpha of the <see cref="ColorHSVA"/>.</param>
 | 
				
			||||||
 | 
					/// <remarks>
 | 
				
			||||||
 | 
					/// Initializes a new instance of the <see cref="ColorHSVA"/> struct with the specified values.
 | 
				
			||||||
 | 
					/// </remarks>
 | 
				
			||||||
 | 
					[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")]
 | 
				
			||||||
 | 
					public readonly struct ColorHSVA(float hue, float saturation, float value, float alpha = 1)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The Hue value of the <see cref="ColorHSVA"/>.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public readonly float Hue = hue.Clamp(0f, 1f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The Saturation value of the <see cref="ColorHSVA"/>.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public readonly float Saturation = saturation.Clamp(0f, 1f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The Value value of the <see cref="ColorHSVA"/>.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public readonly float Value = value.Clamp(0f, 1f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The Alpha value of the <see cref="ColorHSVA"/>.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public readonly float Alpha = alpha;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static ColorHSVA operator -(ColorHSVA color) => new(color.Hue.OneMinus(), color.Saturation.OneMinus(), color.Value.OneMinus(), color.Alpha);
 | 
				
			||||||
 | 
					    public static ColorHSVA operator +(ColorHSVA left, ColorHSVA right) => new(left.Hue + right.Hue, left.Saturation + right.Saturation, left.Value + right.Value, left.Alpha + right.Alpha);
 | 
				
			||||||
 | 
					    public static ColorHSVA operator -(ColorHSVA left, ColorHSVA right) => new(left.Hue - right.Hue, left.Saturation - right.Saturation, left.Value - right.Value, left.Alpha - right.Alpha);
 | 
				
			||||||
 | 
					    public static ColorHSVA operator *(ColorHSVA left, ColorHSVA right) => new(left.Hue * right.Hue, left.Saturation * right.Saturation, left.Value * right.Value, left.Alpha * right.Alpha);
 | 
				
			||||||
 | 
					    public static ColorHSVA operator *(ColorHSVA color, float value) => new(color.Hue * value, color.Saturation * value, color.Value * value, color.Alpha * value);
 | 
				
			||||||
 | 
					    public static ColorHSVA operator *(float value, ColorHSVA color) => new(color.Hue * value, color.Saturation * value, color.Value * value, color.Alpha * value);
 | 
				
			||||||
 | 
					    public static ColorHSVA operator /(ColorHSVA color, float value) => new(color.Hue / value, color.Saturation / value, color.Value / value, color.Alpha / value);
 | 
				
			||||||
 | 
					    public static bool operator ==(ColorHSVA left, ColorHSVA right) => left.Hue == right.Hue && left.Saturation == right.Saturation && left.Value == right.Value;
 | 
				
			||||||
 | 
					    public static bool operator !=(ColorHSVA left, ColorHSVA right) => left.Hue != right.Hue || left.Saturation != right.Saturation || left.Value != right.Value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static implicit operator ColorHSVA(ColorHSV hsv) => new(hsv.Hue, hsv.Saturation, hsv.Value, 1f);
 | 
				
			||||||
 | 
					    public static implicit operator ColorHSVA(ColorRGB rgb) => (ColorRGBA)rgb;
 | 
				
			||||||
 | 
					    public static implicit operator ColorHSVA(ColorRGBA rgba)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        float hue;
 | 
				
			||||||
 | 
					        float saturation;
 | 
				
			||||||
 | 
					        float value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        float rd = rgba.R / 255f;
 | 
				
			||||||
 | 
					        float gd = rgba.G / 255f;
 | 
				
			||||||
 | 
					        float bd = rgba.B / 255f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        float max = Math.Max(rd, Math.Max(gd, bd));
 | 
				
			||||||
 | 
					        float min = Math.Min(rd, Math.Min(gd, bd));
 | 
				
			||||||
 | 
					        float delta = max - min;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (delta.ApproximatelyEquals(0))
 | 
				
			||||||
 | 
					            hue = 0f;
 | 
				
			||||||
 | 
					        else if (max.ApproximatelyEquals(rd))
 | 
				
			||||||
 | 
					            hue = 60f * ((gd - bd) / delta % 6f);
 | 
				
			||||||
 | 
					        else if (max.ApproximatelyEquals(gd))
 | 
				
			||||||
 | 
					            hue = 60f * (((bd - rd) / delta) + 2f);
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            hue = 60f * (((rd - gd) / delta) + 4f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (hue < 0f)
 | 
				
			||||||
 | 
					            hue += 360f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        hue /= 360f;
 | 
				
			||||||
 | 
					        saturation = max.ApproximatelyEquals(0f) ? 0f : delta / max;
 | 
				
			||||||
 | 
					        value = max;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return new(hue, saturation, value, rgba.A / 255f);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Inverts the given <see cref="ColorHSVA"/>.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    /// <param name="color">The <see cref="ColorHSVA"/>.</param>
 | 
				
			||||||
 | 
					    /// <returns>The inverted <see cref="ColorHSVA"/>.</returns>
 | 
				
			||||||
 | 
					    public static ColorHSVA Invert(ColorHSVA color) => -color;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Adds two <see cref="ColorHSVA"/>s.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    /// <param name="left">The first <see cref="ColorHSVA"/>.</param>
 | 
				
			||||||
 | 
					    /// <param name="right">The second <see cref="ColorHSVA"/>.</param>
 | 
				
			||||||
 | 
					    /// <returns>The sum of the two <see cref="ColorHSVA"/>s.</returns>
 | 
				
			||||||
 | 
					    public static ColorHSVA Add(ColorHSVA left, ColorHSVA right) => left + right;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Subtracts one <see cref="ColorHSVA"/> from another.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    /// <param name="left">The <see cref="ColorHSVA"/> to subtract from.</param>
 | 
				
			||||||
 | 
					    /// <param name="right">The <see cref="ColorHSVA"/> to subtract.</param>
 | 
				
			||||||
 | 
					    /// <returns>The result of subtracting the second <see cref="ColorHSVA"/> from the first.</returns>
 | 
				
			||||||
 | 
					    public static ColorHSVA Subtract(ColorHSVA left, ColorHSVA right) => left - right;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Multiplies a <see cref="ColorHSVA"/> by a scalar value.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    /// <param name="color">The <see cref="ColorHSVA"/>.</param>
 | 
				
			||||||
 | 
					    /// <param name="value">The scalar value.</param>
 | 
				
			||||||
 | 
					    /// <returns>The result of multiplying the <see cref="ColorHSVA"/> by the scalar value.</returns>
 | 
				
			||||||
 | 
					    public static ColorHSVA Multiply(ColorHSVA color, float value) => color * value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Divides a <see cref="ColorHSVA"/> by a scalar value.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    /// <param name="color">The <see cref="ColorHSVA"/>.</param>
 | 
				
			||||||
 | 
					    /// <param name="value">The scalar value.</param>
 | 
				
			||||||
 | 
					    /// <returns>The result of dividing the <see cref="ColorHSVA"/> by the scalar value.</returns>
 | 
				
			||||||
 | 
					    public static ColorHSVA Divide(ColorHSVA color, float value) => color / value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Performs linear interpolation between two <see cref="ColorHSVA"/>s.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    /// <param name="from">The starting <see cref="ColorHSVA"/> (t = 0).</param>
 | 
				
			||||||
 | 
					    /// <param name="to">The ending <see cref="ColorHSVA"/> (t = 1).</param>
 | 
				
			||||||
 | 
					    /// <param name="t">The interpolation parameter.</param>
 | 
				
			||||||
 | 
					    /// <returns>The interpolated <see cref="ColorHSVA"/>.</returns>
 | 
				
			||||||
 | 
					    public static ColorHSVA Lerp(ColorHSVA from, ColorHSVA to, float t)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        float hueDiff = to.Hue - from.Hue;
 | 
				
			||||||
 | 
					        float saturationDiff = to.Saturation - from.Saturation;
 | 
				
			||||||
 | 
					        float valueDiff = to.Value - from.Value;
 | 
				
			||||||
 | 
					        float alphaDiff = to.Alpha - from.Alpha;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return from + new ColorHSVA(hueDiff * t, saturationDiff * t, valueDiff * t, alphaDiff * t);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Checks if two <see cref="ColorHSVA"/>s are approximately equal within a specified epsilon range.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    /// <param name="left">The first <see cref="ColorHSVA"/>.</param>
 | 
				
			||||||
 | 
					    /// <param name="right">The second <see cref="ColorHSVA"/>.</param>
 | 
				
			||||||
 | 
					    /// <param name="epsilon">The epsilon range.</param>
 | 
				
			||||||
 | 
					    /// <returns><see cref="true"/> if the <see cref="ColorHSVA"/>s are approximately equal; otherwise, <see cref="false"/>.</returns>
 | 
				
			||||||
 | 
					    public static bool ApproximatelyEquals(ColorHSVA left, ColorHSVA right, float epsilon = float.Epsilon)
 | 
				
			||||||
 | 
					        => left.Hue.ApproximatelyEquals(right.Hue, epsilon) && left.Saturation.ApproximatelyEquals(right.Saturation, epsilon) && left.Value.ApproximatelyEquals(right.Value, epsilon);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Determines whether the specified object is equal to the current <see cref="ColorHSVA"/>.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    /// <param name="obj">The object to compare with the current <see cref="ColorHSVA"/>.</param>
 | 
				
			||||||
 | 
					    /// <returns><see cref="true"/> if the specified object is equal to the current <see cref="ColorHSVA"/>; otherwise, <see cref="false"/>.</returns>
 | 
				
			||||||
 | 
					    public override bool Equals(object? obj) => obj is ColorHSVA colorHSVA && this == colorHSVA;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Generates a hash code for the <see cref="ColorHSVA"/>.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    /// <returns>A hash code for the <see cref="ColorHSVA"/>.</returns>
 | 
				
			||||||
 | 
					    public override int GetHashCode() => System.HashCode.Combine(Hue, Saturation, Value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Converts the <see cref="ColorHSVA"/> to its string representation.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    /// <returns>A string representation of the <see cref="ColorHSVA"/>.</returns>
 | 
				
			||||||
 | 
					    public override string ToString() => $"{nameof(ColorHSVA)}({Hue}, {Saturation}, {Value})";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// Provides extension methods for <see cref="ColorHSVA"/> type.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public static class ColorHSVAExtensions
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <inheritdoc cref="ColorHSVA.Add(ColorHSVA, ColorHSVA)" />
 | 
				
			||||||
 | 
					    public static ColorHSVA Add(this ColorHSVA color, ColorHSVA value) => ColorHSVA.Add(color, value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <inheritdoc cref="ColorHSVA.Subtract(ColorHSVA, ColorHSVA)" />
 | 
				
			||||||
 | 
					    public static ColorHSVA Subtract(this ColorHSVA color, ColorHSVA value) => ColorHSVA.Subtract(color, value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <inheritdoc cref="ColorHSVA.Multiply(ColorHSVA, ColorHSVA)" />
 | 
				
			||||||
 | 
					    public static ColorHSVA Multiply(this ColorHSVA color, float value) => ColorHSVA.Multiply(color, value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <inheritdoc cref="ColorHSVA.Divide(ColorHSVA, ColorHSVA)" />
 | 
				
			||||||
 | 
					    public static ColorHSVA Divide(this ColorHSVA color, float value) => ColorHSVA.Divide(color, value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <inheritdoc cref="ColorHSVA.Lerp(ColorHSVA, ColorHSVA, float)" />
 | 
				
			||||||
 | 
					    public static ColorHSVA Lerp(this ColorHSVA from, ColorHSVA to, float t) => ColorHSVA.Lerp(from, to, t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <inheritdoc cref="ColorHSVA.ApproximatelyEquals(ColorHSVA, ColorHSVA, float) " />
 | 
				
			||||||
 | 
					    public static bool ApproximatelyEquals(this ColorHSVA left, ColorHSVA right, float epsilon = float.Epsilon) => ColorHSVA.ApproximatelyEquals(left, right, epsilon);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -38,30 +38,8 @@ public readonly struct ColorRGB(byte r, byte g, byte b)
 | 
				
			|||||||
    public static bool operator !=(ColorRGB left, ColorRGB right) => left.R != right.R || left.G != right.G || left.B != right.B;
 | 
					    public static bool operator !=(ColorRGB left, ColorRGB right) => left.R != right.R || left.G != right.G || left.B != right.B;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static implicit operator ColorRGB(ColorRGBA rgba) => new(rgba.R, rgba.G, rgba.B);
 | 
					    public static implicit operator ColorRGB(ColorRGBA rgba) => new(rgba.R, rgba.G, rgba.B);
 | 
				
			||||||
    public static implicit operator ColorRGB(ColorHSV hsv)
 | 
					    public static implicit operator ColorRGB(ColorHSVA hsva) => (ColorRGBA)hsva;
 | 
				
			||||||
    {
 | 
					    public static implicit operator ColorRGB(ColorHSV hsv) => (ColorRGBA)hsv;
 | 
				
			||||||
        float hue = hsv.Hue * 360f;
 | 
					 | 
				
			||||||
        float chroma = hsv.Value * hsv.Saturation;
 | 
					 | 
				
			||||||
        float x = chroma * (1f - Math.Abs(hue / 60f % 2f - 1f));
 | 
					 | 
				
			||||||
        float m = hsv.Value - chroma;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        float r1 = 0f;
 | 
					 | 
				
			||||||
        float g1 = 0f;
 | 
					 | 
				
			||||||
        float b1 = 0f;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (hue < 60) { r1 = chroma; g1 = x; b1 = 0; }
 | 
					 | 
				
			||||||
        else if (hue < 120) { r1 = x; g1 = chroma; b1 = 0; }
 | 
					 | 
				
			||||||
        else if (hue < 180) { r1 = 0; g1 = chroma; b1 = x; }
 | 
					 | 
				
			||||||
        else if (hue < 240) { r1 = 0; g1 = x; b1 = chroma; }
 | 
					 | 
				
			||||||
        else if (hue < 300) { r1 = x; g1 = 0; b1 = chroma; }
 | 
					 | 
				
			||||||
        else if (hue <= 360) { r1 = chroma; g1 = 0; b1 = x; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        byte r = (byte)Math.RoundToInt((r1 + m) * 255);
 | 
					 | 
				
			||||||
        byte g = (byte)Math.RoundToInt((g1 + m) * 255);
 | 
					 | 
				
			||||||
        byte b = (byte)Math.RoundToInt((b1 + m) * 255);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return new(r, g, b);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// <summary>
 | 
					    /// <summary>
 | 
				
			||||||
    /// Inverts the given <see cref="ColorRGB"/>.
 | 
					    /// Inverts the given <see cref="ColorRGB"/>.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -44,7 +44,31 @@ public readonly struct ColorRGBA(byte r, byte g, byte b, byte a = 255)
 | 
				
			|||||||
    public static bool operator !=(ColorRGBA left, ColorRGBA right) => left.R != right.R || left.G != right.G || left.B != right.B || left.A != right.A;
 | 
					    public static bool operator !=(ColorRGBA left, ColorRGBA right) => left.R != right.R || left.G != right.G || left.B != right.B || left.A != right.A;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static implicit operator ColorRGBA(ColorRGB rgb) => new(rgb.R, rgb.G, rgb.B, 255);
 | 
					    public static implicit operator ColorRGBA(ColorRGB rgb) => new(rgb.R, rgb.G, rgb.B, 255);
 | 
				
			||||||
    public static implicit operator ColorRGBA(ColorHSV hsv) => (ColorRGB)hsv;
 | 
					    public static implicit operator ColorRGBA(ColorHSV hsv) => (ColorHSVA)hsv;
 | 
				
			||||||
 | 
					    public static implicit operator ColorRGBA(ColorHSVA hsva)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        float hue = hsva.Hue * 360f;
 | 
				
			||||||
 | 
					        float chroma = hsva.Value * hsva.Saturation;
 | 
				
			||||||
 | 
					        float x = chroma * (1f - Math.Abs(hue / 60f % 2f - 1f));
 | 
				
			||||||
 | 
					        float m = hsva.Value - chroma;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        float r1 = 0f;
 | 
				
			||||||
 | 
					        float g1 = 0f;
 | 
				
			||||||
 | 
					        float b1 = 0f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (hue < 60) { r1 = chroma; g1 = x; b1 = 0; }
 | 
				
			||||||
 | 
					        else if (hue < 120) { r1 = x; g1 = chroma; b1 = 0; }
 | 
				
			||||||
 | 
					        else if (hue < 180) { r1 = 0; g1 = chroma; b1 = x; }
 | 
				
			||||||
 | 
					        else if (hue < 240) { r1 = 0; g1 = x; b1 = chroma; }
 | 
				
			||||||
 | 
					        else if (hue < 300) { r1 = x; g1 = 0; b1 = chroma; }
 | 
				
			||||||
 | 
					        else if (hue <= 360) { r1 = chroma; g1 = 0; b1 = x; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        byte r = (byte)Math.RoundToInt((r1 + m) * 255);
 | 
				
			||||||
 | 
					        byte g = (byte)Math.RoundToInt((g1 + m) * 255);
 | 
				
			||||||
 | 
					        byte b = (byte)Math.RoundToInt((b1 + m) * 255);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return new(r, g, b, (byte)(hsva.Alpha * 255));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// <summary>
 | 
					    /// <summary>
 | 
				
			||||||
    /// Inverts the given <see cref="ColorRGBA"/>.
 | 
					    /// Inverts the given <see cref="ColorRGBA"/>.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,11 +5,14 @@ namespace Syntriax.Engine.Systems.Tween;
 | 
				
			|||||||
public static class TweenColorExtensions
 | 
					public static class TweenColorExtensions
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public static ITween TweenColor(this ColorRGB initialColorRGB, ITweenManager tweenManager, float duration, ColorRGB targetColorRGB, System.Action<ColorRGB> setMethod)
 | 
					    public static ITween TweenColor(this ColorRGB initialColorRGB, ITweenManager tweenManager, float duration, ColorRGB targetColorRGB, System.Action<ColorRGB> setMethod)
 | 
				
			||||||
        => tweenManager.StartTween(duration, t => setMethod?.Invoke(initialColorRGB.Lerp(targetColorRGB, t)));
 | 
					        => TweenColor((ColorHSV)initialColorRGB, tweenManager, duration, (ColorHSV)targetColorRGB, color => setMethod?.Invoke(color));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static ITween TweenColor(this ColorRGBA initialColorRGBA, ITweenManager tweenManager, float duration, ColorRGBA targetColorRGBA, System.Action<ColorRGBA> setMethod)
 | 
					    public static ITween TweenColor(this ColorRGBA initialColorRGBA, ITweenManager tweenManager, float duration, ColorRGBA targetColorRGBA, System.Action<ColorRGBA> setMethod)
 | 
				
			||||||
        => tweenManager.StartTween(duration, t => setMethod?.Invoke(initialColorRGBA.Lerp(targetColorRGBA, t)));
 | 
					        => TweenColor((ColorHSVA)initialColorRGBA, tweenManager, duration, (ColorHSVA)targetColorRGBA, color => setMethod?.Invoke(color));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static ITween TweenColor(this ColorHSV initialColorHSV, ITweenManager tweenManager, float duration, ColorHSV targetColorHSV, System.Action<ColorHSV> setMethod)
 | 
					    public static ITween TweenColor(this ColorHSV initialColorHSV, ITweenManager tweenManager, float duration, ColorHSV targetColorHSV, System.Action<ColorHSV> setMethod)
 | 
				
			||||||
        => tweenManager.StartTween(duration, t => setMethod?.Invoke(initialColorHSV.Lerp(targetColorHSV, t)));
 | 
					        => tweenManager.StartTween(duration, t => setMethod?.Invoke(initialColorHSV.Lerp(targetColorHSV, t)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static ITween TweenColor(this ColorHSVA initialColorHSVA, ITweenManager tweenManager, float duration, ColorHSVA targetColorHSVA, System.Action<ColorHSVA> setMethod)
 | 
				
			||||||
 | 
					        => tweenManager.StartTween(duration, t => setMethod?.Invoke(initialColorHSVA.Lerp(targetColorHSVA, t)));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user