From d4356257573244fd754133e16da05755909766b9 Mon Sep 17 00:00:00 2001 From: Orange Date: Sat, 18 May 2024 13:58:54 +0300 Subject: [PATCH] added hsv stuff --- include/uml/color.h | 20 ++++++++++++++- source/color.cpp | 62 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 80 insertions(+), 2 deletions(-) diff --git a/include/uml/color.h b/include/uml/color.h index d5c05ff..f3f3795 100644 --- a/include/uml/color.h +++ b/include/uml/color.h @@ -11,6 +11,13 @@ namespace uml::color { + struct HSV + { + float m_hue{}; + float m_saturation{}; + float m_value{}; + }; + [[nodiscard]] Vector3 Blend(const Vector3& first, const Vector3& second, float ratio); @@ -18,9 +25,20 @@ namespace uml::color { public: Color(float r, float g, float b, float a); + + [[nodiscard]] static Color FromRGBA(uint8_t r, uint8_t g, uint8_t b, uint8_t a); + + [[nodiscard]] + static Color FromHSV(float hue, float saturation, float value); + + [[nodiscard]] + HSV ToHSV() const; + explicit Color(Vector4 vec); - [[nodiscard]] Color Blend(const Color& other, float ratio) const; + + [[nodiscard]] + Color Blend(const Color& other, float ratio) const; [[nodiscard]] static Color Red() {return {1.f, 0.f, 0.f, 1.f};} [[nodiscard]] static Color Green() {return {0.f, 1.f, 0.f, 1.f};} diff --git a/source/color.cpp b/source/color.cpp index d056008..0d09319 100644 --- a/source/color.cpp +++ b/source/color.cpp @@ -4,6 +4,8 @@ #include "uml/color.h" #include +#include + namespace uml::color { @@ -35,4 +37,62 @@ namespace uml::color { return Color{Vector4(r, g, b, a) / 255.f}; } -} \ No newline at end of file + + Color Color::FromHSV(float hue, const float saturation, const float value) { + float r{}, g{}, b{}; + + hue = std::clamp(hue, 0.f, 1.f); + + const int i = static_cast(hue * 6.f); + const float f = hue * 6 - i; + const float p = value * (1 - saturation); + const float q = value * (1 - f * saturation); + const float t = value * (1 - (1 - f) * saturation); + + switch (i % 6) + { + case 0: r = value, g = t, b = p; break; + case 1: r = q, g = value, b = p; break; + case 2: r = p, g = value, b = t; break; + case 3: r = p, g = q, b = value; break; + case 4: r = t, g = p, b = value; break; + case 5: r = value, g = p, b = q; break; + + default: return {0.f, 0.f, 0.f, 0.f}; + } + + return {r, g, b, 1.f}; + } + + HSV Color::ToHSV() const { + HSV hsvData; + + const float& red = x; + const float& green = y; + const float& blue = z; + + const float max = std::max({red, green, blue}); + const float min = std::min({red, green, blue}); + const float delta = max - min; + + + if (delta == 0.f) + hsvData.m_hue = 0.f; + + else if (max == red) + hsvData.m_hue = 60.f * (std::fmodf(((green - blue) / delta), 6.f)); + else if (max == green) + hsvData.m_hue = 60.f * (((blue - red) / delta) + 2.f); + else if (max == blue) + hsvData.m_hue = 60.f * (((red - green) / delta) + 4.f); + + if (hsvData.m_hue < 0.f) + hsvData.m_hue += 360.f; + + hsvData.m_hue /= 360.f; + hsvData.m_saturation = max == 0.f ? 0.f : delta / max; + hsvData.m_value = max; + + return hsvData; + } +}