156 lines
3.7 KiB
C#
156 lines
3.7 KiB
C#
using System;
|
|
using System.Numerics;
|
|
using System.Runtime.CompilerServices;
|
|
using Auspex.Rendering.Direct3D;
|
|
using Dalamud.Bindings.ImGui;
|
|
|
|
namespace Auspex;
|
|
|
|
public static class AxColor
|
|
{
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static uint WithAlpha(uint color, byte alpha)
|
|
{
|
|
return (color & 0xFFFFFF) | (uint)(alpha << 24);
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static uint WithAlpha(uint color, float alphaFactor)
|
|
{
|
|
uint num = (color >> 24) & 0xFF;
|
|
num = (uint)((float)num * Math.Clamp(alphaFactor, 0f, 1f));
|
|
return (color & 0xFFFFFF) | (num << 24);
|
|
}
|
|
|
|
public static uint FromHSV(float h, float s, float v, float a = 1f)
|
|
{
|
|
float outR = 0f;
|
|
float outG = 0f;
|
|
float outB = 0f;
|
|
ImGui.ColorConvertHSVtoRGB(h, s, v, ref outR, ref outG, ref outB);
|
|
return new Vector4(outR, outG, outB, a).ToUint();
|
|
}
|
|
|
|
public static (float H, float S, float V, float A) ToHSV(uint color)
|
|
{
|
|
Vector4 vector = color.ToVector4();
|
|
float outH = 0f;
|
|
float outS = 0f;
|
|
float outV = 0f;
|
|
ImGui.ColorConvertRGBtoHSV(vector.X, vector.Y, vector.Z, ref outH, ref outS, ref outV);
|
|
return (H: outH, S: outS, V: outV, A: vector.W);
|
|
}
|
|
|
|
public static uint FromHSL(float h, float s, float l, float a = 1f)
|
|
{
|
|
HSLToRGB(h, s, l, out var r, out var g, out var b);
|
|
return new Vector4(r, g, b, a).ToUint();
|
|
}
|
|
|
|
public static (float H, float S, float L, float A) ToHSL(uint color)
|
|
{
|
|
Vector4 vector = color.ToVector4();
|
|
RGBToHSL(vector.X, vector.Y, vector.Z, out var h, out var s, out var l);
|
|
return (H: h, S: s, L: l, A: vector.W);
|
|
}
|
|
|
|
public static uint Brighten(uint color, float amount)
|
|
{
|
|
Vector4 vector = color.ToVector4();
|
|
RGBToHSL(vector.X, vector.Y, vector.Z, out var h, out var s, out var l);
|
|
l = Math.Clamp(l + amount, 0f, 1f);
|
|
HSLToRGB(h, s, l, out var r, out var g, out var b);
|
|
return new Vector4(r, g, b, vector.W).ToUint();
|
|
}
|
|
|
|
public static uint Darken(uint color, float amount)
|
|
{
|
|
return Brighten(color, 0f - amount);
|
|
}
|
|
|
|
public static uint Saturate(uint color, float amount)
|
|
{
|
|
return Desaturate(color, 0f - amount);
|
|
}
|
|
|
|
public static uint Desaturate(uint color, float amount)
|
|
{
|
|
Vector4 vector = color.ToVector4();
|
|
RGBToHSL(vector.X, vector.Y, vector.Z, out var h, out var s, out var l);
|
|
s = Math.Clamp(s - amount, 0f, 1f);
|
|
HSLToRGB(h, s, l, out var r, out var g, out var b);
|
|
return new Vector4(r, g, b, vector.W).ToUint();
|
|
}
|
|
|
|
public static uint Lerp(uint from, uint to, float t)
|
|
{
|
|
Vector4 value = from.ToVector4();
|
|
Vector4 value2 = to.ToVector4();
|
|
return Vector4.Lerp(value, value2, t).ToUint();
|
|
}
|
|
|
|
private static void RGBToHSL(float r, float g, float b, out float h, out float s, out float l)
|
|
{
|
|
float num = MathF.Max(r, MathF.Max(g, b));
|
|
float num2 = MathF.Min(r, MathF.Min(g, b));
|
|
l = (num + num2) * 0.5f;
|
|
if (num == num2)
|
|
{
|
|
h = (s = 0f);
|
|
return;
|
|
}
|
|
float num3 = num - num2;
|
|
s = ((l > 0.5f) ? (num3 / (2f - num - num2)) : (num3 / (num + num2)));
|
|
if (num == r)
|
|
{
|
|
h = ((g - b) / num3 + ((g < b) ? 6f : 0f)) / 6f;
|
|
}
|
|
else if (num == g)
|
|
{
|
|
h = ((b - r) / num3 + 2f) / 6f;
|
|
}
|
|
else
|
|
{
|
|
h = ((r - g) / num3 + 4f) / 6f;
|
|
}
|
|
}
|
|
|
|
private static void HSLToRGB(float h, float s, float l, out float r, out float g, out float b)
|
|
{
|
|
if (s == 0f)
|
|
{
|
|
r = (g = (b = l));
|
|
return;
|
|
}
|
|
float num = ((l < 0.5f) ? (l * (1f + s)) : (l + s - l * s));
|
|
float p = 2f * l - num;
|
|
r = HueToRGB(p, num, h + 1f / 3f);
|
|
g = HueToRGB(p, num, h);
|
|
b = HueToRGB(p, num, h - 1f / 3f);
|
|
}
|
|
|
|
private static float HueToRGB(float p, float q, float t)
|
|
{
|
|
if (t < 0f)
|
|
{
|
|
t += 1f;
|
|
}
|
|
if (t > 1f)
|
|
{
|
|
t -= 1f;
|
|
}
|
|
if (t < 1f / 6f)
|
|
{
|
|
return p + (q - p) * 6f * t;
|
|
}
|
|
if (t < 0.5f)
|
|
{
|
|
return q;
|
|
}
|
|
if (t < 2f / 3f)
|
|
{
|
|
return p + (q - p) * (2f / 3f - t) * 6f;
|
|
}
|
|
return p;
|
|
}
|
|
}
|