mirror of
https://github.com/All-Of-Us-Mods/MiraAPI.git
synced 2026-10-20 01:46:15 +00:00
optimisations + example color
This commit is contained in:
11 files changed
+272
-96
No files matched your search
@@ -89,3 +89,9 @@ dotnet_diagnostic.IDE0001.severity = warning
|
||||
|
||||
# IDE0079: Remove unnecessary suppression
|
||||
dotnet_diagnostic.IDE0079.severity = none
|
||||
|
||||
# S1244: Floating point numbers should not be tested for equality
|
||||
dotnet_diagnostic.S1244.severity = none
|
||||
|
||||
# IDE0045: Convert to conditional expression
|
||||
dotnet_diagnostic.IDE0045.severity = none
|
||||
@@ -1,4 +1,6 @@
|
||||
using MiraAPI.Colors;
|
||||
using MiraAPI.Colors.ColorSpaces;
|
||||
using MiraAPI.Utilities;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MiraAPI.Example;
|
||||
@@ -14,4 +16,9 @@ public static class ExampleColors
|
||||
public static CustomColor Rose { get; } = new("color.rose", new Color(0.98f, 0.26f, 0.62f));
|
||||
|
||||
public static CustomColor Gold { get; } = new("color.gold", new Color(1.0f, 0.84f, 0.0f));
|
||||
|
||||
public static VariableColor Rainbow { get; } = new("color.rainbow", t => new HsbColor(MathUtilities.PingPong(t, 1f), 1f, 1f))
|
||||
{
|
||||
ColorBrightness = CustomColorBrightness.Lighter,
|
||||
};
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using MiraAPI.Utilities;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MiraAPI.Colors.ColorSpaces;
|
||||
@@ -20,7 +21,7 @@ public record struct CmykColor(float c, float m, float y, float k, float a = 1f)
|
||||
/// Implicitly converts a <see cref="CmykColor"/> to a Unity <see cref="Color"/>.
|
||||
/// </summary>
|
||||
/// <param name="c">The color being converted.</param>
|
||||
public static implicit operator Color(CmykColor c)
|
||||
public static implicit operator Color(in CmykColor c)
|
||||
{
|
||||
return ToColor(c);
|
||||
}
|
||||
@@ -29,7 +30,7 @@ public record struct CmykColor(float c, float m, float y, float k, float a = 1f)
|
||||
/// Implicitly converts a Unity <see cref="Color"/> to a <see cref="CmykColor"/>.
|
||||
/// </summary>
|
||||
/// <param name="c">The color being converted.</param>
|
||||
public static implicit operator CmykColor(Color c)
|
||||
public static implicit operator CmykColor(in Color c)
|
||||
{
|
||||
return FromColor(c);
|
||||
}
|
||||
@@ -39,13 +40,13 @@ public record struct CmykColor(float c, float m, float y, float k, float a = 1f)
|
||||
/// </summary>
|
||||
/// <param name="cmyk">The CMYK color to convert.</param>
|
||||
/// <returns>A Unity <see cref="Color"/> representing the same visual color.</returns>
|
||||
public static Color ToColor(CmykColor cmyk)
|
||||
public static Color ToColor(in CmykColor cmyk)
|
||||
{
|
||||
var r = (1f - cmyk.c) * (1f - cmyk.k);
|
||||
var g = (1f - cmyk.m) * (1f - cmyk.k);
|
||||
var b = (1f - cmyk.y) * (1f - cmyk.k);
|
||||
|
||||
return new Color(Mathf.Clamp01(r), Mathf.Clamp01(g), Mathf.Clamp01(b), cmyk.a);
|
||||
return new Color(MathUtilities.Clamp01(r), MathUtilities.Clamp01(g), MathUtilities.Clamp01(b), cmyk.a);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -53,22 +54,24 @@ public record struct CmykColor(float c, float m, float y, float k, float a = 1f)
|
||||
/// </summary>
|
||||
/// <param name="color">The Unity Color to convert.</param>
|
||||
/// <returns>A <see cref="CmykColor"/> representing the same visual color.</returns>
|
||||
public static CmykColor FromColor(Color color)
|
||||
public static CmykColor FromColor(in Color color)
|
||||
{
|
||||
var r = color.r;
|
||||
var g = color.g;
|
||||
var b = color.b;
|
||||
|
||||
var k = 1f - Mathf.Max(r, g, b);
|
||||
var k = 1f - MathF.Max(r, MathF.Max(g, b));
|
||||
|
||||
if (k >= 1f)
|
||||
return new CmykColor(0f, 0f, 0f, 1f, color.a);
|
||||
|
||||
var c = (1f - r - k) / (1f - k);
|
||||
var m = (1f - g - k) / (1f - k);
|
||||
var y = (1f - b - k) / (1f - k);
|
||||
var invK = 1f / (1f - k);
|
||||
|
||||
return new CmykColor(Mathf.Clamp01(c), Mathf.Clamp01(m), Mathf.Clamp01(y), Mathf.Clamp01(k), color.a);
|
||||
var c = (1f - r - k) * invK;
|
||||
var m = (1f - g - k) * invK;
|
||||
var y = (1f - b - k) * invK;
|
||||
|
||||
return new CmykColor(MathUtilities.Clamp01(c), MathUtilities.Clamp01(m), MathUtilities.Clamp01(y), MathUtilities.Clamp01(k), color.a);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -78,10 +81,9 @@ public record struct CmykColor(float c, float m, float y, float k, float a = 1f)
|
||||
/// <param name="b">The ending color.</param>
|
||||
/// <param name="t">The interpolation value between the two colors, clamped to a 0 to 1 range.</param>
|
||||
/// <returns>The interpolated <see cref="CmykColor"/>.</returns>
|
||||
public static CmykColor Lerp(CmykColor a, CmykColor b, float t)
|
||||
public static CmykColor Lerp(in CmykColor a, in CmykColor b, float t)
|
||||
{
|
||||
t = Mathf.Clamp01(t);
|
||||
return LerpUnclamped(a, b, t);
|
||||
return LerpUnclamped(a, b, MathUtilities.Clamp01(t));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -91,13 +93,13 @@ public record struct CmykColor(float c, float m, float y, float k, float a = 1f)
|
||||
/// <param name="b">The ending color.</param>
|
||||
/// <param name="t">The interpolation value between the two colors.</param>
|
||||
/// <returns>The interpolated <see cref="CmykColor"/>.</returns>
|
||||
public static CmykColor LerpUnclamped(CmykColor a, CmykColor b, float t)
|
||||
public static CmykColor LerpUnclamped(in CmykColor a, in CmykColor b, float t)
|
||||
{
|
||||
return new CmykColor(
|
||||
Mathf.LerpUnclamped(a.c, b.c, t),
|
||||
Mathf.LerpUnclamped(a.m, b.m, t),
|
||||
Mathf.LerpUnclamped(a.y, b.y, t),
|
||||
Mathf.LerpUnclamped(a.k, b.k, t),
|
||||
Mathf.LerpUnclamped(a.a, b.a, t));
|
||||
MathUtilities.LerpUnclamped(a.c, b.c, t),
|
||||
MathUtilities.LerpUnclamped(a.m, b.m, t),
|
||||
MathUtilities.LerpUnclamped(a.y, b.y, t),
|
||||
MathUtilities.LerpUnclamped(a.k, b.k, t),
|
||||
MathUtilities.LerpUnclamped(a.a, b.a, t));
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using MiraAPI.Utilities;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MiraAPI.Colors.ColorSpaces;
|
||||
@@ -19,7 +20,7 @@ public record struct HsbColor(float h, float s, float b, float a = 1f)
|
||||
/// Implicitly converts an <see cref="HsbColor"/> to a Unity <see cref="Color"/>.
|
||||
/// </summary>
|
||||
/// <param name="c">The color being converted.</param>
|
||||
public static implicit operator Color(HsbColor c)
|
||||
public static implicit operator Color(in HsbColor c)
|
||||
{
|
||||
return ToColor(c);
|
||||
}
|
||||
@@ -28,7 +29,7 @@ public record struct HsbColor(float h, float s, float b, float a = 1f)
|
||||
/// Implicitly converts a Unity <see cref="Color"/> to an <see cref="HsbColor"/>.
|
||||
/// </summary>
|
||||
/// <param name="c">The color being converted.</param>
|
||||
public static implicit operator HsbColor(Color c)
|
||||
public static implicit operator HsbColor(in Color c)
|
||||
{
|
||||
return FromColor(c);
|
||||
}
|
||||
@@ -38,33 +39,32 @@ public record struct HsbColor(float h, float s, float b, float a = 1f)
|
||||
/// </summary>
|
||||
/// <param name="hsb">The HSB color to convert.</param>
|
||||
/// <returns>A Unity <see cref="Color"/> representing the same visual color.</returns>
|
||||
public static Color ToColor(HsbColor hsb)
|
||||
public static Color ToColor(in HsbColor hsb)
|
||||
{
|
||||
var r = hsb.b;
|
||||
var g = hsb.b;
|
||||
var b = hsb.b;
|
||||
if (hsb.s <= float.Epsilon)
|
||||
return new Color(MathUtilities.Clamp01(hsb.b), MathUtilities.Clamp01(hsb.b), MathUtilities.Clamp01(hsb.b), hsb.a);
|
||||
|
||||
if (hsb.s <= Mathf.Epsilon)
|
||||
return new Color(Mathf.Clamp01(r), Mathf.Clamp01(g), Mathf.Clamp01(b), hsb.a);
|
||||
var c = hsb.b * hsb.s;
|
||||
var hPrime = hsb.h * 6f;
|
||||
var x = c * (1f - MathF.Abs((hPrime % 2f) - 1f));
|
||||
var m = hsb.b - c;
|
||||
|
||||
var max = hsb.b;
|
||||
var dif = hsb.b * hsb.s;
|
||||
var min = hsb.b - dif;
|
||||
|
||||
var h = hsb.h * 360f;
|
||||
|
||||
(r, g, b) = h switch
|
||||
var (r, g, b) = hPrime switch
|
||||
{
|
||||
< 60f => (max, h * dif / 60f + min, min),
|
||||
< 120f => (-(h - 120f) * dif / 60f + min, max, min),
|
||||
< 180f => (min, max, (h - 120f) * dif / 60f + min),
|
||||
< 240f => (min, -(h - 240f) * dif / 60f + min, max),
|
||||
< 300f => ((h - 240f) * dif / 60f + min, min, max),
|
||||
<= 360f => (max, min, -(h - 360f) * dif / 60f + min),
|
||||
< 1f => (c, x, 0f),
|
||||
< 2f => (x, c, 0f),
|
||||
< 3f => (0f, c, x),
|
||||
< 4f => (0f, x, c),
|
||||
< 5f => (x, 0f, c),
|
||||
<= 6f => (c, 0f, x),
|
||||
_ => (0f, 0f, 0f),
|
||||
};
|
||||
|
||||
return new Color(Mathf.Clamp01(r), Mathf.Clamp01(g), Mathf.Clamp01(b), hsb.a);
|
||||
return new Color(
|
||||
MathUtilities.Clamp01(r + m),
|
||||
MathUtilities.Clamp01(g + m),
|
||||
MathUtilities.Clamp01(b + m),
|
||||
hsb.a);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -72,10 +72,33 @@ public record struct HsbColor(float h, float s, float b, float a = 1f)
|
||||
/// </summary>
|
||||
/// <param name="color">The Unity Color to convert.</param>
|
||||
/// <returns>An <see cref="HsbColor"/> representing the same visual color.</returns>
|
||||
public static HsbColor FromColor(Color color)
|
||||
public static HsbColor FromColor(in Color color)
|
||||
{
|
||||
Color.RGBToHSV(color, out var h, out var s, out var v);
|
||||
return new HsbColor(h, s, v, color.a);
|
||||
var max = MathF.Max(color.r, MathF.Max(color.g, color.b));
|
||||
var min = MathF.Min(color.r, MathF.Min(color.g, color.b));
|
||||
var delta = max - min;
|
||||
|
||||
var h = 0f;
|
||||
|
||||
if (delta > 0f)
|
||||
{
|
||||
if (max == color.r)
|
||||
h = (color.g - color.b) / delta % 6f;
|
||||
else if (max == color.g)
|
||||
h = (color.b - color.r) / delta + 2f;
|
||||
else
|
||||
h = (color.r - color.g) / delta + 4f;
|
||||
|
||||
h /= 6f;
|
||||
|
||||
if (h < 0f)
|
||||
h += 1f;
|
||||
}
|
||||
|
||||
var s = max == 0f ? 0f : delta / max;
|
||||
var b = max;
|
||||
|
||||
return new HsbColor(h, s, b, color.a);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -85,10 +108,9 @@ public record struct HsbColor(float h, float s, float b, float a = 1f)
|
||||
/// <param name="b">The ending color.</param>
|
||||
/// <param name="t">The interpolation value between the two colors, clamped to a 0 to 1 range.</param>
|
||||
/// <returns>The interpolated <see cref="HsbColor"/>.</returns>
|
||||
public static HsbColor Lerp(HsbColor a, HsbColor b, float t)
|
||||
public static HsbColor Lerp(in HsbColor a, in HsbColor b, float t)
|
||||
{
|
||||
t = Mathf.Clamp01(t);
|
||||
return LerpUnclamped(a, b, t);
|
||||
return LerpUnclamped(a, b, MathUtilities.Clamp01(t));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -98,17 +120,17 @@ public record struct HsbColor(float h, float s, float b, float a = 1f)
|
||||
/// <param name="b">The ending color.</param>
|
||||
/// <param name="t">The interpolation value between the two colors.</param>
|
||||
/// <returns>The interpolated <see cref="HsbColor"/>.</returns>
|
||||
public static HsbColor LerpUnclamped(HsbColor a, HsbColor b, float t)
|
||||
public static HsbColor LerpUnclamped(in HsbColor a, in HsbColor b, float t)
|
||||
{
|
||||
var hueDifference = Mathf.Repeat(b.h - a.h, 1f);
|
||||
var hueDifference = MathUtilities.Repeat(b.h - a.h, 1f);
|
||||
|
||||
if (hueDifference > 0.5f)
|
||||
hueDifference -= 1f;
|
||||
|
||||
return new HsbColor(
|
||||
Mathf.Repeat(a.h + (hueDifference * t), 1f),
|
||||
Mathf.LerpUnclamped(a.s, b.s, t),
|
||||
Mathf.LerpUnclamped(a.b, b.b, t),
|
||||
Mathf.LerpUnclamped(a.a, b.a, t));
|
||||
MathUtilities.Repeat(a.h + (hueDifference * t), 1f),
|
||||
MathUtilities.LerpUnclamped(a.s, b.s, t),
|
||||
MathUtilities.LerpUnclamped(a.b, b.b, t),
|
||||
MathUtilities.LerpUnclamped(a.a, b.a, t));
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using MiraAPI.Utilities;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MiraAPI.Colors.ColorSpaces;
|
||||
@@ -19,7 +20,7 @@ public record struct HslColor(float h, float s, float l, float a = 1f)
|
||||
/// Implicitly converts an <see cref="HslColor"/> to a Unity <see cref="Color"/>.
|
||||
/// </summary>
|
||||
/// <param name="c">The color being converted.</param>
|
||||
public static implicit operator Color(HslColor c)
|
||||
public static implicit operator Color(in HslColor c)
|
||||
{
|
||||
return ToColor(c);
|
||||
}
|
||||
@@ -28,7 +29,7 @@ public record struct HslColor(float h, float s, float l, float a = 1f)
|
||||
/// Implicitly converts a Unity <see cref="Color"/> to an <see cref="HslColor"/>.
|
||||
/// </summary>
|
||||
/// <param name="c">The color being converted.</param>
|
||||
public static implicit operator HslColor(Color c)
|
||||
public static implicit operator HslColor(in Color c)
|
||||
{
|
||||
return FromColor(c);
|
||||
}
|
||||
@@ -38,14 +39,14 @@ public record struct HslColor(float h, float s, float l, float a = 1f)
|
||||
/// </summary>
|
||||
/// <param name="hsl">The HSL color to convert.</param>
|
||||
/// <returns>A Unity <see cref="Color"/> representing the same visual color.</returns>
|
||||
public static Color ToColor(HslColor hsl)
|
||||
public static Color ToColor(in HslColor hsl)
|
||||
{
|
||||
if (hsl.s <= Mathf.Epsilon)
|
||||
return new Color(Mathf.Clamp01(hsl.l), Mathf.Clamp01(hsl.l), Mathf.Clamp01(hsl.l), hsl.a);
|
||||
if (hsl.s <= float.Epsilon)
|
||||
return new Color(MathUtilities.Clamp01(hsl.l), MathUtilities.Clamp01(hsl.l), MathUtilities.Clamp01(hsl.l), hsl.a);
|
||||
|
||||
var c = (1f - Mathf.Abs(2f * hsl.l - 1f)) * hsl.s;
|
||||
var c = (1f - MathF.Abs(2f * hsl.l - 1f)) * hsl.s;
|
||||
var hPrime = hsl.h * 6f;
|
||||
var x = c * (1f - Mathf.Abs((hPrime % 2f) - 1f));
|
||||
var x = c * (1f - MathF.Abs((hPrime % 2f) - 1f));
|
||||
var m = hsl.l - c / 2f;
|
||||
|
||||
var (r, g, b) = hPrime switch
|
||||
@@ -55,11 +56,11 @@ public record struct HslColor(float h, float s, float l, float a = 1f)
|
||||
< 3f => (0f, c, x),
|
||||
< 4f => (0f, x, c),
|
||||
< 5f => (x, 0f, c),
|
||||
< 6f => (c, 0f, x),
|
||||
<= 6f => (c, 0f, x),
|
||||
_ => (0f, 0f, 0f),
|
||||
};
|
||||
|
||||
return new Color(Mathf.Clamp01(r + m), Mathf.Clamp01(g + m), Mathf.Clamp01(b + m), hsl.a);
|
||||
return new Color(MathUtilities.Clamp01(r + m), MathUtilities.Clamp01(g + m), MathUtilities.Clamp01(b + m), hsl.a);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -67,16 +68,31 @@ public record struct HslColor(float h, float s, float l, float a = 1f)
|
||||
/// </summary>
|
||||
/// <param name="color">The Unity Color to convert.</param>
|
||||
/// <returns>An <see cref="HslColor"/> representing the same visual color.</returns>
|
||||
public static HslColor FromColor(Color color)
|
||||
public static HslColor FromColor(in Color color)
|
||||
{
|
||||
var max = Mathf.Max(color.r, Mathf.Max(color.g, color.b));
|
||||
var min = Mathf.Min(color.r, Mathf.Min(color.g, color.b));
|
||||
var max = MathF.Max(color.r, MathF.Max(color.g, color.b));
|
||||
var min = MathF.Min(color.r, MathF.Min(color.g, color.b));
|
||||
var l = (max + min) / 2f;
|
||||
var delta = max - min;
|
||||
|
||||
var s = delta == 0f ? 0f : delta / (1f - Mathf.Abs(2f * l - 1f));
|
||||
var s = delta == 0f ? 0f : delta / (1f - MathF.Abs(2f * l - 1f));
|
||||
|
||||
Color.RGBToHSV(color, out var h, out _, out _);
|
||||
var h = 0f;
|
||||
|
||||
if (delta > 0f)
|
||||
{
|
||||
if (max == color.r)
|
||||
h = (color.g - color.b) / delta % 6f;
|
||||
else if (max == color.g)
|
||||
h = (color.b - color.r) / delta + 2f;
|
||||
else
|
||||
h = (color.r - color.g) / delta + 4f;
|
||||
|
||||
h /= 6f;
|
||||
|
||||
if (h < 0f)
|
||||
h += 1f;
|
||||
}
|
||||
|
||||
return new HslColor(h, s, l, color.a);
|
||||
}
|
||||
@@ -88,10 +104,9 @@ public record struct HslColor(float h, float s, float l, float a = 1f)
|
||||
/// <param name="b">The ending color.</param>
|
||||
/// <param name="t">The interpolation value between the two colors, clamped to a 0 to 1 range.</param>
|
||||
/// <returns>The interpolated <see cref="HslColor"/>.</returns>
|
||||
public static HslColor Lerp(HslColor a, HslColor b, float t)
|
||||
public static HslColor Lerp(in HslColor a, in HslColor b, float t)
|
||||
{
|
||||
t = Mathf.Clamp01(t);
|
||||
return LerpUnclamped(a, b, t);
|
||||
return LerpUnclamped(a, b, MathUtilities.Clamp01(t));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -101,17 +116,17 @@ public record struct HslColor(float h, float s, float l, float a = 1f)
|
||||
/// <param name="b">The ending color.</param>
|
||||
/// <param name="t">The interpolation value between the two colors.</param>
|
||||
/// <returns>The interpolated <see cref="HslColor"/>.</returns>
|
||||
public static HslColor LerpUnclamped(HslColor a, HslColor b, float t)
|
||||
public static HslColor LerpUnclamped(in HslColor a, in HslColor b, float t)
|
||||
{
|
||||
var hueDifference = Mathf.Repeat(b.h - a.h, 1f);
|
||||
var hueDifference = MathUtilities.Repeat(b.h - a.h, 1f);
|
||||
|
||||
if (hueDifference > 0.5f)
|
||||
hueDifference -= 1f;
|
||||
|
||||
return new HslColor(
|
||||
Mathf.Repeat(a.h + (hueDifference * t), 1f),
|
||||
Mathf.LerpUnclamped(a.s, b.s, t),
|
||||
Mathf.LerpUnclamped(a.l, b.l, t),
|
||||
Mathf.LerpUnclamped(a.a, b.a, t));
|
||||
MathUtilities.Repeat(a.h + (hueDifference * t), 1f),
|
||||
MathUtilities.LerpUnclamped(a.s, b.s, t),
|
||||
MathUtilities.LerpUnclamped(a.l, b.l, t),
|
||||
MathUtilities.LerpUnclamped(a.a, b.a, t));
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using MiraAPI.Translation;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using MiraAPI.Translation;
|
||||
using MiraAPI.Utilities;
|
||||
using UnityEngine;
|
||||
|
||||
@@ -10,17 +11,37 @@ namespace MiraAPI.Colors;
|
||||
/// <param name="name">The name of the option.</param>
|
||||
/// <param name="mainColor">The main color.</param>
|
||||
/// <param name="shadowColor">The shadow color.</param>
|
||||
[SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1513:Closing brace should be followed by blank line", Justification = "Looks weird.")]
|
||||
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "Internal code.")]
|
||||
public class CustomColor(StringNames name, Color32 mainColor, Color32 shadowColor)
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the main color.
|
||||
/// </summary>
|
||||
public Color32 MainColor { get; set; } = mainColor;
|
||||
public Color32 MainColor
|
||||
{
|
||||
get;
|
||||
set
|
||||
{
|
||||
field = value;
|
||||
InternalMainColor = value;
|
||||
}
|
||||
}
|
||||
= mainColor;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the shadow color.
|
||||
/// </summary>
|
||||
public Color32 ShadowColor { get; set; } = shadowColor;
|
||||
public Color32 ShadowColor
|
||||
{
|
||||
get;
|
||||
set
|
||||
{
|
||||
field = value;
|
||||
InternalShadowColor = value;
|
||||
}
|
||||
}
|
||||
= shadowColor;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the color.
|
||||
@@ -32,6 +53,9 @@ public class CustomColor(StringNames name, Color32 mainColor, Color32 shadowColo
|
||||
/// </summary>
|
||||
public CustomColorBrightness ColorBrightness { get; set; } = CustomColorBrightness.Darker;
|
||||
|
||||
internal Color InternalMainColor = mainColor;
|
||||
internal Color InternalShadowColor = shadowColor;
|
||||
|
||||
/// <inheritdoc cref="CustomColor"/>
|
||||
public CustomColor(StringNames name, Color32 mainColor)
|
||||
: this(name, mainColor, mainColor.GetShadowColor(60))
|
||||
|
||||
@@ -63,13 +63,13 @@ public static class PaletteManager
|
||||
/// </summary>
|
||||
/// <param name="colorId">The id of the color.</param>
|
||||
/// <returns>The main color associated with the provided ID.</returns>
|
||||
public static Color32 GetMainColor(int colorId)
|
||||
public static Color GetMainColor(int colorId)
|
||||
{
|
||||
return !ColorIdToColorMap.TryGetValue(colorId, out var custom)
|
||||
? Palette.PlayerColors[colorId]
|
||||
: (custom is VariableColor variable
|
||||
? variable.EvaluateMainColor()
|
||||
: custom.MainColor);
|
||||
: custom.InternalMainColor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -77,12 +77,12 @@ public static class PaletteManager
|
||||
/// </summary>
|
||||
/// <param name="colorId">The id of the color.</param>
|
||||
/// <returns>The shadow color associated with the provided ID.</returns>
|
||||
public static Color32 GetShadowColor(int colorId)
|
||||
public static Color GetShadowColor(int colorId)
|
||||
{
|
||||
return !ColorIdToColorMap.TryGetValue(colorId, out var custom)
|
||||
? Palette.ShadowColors[colorId]
|
||||
: (custom is VariableColor variable
|
||||
? variable.EvaluateShadowColor()
|
||||
: custom.ShadowColor);
|
||||
: custom.InternalShadowColor);
|
||||
}
|
||||
}
|
||||
@@ -14,33 +14,33 @@ namespace MiraAPI.Colors;
|
||||
/// <param name="shadowEvaluator">The function to evaluate the dynamic shadow color.</param>
|
||||
/// <param name="mainColor">The static main color used when dynamic colors are disabled.</param>
|
||||
/// <param name="shadowColor">The static shadow color used when dynamic colors are disabled.</param>
|
||||
public sealed class VariableColor(StringNames name, Func<float, Color32> mainEvaluator, Func<float, Color32>? shadowEvaluator, Color32? mainColor = null, Color32? shadowColor = null)
|
||||
public sealed class VariableColor(StringNames name, Func<float, Color> mainEvaluator, Func<float, Color>? shadowEvaluator, Color32? mainColor = null, Color32? shadowColor = null)
|
||||
: CustomColor(name, mainColor ?? mainEvaluator(0f), shadowColor ?? shadowEvaluator?.Invoke(0f) ?? (mainColor ?? mainEvaluator(0f)).GetShadowColor(60))
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets a delegate that takes a normalized time value and returns the dynamic main color.
|
||||
/// </summary>
|
||||
public Func<float, Color32> MainEvaluator { get; set; } = mainEvaluator;
|
||||
public Func<float, Color> MainEvaluator { get; set; } = mainEvaluator;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a delegate that takes a normalized time value and returns the dynamic shadow color.
|
||||
/// </summary>
|
||||
public Func<float, Color32> ShadowEvaluator { get; set; } = shadowEvaluator ?? (t => mainEvaluator(t).GetShadowColor(60));
|
||||
public Func<float, Color> ShadowEvaluator { get; set; } = shadowEvaluator ?? (t => mainEvaluator(t).GetShadowColor(0.24f));
|
||||
|
||||
/// <inheritdoc cref="VariableColor"/>
|
||||
public VariableColor(StringNames name, Func<float, Color32> mainEvaluator, Color32? mainColor = null)
|
||||
public VariableColor(StringNames name, Func<float, Color> mainEvaluator, Color32? mainColor = null)
|
||||
: this(name, mainEvaluator, null, mainColor, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="VariableColor"/>
|
||||
public VariableColor(string name, Func<float, Color32> mainEvaluator, Color32? mainColor = null)
|
||||
public VariableColor(string name, Func<float, Color> mainEvaluator, Color32? mainColor = null)
|
||||
: this(name, mainEvaluator, null, mainColor, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="VariableColor"/>
|
||||
public VariableColor(string name, Func<float, Color32> mainEvaluator, Func<float, Color32>? shadowEvaluator, Color32? mainColor = null, Color32? shadowColor = null)
|
||||
public VariableColor(string name, Func<float, Color> mainEvaluator, Func<float, Color>? shadowEvaluator, Color32? mainColor = null, Color32? shadowColor = null)
|
||||
: this(MiraLocaleManager.GetOrCreateLocaleString(name), mainEvaluator, shadowEvaluator, mainColor, shadowColor)
|
||||
{
|
||||
}
|
||||
@@ -49,21 +49,21 @@ public sealed class VariableColor(StringNames name, Func<float, Color32> mainEva
|
||||
/// Evaluates the dynamic main color based on the current in-game time.
|
||||
/// </summary>
|
||||
/// <returns>The dynamically evaluated color, or the static <see cref="CustomColor.MainColor"/> if static variant colors are enabled in the user's settings.</returns>
|
||||
public Color32 EvaluateMainColor()
|
||||
public Color EvaluateMainColor()
|
||||
{
|
||||
return LocalSettingsTabSingleton<MiraApiSettings>.Instance.EnableVariableColors.Value
|
||||
? MainEvaluator(Time.time)
|
||||
: MainColor;
|
||||
: InternalMainColor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Evaluates the dynamic shadow color based on the current in-game time.
|
||||
/// </summary>
|
||||
/// <returns>The dynamically evaluated color, or the static <see cref="CustomColor.ShadowColor"/> if static variant colors are enabled in the user's settings.</returns>
|
||||
public Color32 EvaluateShadowColor()
|
||||
public Color EvaluateShadowColor()
|
||||
{
|
||||
return LocalSettingsTabSingleton<MiraApiSettings>.Instance.EnableVariableColors.Value
|
||||
? ShadowEvaluator(Time.time)
|
||||
: ShadowColor;
|
||||
: InternalShadowColor;
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,8 @@ public sealed class VariableColorBehaviour : MonoBehaviour
|
||||
private Material material;
|
||||
private VariableColor? color;
|
||||
|
||||
private static readonly Color VisorColor = Palette.VisorColor;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the current variant color.
|
||||
/// </summary>
|
||||
@@ -41,6 +43,6 @@ public sealed class VariableColorBehaviour : MonoBehaviour
|
||||
|
||||
material.SetColor(ShaderID.BodyColor, color.EvaluateMainColor());
|
||||
material.SetColor(ShaderID.BackColor, color.EvaluateShadowColor());
|
||||
material.SetColor(ShaderID.VisorColor, Palette.VisorColor);
|
||||
material.SetColor(ShaderID.VisorColor, VisorColor);
|
||||
}
|
||||
}
|
||||
@@ -620,7 +620,23 @@ public static class Extensions
|
||||
(byte)Mathf.Clamp(color.r - darknessAmount, 0, 255),
|
||||
(byte)Mathf.Clamp(color.g - darknessAmount, 0, 255),
|
||||
(byte)Mathf.Clamp(color.b - darknessAmount, 0, 255),
|
||||
byte.MaxValue);
|
||||
color.a);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a darkened version of a <see cref="Color"/>.
|
||||
/// </summary>
|
||||
/// <param name="color">The original <see cref="Color"/>.</param>
|
||||
/// <param name="darknessAmount">A darkness amount between 0 and 1.</param>
|
||||
/// <returns>The darkened <see cref="Color"/>.</returns>
|
||||
public static Color GetShadowColor(this Color color, float darknessAmount)
|
||||
{
|
||||
return
|
||||
new Color(
|
||||
MathUtilities.Clamp01(color.r - darknessAmount),
|
||||
MathUtilities.Clamp01(color.g - darknessAmount),
|
||||
MathUtilities.Clamp01(color.b - darknessAmount),
|
||||
color.a);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -796,7 +812,7 @@ public static class Extensions
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fixed version of <see cref="Reactor.Utilities.Extensions.UnityExtensions.SetOutline(Renderer, Color?)"/>.
|
||||
/// Fixed version of <see cref="UnityExtensions.SetOutline(Renderer, Color?)"/>.
|
||||
/// </summary>
|
||||
/// <param name="renderer">The <see cref="Renderer"/> you want to update the outline for.</param>
|
||||
/// <param name="color">The outline <see cref="Color"/>.</param>
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
using System;
|
||||
|
||||
namespace MiraAPI.Utilities;
|
||||
|
||||
/// <summary>
|
||||
/// Provides mathematical utility methods.
|
||||
/// </summary>
|
||||
public static class MathUtilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Linearly interpolates between two values, clamping the interpolant between 0 and 1.
|
||||
/// </summary>
|
||||
/// <param name="a">The starting value.</param>
|
||||
/// <param name="b">The ending value.</param>
|
||||
/// <param name="t">The interpolation value, automatically clamped to a 0 to 1 range.</param>
|
||||
/// <returns>The interpolated float.</returns>
|
||||
public static float Lerp(float a, float b, float t)
|
||||
{
|
||||
return a + ((b - a) * Clamp01(t));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Linearly interpolates between two values without clamping the interpolant.
|
||||
/// </summary>
|
||||
/// <param name="a">The starting value.</param>
|
||||
/// <param name="b">The ending value.</param>
|
||||
/// <param name="t">The interpolation value.</param>
|
||||
/// <returns>The interpolated float.</returns>
|
||||
public static float LerpUnclamped(float a, float b, float t)
|
||||
{
|
||||
return a + ((b - a) * t);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clamps a floating-point value strictly between 0 and 1.
|
||||
/// </summary>
|
||||
/// <param name="value">The floating-point value to clamp.</param>
|
||||
/// <returns>The clamped value.</returns>
|
||||
public static float Clamp01(float value)
|
||||
{
|
||||
return Math.Clamp(value, 0f, 1f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ping-pongs a value back and forth between a minimum and maximum value.
|
||||
/// </summary>
|
||||
/// <param name="t">The input time or interpolant.</param>
|
||||
/// <param name="min">The minimum boundary of the ping-pong wave.</param>
|
||||
/// <param name="max">The maximum boundary of the ping-pong wave.</param>
|
||||
/// <param name="speed">The multiplier for the speed of the ping-pong effect.</param>
|
||||
/// <returns>A value oscillating continuously between <paramref name="min"/> and <paramref name="max"/>.</returns>
|
||||
public static float PingPong(float t, float min, float max, float speed = 1f)
|
||||
{
|
||||
return min + PingPong(t, max - min, speed);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ping-pongs a value back and forth between 0 and a specified length.
|
||||
/// </summary>
|
||||
/// <param name="t">The input time or interpolant.</param>
|
||||
/// <param name="length">The maximum value to bounce against, starting from 0.</param>
|
||||
/// <param name="speed">The multiplier for the speed of the ping-pong effect.</param>
|
||||
/// <returns>A value oscillating continuously between 0 and <paramref name="length"/>.</returns>
|
||||
public static float PingPong(float t, float length, float speed = 1f)
|
||||
{
|
||||
var dx = speed * t;
|
||||
var floor = (int)MathF.Floor(dx);
|
||||
var phase = floor % 2; // 0 = forward, 1 = backward
|
||||
return Clamp01(((dx - floor) * ((2 * phase) - 1)) + 1 - phase) * length;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loops a value strictly between 0 and a maximum length, behaving like a standard float modulo.
|
||||
/// </summary>
|
||||
/// <param name="t">The input value to loop.</param>
|
||||
/// <param name="length">The maximum length of the repeating sequence.</param>
|
||||
/// <returns>The wrapped value smoothly looping back to 0 upon reaching <paramref name="length"/>.</returns>
|
||||
public static float Repeat(float t, float length)
|
||||
{
|
||||
return Math.Clamp(t - (MathF.Floor(t / length) * length), 0f, length);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user