From a2ec1ef418e1c0e2d2b6b357eb1e059158046dee Mon Sep 17 00:00:00 2001 From: Orange Date: Tue, 3 Sep 2024 21:23:25 +0300 Subject: [PATCH] added constexpr to color --- include/omath/color.h | 98 ++++++++++++++++++++++++++++++++++++----- source/color.cpp | 86 ------------------------------------ tests/UnitTestColor.cpp | 20 ++++----- 3 files changed, 96 insertions(+), 108 deletions(-) diff --git a/include/omath/color.h b/include/omath/color.h index 2a5f2ba..6f574ae 100644 --- a/include/omath/color.h +++ b/include/omath/color.h @@ -18,30 +18,104 @@ namespace omath::color float m_value{}; }; - [[nodiscard]] - Vector3 Blend(const Vector3& first, const Vector3& second, float ratio); class Color final : public Vector4 { public: - Color(float r, float g, float b, float a); - explicit Color(); + constexpr Color(float r, float g, float b, float a) : Vector4(r,g,b,a) + { + Clamp(0.f, 1.f); + } + + explicit Color() + ; [[nodiscard]] - static Color FromRGBA(uint8_t r, uint8_t g, uint8_t b, uint8_t a); + constexpr static Color FromRGBA(uint8_t r, uint8_t g, uint8_t b, uint8_t a) + { + return Color{Vector4(r, g, b, a) / 255.f}; + } [[nodiscard]] - static Color FromHSV(float hue, float saturation, float value); + constexpr static Color FromHSV(float hue, float saturation, 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}; + } [[nodiscard]] - HSV ToHSV() const; + constexpr HSV ToHSV() const + { + HSV hsvData; - explicit Color(Vector4 vec); + 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; + } + + constexpr explicit Color(const Vector4& vec) : Vector4(vec) + { + Clamp(0.f, 1.f); + } [[nodiscard]] - Color Blend(const Color& other, float ratio) const; + constexpr Color Blend(const Color& other, float ratio) const + { + return Color( (*this * (1.f - ratio)) + (other * ratio) ); + } - [[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};} - [[nodiscard]] static Color Blue() {return {0.f, 0.f, 1.f, 1.f};} + [[nodiscard]] static constexpr Color Red() {return {1.f, 0.f, 0.f, 1.f};} + [[nodiscard]] static constexpr Color Green() {return {0.f, 1.f, 0.f, 1.f};} + [[nodiscard]] static constexpr Color Blue() {return {0.f, 0.f, 1.f, 1.f};} }; + + [[nodiscard]] + constexpr Color Blend(const Color& first, const Color& second, float ratio) + { + return Color{first * (1.f - std::clamp(ratio, 0.f, 1.f)) + second * ratio}; + } } \ No newline at end of file diff --git a/source/color.cpp b/source/color.cpp index cbe1995..1916733 100644 --- a/source/color.cpp +++ b/source/color.cpp @@ -9,92 +9,6 @@ namespace omath::color { - Vector3 Blend(const Vector3 &first, const Vector3 &second, float ratio) - { - return first * (1.f - std::clamp(ratio, 0.f, 1.f)) + second * ratio; - } - - Color Color::Blend(const Color &other, float ratio) const - { - return Color( (*this * (1.f - ratio)) + (other * ratio) ); - } - - Color::Color(const float r, const float g, const float b, const float a) - : Vector4(std::clamp(r, 0.f, 1.f), - std::clamp(g, 0.f, 1.f), - std::clamp(b, 0.f, 1.f), - std::clamp(a, 0.f, 1.f)) - { - - } - - Color::Color(Vector4 vec) : Vector4(vec.Clamp(0.f, 1.f)) - { - - } - - Color Color::FromRGBA(uint8_t r, uint8_t g, uint8_t b, uint8_t a = 255) - { - return Color{Vector4(r, g, b, a) / 255.f}; - } - - 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; - } Color::Color() : Vector4(0.f, 0.f, 0.f, 0.f) { diff --git a/tests/UnitTestColor.cpp b/tests/UnitTestColor.cpp index ffe828c..a74de5c 100644 --- a/tests/UnitTestColor.cpp +++ b/tests/UnitTestColor.cpp @@ -23,7 +23,7 @@ protected: // Test constructors TEST_F(UnitTestColor, Constructor_Float) { - Color color(0.5f, 0.5f, 0.5f, 1.0f); + constexpr Color color(0.5f, 0.5f, 0.5f, 1.0f); EXPECT_FLOAT_EQ(color.x, 0.5f); EXPECT_FLOAT_EQ(color.y, 0.5f); EXPECT_FLOAT_EQ(color.z, 0.5f); @@ -32,7 +32,7 @@ TEST_F(UnitTestColor, Constructor_Float) TEST_F(UnitTestColor, Constructor_Vector4) { - omath::Vector4 vec(0.2f, 0.4f, 0.6f, 0.8f); + constexpr omath::Vector4 vec(0.2f, 0.4f, 0.6f, 0.8f); Color color(vec); EXPECT_FLOAT_EQ(color.x, 0.2f); EXPECT_FLOAT_EQ(color.y, 0.4f); @@ -43,7 +43,7 @@ TEST_F(UnitTestColor, Constructor_Vector4) // Test static methods for color creation TEST_F(UnitTestColor, FromRGBA) { - Color color = Color::FromRGBA(128, 64, 32, 255); + constexpr Color color = Color::FromRGBA(128, 64, 32, 255); EXPECT_FLOAT_EQ(color.x, 128.0f / 255.0f); EXPECT_FLOAT_EQ(color.y, 64.0f / 255.0f); EXPECT_FLOAT_EQ(color.z, 32.0f / 255.0f); @@ -52,7 +52,7 @@ TEST_F(UnitTestColor, FromRGBA) TEST_F(UnitTestColor, FromHSV) { - Color color = Color::FromHSV(0.0f, 1.0f, 1.0f); // Red in HSV + constexpr Color color = Color::FromHSV(0.0f, 1.0f, 1.0f); // Red in HSV EXPECT_FLOAT_EQ(color.x, 1.0f); EXPECT_FLOAT_EQ(color.y, 0.0f); EXPECT_FLOAT_EQ(color.z, 0.0f); @@ -81,9 +81,9 @@ TEST_F(UnitTestColor, Blend) // Test predefined colors TEST_F(UnitTestColor, PredefinedColors) { - Color red = Color::Red(); - Color green = Color::Green(); - Color blue = Color::Blue(); + constexpr Color red = Color::Red(); + constexpr Color green = Color::Green(); + constexpr Color blue = Color::Blue(); EXPECT_FLOAT_EQ(red.x, 1.0f); EXPECT_FLOAT_EQ(red.y, 0.0f); @@ -104,9 +104,9 @@ TEST_F(UnitTestColor, PredefinedColors) // Test non-member function: Blend for Vector3 TEST_F(UnitTestColor, BlendVector3) { - omath::Vector3 v1(1.0f, 0.0f, 0.0f); // Red - omath::Vector3 v2(0.0f, 1.0f, 0.0f); // Green - omath::Vector3 blended = Blend(v1, v2, 0.5f); + constexpr omath::color::Color v1(1.0f, 0.0f, 0.0f, 1.f); // Red + constexpr omath::color::Color v2(0.0f, 1.0f, 0.0f, 1.f); // Green + constexpr omath::color::Color blended = Blend(v1, v2, 0.5f); EXPECT_FLOAT_EQ(blended.x, 0.5f); EXPECT_FLOAT_EQ(blended.y, 0.5f); EXPECT_FLOAT_EQ(blended.z, 0.0f);