Browse Source

Math: use a dedicated type for HSV colors instead of a tuple.

Pros:

 * faster compile times (#include <tuple> is 13k lines, ugh)
 * ability to have NoInit and ZeroInit constructors
 * ability to do fuzzy compare
 * named members, so we don't have to use mutable std::tie()

Cons:

 * ... none?

The old Color[34]::Hsv is still a tuple and the new ColorHsv is
convertible to/from it (and even std::tie() works). These are all
deprecated (along with the <tuple> include).
pull/331/head
Vladimír Vondruš 7 years ago
parent
commit
547a3f3cea
  1. 4
      doc/changelog.dox
  2. 2
      doc/generated/shaders.cpp
  3. 2
      doc/snippets/MagnumDebugTools-gl.cpp
  4. 20
      doc/snippets/MagnumMath.cpp
  5. 3
      src/Magnum/Magnum.h
  6. 205
      src/Magnum/Math/Color.h
  7. 1
      src/Magnum/Math/Math.h
  8. 235
      src/Magnum/Math/Test/ColorTest.cpp
  9. 2
      src/Magnum/Math/instantiation.cpp

4
doc/changelog.dox

@ -294,6 +294,10 @@ See also:
@subsection changelog-latest-deprecated Deprecated APIs @subsection changelog-latest-deprecated Deprecated APIs
- @cpp Math::Color3::Hsv @ce and @cpp Math::Color4::Hsv @ce tuple typedefs
are deprecated in favor of tuple-less @ref Math::ColorHsv, working
correctly with the usual @ref Math::NoInit / @ref Math::ZeroInit tags while
being faster to compile
- @cpp Trade::ImporterFileCallbackPolicy @ce is deprecated as it was moved - @cpp Trade::ImporterFileCallbackPolicy @ce is deprecated as it was moved
to @ref InputFileCallbackPolicy in the root namespace to be shared with to @ref InputFileCallbackPolicy in the root namespace to be shared with
APIs outside of the @ref Trade namespace APIs outside of the @ref Trade namespace

2
doc/generated/shaders.cpp

@ -194,7 +194,7 @@ std::string ShaderVisualizer::vertexColor() {
std::vector<Color3> colors; std::vector<Color3> colors;
colors.reserve(sphere.positions(0).size()); colors.reserve(sphere.positions(0).size());
for(Vector3 position: sphere.positions(0)) for(Vector3 position: sphere.positions(0))
colors.push_back(Color3::fromHsv(Math::lerp(240.0_degf, 420.0_degf, Math::max(1.0f - (position - target).length(), 0.0f)), 0.85f, 0.666f)); colors.push_back(Color3::fromHsv({Math::lerp(240.0_degf, 420.0_degf, Math::max(1.0f - (position - target).length(), 0.0f)), 0.85f, 0.666f}));
GL::Buffer vertices, indices; GL::Buffer vertices, indices;
vertices.setData(MeshTools::interleave(sphere.positions(0), colors), GL::BufferUsage::StaticDraw); vertices.setData(MeshTools::interleave(sphere.positions(0), colors), GL::BufferUsage::StaticDraw);

2
doc/snippets/MagnumDebugTools-gl.cpp

@ -71,7 +71,7 @@ SceneGraph::DrawableGroup3D debugDrawables;
DebugTools::ResourceManager::instance().set("my", DebugTools::ResourceManager::instance().set("my",
DebugTools::ForceRendererOptions{} DebugTools::ForceRendererOptions{}
.setSize(5.0f) .setSize(5.0f)
.setColor(Color3::fromHsv(120.0_degf, 1.0f, 0.7f))); .setColor(Color3::fromHsv({120.0_degf, 1.0f, 0.7f})));
// Create debug renderer for given object, use "my" options for it // Create debug renderer for given object, use "my" options for it
Vector3 force; Vector3 force;

20
doc/snippets/MagnumMath.cpp

@ -110,7 +110,7 @@ static_cast<void>(b);
/* [matrix-vector-construct-color-hue] */ /* [matrix-vector-construct-color-hue] */
auto green = Color3::green(); // {0.0f, 1.0f, 0.0f} auto green = Color3::green(); // {0.0f, 1.0f, 0.0f}
auto cyan = Color4::cyan(0.5f, 0.95f); // {0.5f, 1.0f, 1.0f, 0.95f} auto cyan = Color4::cyan(0.5f, 0.95f); // {0.5f, 1.0f, 1.0f, 0.95f}
auto fadedRed = Color3::fromHsv(219.0_degf, 0.50f, 0.57f); auto fadedRed = Color3::fromHsv({219.0_degf, 0.50f, 0.57f});
/* [matrix-vector-construct-color-hue] */ /* [matrix-vector-construct-color-hue] */
static_cast<void>(green); static_cast<void>(green);
static_cast<void>(cyan); static_cast<void>(cyan);
@ -726,15 +726,6 @@ static_cast<void>(a);
static_cast<void>(b); static_cast<void>(b);
} }
{
Color3 color;
/* [Color3-toHsv] */
Deg hue;
Float saturation, value;
std::tie(hue, saturation, value) = color.toHsv();
/* [Color3-toHsv] */
}
{ {
/* [Color3-toSrgb] */ /* [Color3-toSrgb] */
Color3 color; Color3 color;
@ -775,15 +766,6 @@ Color4 rgba = Color4::fromSrgb(0xff3366, 0.5f);
static_cast<void>(rgba); static_cast<void>(rgba);
} }
{
Color4 color;
/* [Color4-toHsv] */
Deg hue;
Float saturation, value;
std::tie(hue, saturation, value) = color.toHsv();
/* [Color4-toHsv] */
}
{ {
/* [Color4-toSrgbAlpha] */ /* [Color4-toSrgbAlpha] */
Color4 color; Color4 color;

3
src/Magnum/Magnum.h

@ -311,6 +311,9 @@ typedef Math::Color3<Float> Color3;
/** @brief Four-component (RGBA) float color */ /** @brief Four-component (RGBA) float color */
typedef Math::Color4<Float> Color4; typedef Math::Color4<Float> Color4;
/** @brief HSV float color */
typedef Math::ColorHsv<Float> ColorHsv;
/** /**
@brief Three-component (RGB) unsigned byte color @brief Three-component (RGB) unsigned byte color

205
src/Magnum/Math/Color.h

@ -29,45 +29,43 @@
* @brief Class @ref Magnum::Math::Color3, @ref Magnum::Math::Color4, literal @link Magnum::Math::Literals::operator""_rgb() @endlink, @link Magnum::Math::Literals::operator""_rgba() @endlink, @link Magnum::Math::Literals::operator""_rgbf() @endlink, @link Magnum::Math::Literals::operator""_rgbaf() @endlink, @link Magnum::Math::Literals::operator""_srgb() @endlink, @link Magnum::Math::Literals::operator""_srgba() @endlink, @link Magnum::Math::Literals::operator""_srgbf() @endlink, @link Magnum::Math::Literals::operator""_srgbaf() @endlink * @brief Class @ref Magnum::Math::Color3, @ref Magnum::Math::Color4, literal @link Magnum::Math::Literals::operator""_rgb() @endlink, @link Magnum::Math::Literals::operator""_rgba() @endlink, @link Magnum::Math::Literals::operator""_rgbf() @endlink, @link Magnum::Math::Literals::operator""_rgbaf() @endlink, @link Magnum::Math::Literals::operator""_srgb() @endlink, @link Magnum::Math::Literals::operator""_srgba() @endlink, @link Magnum::Math::Literals::operator""_srgbf() @endlink, @link Magnum::Math::Literals::operator""_srgbaf() @endlink
*/ */
#include <tuple>
#include "Magnum/Math/Matrix.h" #include "Magnum/Math/Matrix.h"
#include "Magnum/Math/Packing.h" #include "Magnum/Math/Packing.h"
#include "Magnum/Math/Vector4.h" #include "Magnum/Math/Vector4.h"
#ifdef MAGNUM_BUILD_DEPRECATED
#include <tuple> /** @todo remove when Color[34]::Hsv is removed */
#endif
namespace Magnum { namespace Math { namespace Magnum { namespace Math {
namespace Implementation { namespace Implementation {
/* Convert color from HSV */ /* Convert color from HSV */
template<class T> typename std::enable_if<std::is_floating_point<T>::value, Color3<T>>::type fromHsv(const typename Color3<T>::Hsv& hsv) { template<class T> typename std::enable_if<std::is_floating_point<T>::value, Color3<T>>::type fromHsv(ColorHsv<T> hsv) {
Deg<T> hue;
T saturation, value;
std::tie(hue, saturation, value) = hsv;
/* Remove repeats */ /* Remove repeats */
hue -= floor(T(hue)/T(360))*Deg<T>(360); hsv.hue -= floor(T(hsv.hue)/T(360))*Deg<T>(360);
if(hue < Deg<T>(0)) hue += Deg<T>(360); if(hsv.hue < Deg<T>(0)) hsv.hue += Deg<T>(360);
int h = int(T(hue)/T(60)) % 6; int h = int(T(hsv.hue)/T(60)) % 6;
T f = T(hue)/T(60) - h; T f = T(hsv.hue)/T(60) - h;
T p = value * (T(1) - saturation); T p = hsv.value * (T(1) - hsv.saturation);
T q = value * (T(1) - f*saturation); T q = hsv.value * (T(1) - f*hsv.saturation);
T t = value * (T(1) - (T(1) - f)*saturation); T t = hsv.value * (T(1) - (T(1) - f)*hsv.saturation);
switch(h) { switch(h) {
case 0: return {value, t, p}; case 0: return {hsv.value, t, p};
case 1: return {q, value, p}; case 1: return {q, hsv.value, p};
case 2: return {p, value, t}; case 2: return {p, hsv.value, t};
case 3: return {p, q, value}; case 3: return {p, q, hsv.value};
case 4: return {t, p, value}; case 4: return {t, p, hsv.value};
case 5: return {value, p, q}; case 5: return {hsv.value, p, q};
default: CORRADE_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */ default: CORRADE_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */
} }
} }
template<class T> inline typename std::enable_if<std::is_integral<T>::value, Color3<T>>::type fromHsv(const typename Color3<T>::Hsv& hsv) { template<class T> inline typename std::enable_if<std::is_integral<T>::value, Color3<T>>::type fromHsv(const ColorHsv<typename TypeTraits<T>::FloatingPointType>& hsv) {
return pack<Color3<T>>(fromHsv<typename Color3<T>::FloatingPointType>(hsv)); return pack<Color3<T>>(fromHsv<typename TypeTraits<T>::FloatingPointType>(hsv));
} }
/* Internal hue computing function */ /* Internal hue computing function */
@ -114,14 +112,14 @@ template<class T> inline typename Color3<T>::FloatingPointType value(typename st
} }
/* Convert color to HSV */ /* Convert color to HSV */
template<class T> inline typename Color3<T>::Hsv toHsv(typename std::enable_if<std::is_floating_point<T>::value, const Color3<T>&>::type color) { template<class T> inline ColorHsv<T> toHsv(typename std::enable_if<std::is_floating_point<T>::value, const Color3<T>&>::type color) {
T max = color.max(); T max = color.max();
T delta = max - color.min(); T delta = max - color.min();
return typename Color3<T>::Hsv(hue<typename Color3<T>::FloatingPointType>(color, max, delta), max != T(0) ? delta/max : T(0), max); return ColorHsv<T>{hue<typename Color3<T>::FloatingPointType>(color, max, delta), max != T(0) ? delta/max : T(0), max};
} }
template<class T> inline typename Color3<T>::Hsv toHsv(typename std::enable_if<std::is_integral<T>::value, const Color3<T>&>::type color) { template<class T> inline ColorHsv<typename TypeTraits<T>::FloatingPointType> toHsv(typename std::enable_if<std::is_integral<T>::value, const Color3<T>&>::type color) {
return toHsv<typename Color3<T>::FloatingPointType>(unpack<Color3<typename Color3<T>::FloatingPointType>>(color)); return toHsv<typename TypeTraits<T>::FloatingPointType>(unpack<Color3<typename TypeTraits<T>::FloatingPointType>>(color));
} }
/* sRGB -> RGB conversion */ /* sRGB -> RGB conversion */
@ -254,13 +252,12 @@ template<class T> class Color3: public Vector3<T> {
*/ */
typedef typename TypeTraits<T>::FloatingPointType FloatingPointType; typedef typename TypeTraits<T>::FloatingPointType FloatingPointType;
/** #ifdef MAGNUM_BUILD_DEPRECATED
* @brief Type for storing HSV color space values /** @brief @copybrief ColorHsv
* * @deprecated Use @ref ColorHsv instead.
* Hue in range @f$ [0.0, 360.0] @f$, saturation and value in range
* @f$ [0.0, 1.0] @f$.
*/ */
typedef std::tuple<Deg<FloatingPointType>, FloatingPointType, FloatingPointType> Hsv; typedef CORRADE_DEPRECATED("use ColorHsv instead") std::tuple<Deg<FloatingPointType>, FloatingPointType, FloatingPointType> Hsv;
#endif
/** /**
* @brief Red color * @brief Red color
@ -335,13 +332,18 @@ template<class T> class Color3: public Vector3<T> {
* Hue can overflow the range @f$ [0.0, 360.0] @f$. * Hue can overflow the range @f$ [0.0, 360.0] @f$.
* @see @ref toHsv() * @see @ref toHsv()
*/ */
static Color3<T> fromHsv(const Hsv& hsv) { static Color3<T> fromHsv(const ColorHsv<FloatingPointType>& hsv) {
return Implementation::fromHsv<T>(hsv); return Implementation::fromHsv<T>(hsv);
} }
/** @overload */
static Color3<T> fromHsv(Deg<FloatingPointType> hue, FloatingPointType saturation, FloatingPointType value) { #ifdef MAGNUM_BUILD_DEPRECATED
return fromHsv(std::make_tuple(hue, saturation, value)); /** @brief @copybrief fromHsv(const ColorHsv<FloatingPointType>&)
* @deprecated Use @ref fromHsv(const ColorHsv<FloatingPointType>&) instead.
*/
static CORRADE_DEPRECATED("use fromHsv(const ColorHsv<FloatingPointType>&) instead") Color3<T> fromHsv(Deg<FloatingPointType> hue, FloatingPointType saturation, FloatingPointType value) {
return fromHsv({hue, saturation, value});
} }
#endif
/** /**
* @brief Create linear RGB color from sRGB representation * @brief Create linear RGB color from sRGB representation
@ -482,13 +484,9 @@ template<class T> class Color3: public Vector3<T> {
/** /**
* @brief Convert to HSV representation * @brief Convert to HSV representation
* *
* Example usage:
*
* @snippet MagnumMath.cpp Color3-toHsv
*
* @see @ref hue(), @ref saturation(), @ref value(), @ref fromHsv() * @see @ref hue(), @ref saturation(), @ref value(), @ref fromHsv()
*/ */
Hsv toHsv() const { ColorHsv<FloatingPointType> toHsv() const {
return Implementation::toHsv<T>(*this); return Implementation::toHsv<T>(*this);
} }
@ -616,8 +614,12 @@ class Color4: public Vector4<T> {
/** @copydoc Color3::FloatingPointType */ /** @copydoc Color3::FloatingPointType */
typedef typename Color3<T>::FloatingPointType FloatingPointType; typedef typename Color3<T>::FloatingPointType FloatingPointType;
/** @copydoc Color3::Hsv */ #ifdef MAGNUM_BUILD_DEPRECATED
typedef typename Color3<T>::Hsv Hsv; /** @brief @copybrief ColorHsv
* @deprecated Use @ref ColorHsv instead.
*/
typedef CORRADE_DEPRECATED("use ColorHsv instead") std::tuple<Deg<FloatingPointType>, FloatingPointType, FloatingPointType> Hsv;
#endif
/** /**
* @brief Red color * @brief Red color
@ -689,13 +691,18 @@ class Color4: public Vector4<T> {
* Hue can overflow the range @f$ [0.0, 360.0] @f$. * Hue can overflow the range @f$ [0.0, 360.0] @f$.
* @see @ref toHsv() * @see @ref toHsv()
*/ */
static Color4<T> fromHsv(const Hsv& hsv, T a = Implementation::fullChannel<T>()) { static Color4<T> fromHsv(const ColorHsv<FloatingPointType>& hsv, T a = Implementation::fullChannel<T>()) {
return Color4<T>(Implementation::fromHsv<T>(hsv), a); return Color4<T>(Implementation::fromHsv<T>(hsv), a);
} }
/** @overload */
static Color4<T> fromHsv(Deg<FloatingPointType> hue, FloatingPointType saturation, FloatingPointType value, T alpha = Implementation::fullChannel<T>()) { #ifdef MAGNUM_BUILD_DEPRECATED
return fromHsv(std::make_tuple(hue, saturation, value), alpha); /** @brief @copybrief fromHsv(const ColorHsv<FloatingPointType>&, T)
* @deprecated Use @ref fromHsv(const ColorHsv<FloatingPointType>&, T) instead.
*/
static CORRADE_DEPRECATED("use fromHsv(const ColorHsv<FloatingPointType>&, T) instead") Color4<T> fromHsv(Deg<FloatingPointType> hue, FloatingPointType saturation, FloatingPointType value, T alpha = Implementation::fullChannel<T>()) {
return fromHsv({hue, saturation, value}, alpha);
} }
#endif
/** /**
* @brief Create linear RGBA color from sRGB + alpha representation * @brief Create linear RGBA color from sRGB + alpha representation
@ -899,13 +906,11 @@ class Color4: public Vector4<T> {
* @brief Convert to HSV representation * @brief Convert to HSV representation
* *
* The alpha channel is not subject to any conversion, so it is * The alpha channel is not subject to any conversion, so it is
* ignored. Example usage: * ignored.
* * @see @ref hue(), @ref saturation(), @ref value(), @ref a(),
* @snippet MagnumMath.cpp Color4-toHsv * @ref fromHsv()
*
* @see @ref hue(), @ref saturation(), @ref value(), @ref fromHsv()
*/ */
Hsv toHsv() const { ColorHsv<FloatingPointType> toHsv() const {
return Implementation::toHsv<T>(Vector4<T>::rgb()); return Implementation::toHsv<T>(Vector4<T>::rgb());
} }
@ -1025,6 +1030,100 @@ template<class T> inline Vector3<T> xyzToXyY(const Vector3<T>& xyz) {
return {xyz.xy()/xyz.sum(), xyz.y()}; return {xyz.xy()/xyz.sum(), xyz.y()};
} }
/**
@brief HSV color
Storage-only type with just the usual constructors and (non-)equality
comparison.
@see @ref Color3::fromHsv(), @ref Color3::toHsv(), @ref Color4::fromHsv(),
@ref Color4::toHsv()
*/
template<class T> struct ColorHsv {
/**
* @brief Default constructor
*
* All members are set to zero.
*/
constexpr /*implicit*/ ColorHsv(ZeroInitT = ZeroInit) noexcept: hue{}, saturation{}, value{} {}
/** @brief Construct without initializing the contents */
explicit ColorHsv(NoInitT) noexcept: hue{NoInit} /* and the others not */ {}
/** @brief Constructor */
constexpr /*implicit*/ ColorHsv(Deg<T> hue, T saturation, T value) noexcept: hue{hue}, saturation{saturation}, value{value} {}
/**
* @brief Construct from different type
*
* Performs only default casting on the values, no rounding or
* anything else.
*/
template<class U> constexpr explicit ColorHsv(const ColorHsv<U>& other) noexcept: hue{other.hue}, saturation{T(other.saturation)}, value{T(other.value)} {}
#ifdef MAGNUM_BUILD_DEPRECATED
/**
* @brief Construct from @ref Color3::Hsv
* @deprecated Use @ref ColorHsv instead of @ref Color3::Hsv
*/
constexpr CORRADE_DEPRECATED("use ColorHsv instead of Color3::Hsv") /*implicit*/ ColorHsv(std::tuple<Deg<T>, T, T> hsv) noexcept:
hue{std::get<0>(hsv)}, saturation{std::get<1>(hsv)}, value{std::get<2>(hsv)} {}
/**
* @brief Convert to @ref Color3::Hsv
* @deprecated Use @ref ColorHsv instead of @ref Color3::Hsv
*/
constexpr CORRADE_DEPRECATED("use ColorHsv instead of Color3::Hsv") /*implicit*/ operator std::tuple<Deg<T>, T, T>() const {
return std::make_tuple(hue, saturation, value);
}
/** @overload */ /* for std::tie() */
CORRADE_DEPRECATED("use ColorHsv instead of Color3::Hsv") /*implicit*/ operator std::tuple<Deg<T>&, T&, T&>() {
return std::tuple<Deg<T>&, T&, T&>{hue, saturation, value};
}
/** @overload */ /* for std::tie() */
constexpr CORRADE_DEPRECATED("use ColorHsv instead of Color3::Hsv") /*implicit*/ operator std::tuple<const Deg<T>&, const T&, const T&>() const {
return std::tuple<const Deg<T>&, const T&, const T&>{hue, saturation, value};
}
#endif
/** @brief Equality comparison */
bool operator==(const ColorHsv<T>& other) const {
return hue == other.hue &&
TypeTraits<T>::equals(saturation, other.saturation) &&
TypeTraits<T>::equals(value, other.value);
}
/** @brief Non-equality comparison */
bool operator!=(const ColorHsv<T>& other) const {
return !operator==(other);
}
/** @brief Hue, in range @f$ [0.0, 360.0] @f$ */
Deg<T> hue;
/** @brief Saturation, in range @f$ [0.0, 1.0] @f$ */
T saturation;
/** @brief Value, in range @f$ [0.0, 1.0] @f$ */
T value;
};
#ifndef CORRADE_NO_DEBUG
/** @debugoperator{ColorHsv} */
template<class T> Corrade::Utility::Debug& operator<<(Corrade::Utility::Debug& debug, const ColorHsv<T>& value) {
return debug << "ColorHsv(" << Corrade::Utility::Debug::nospace << value.hue
<< Corrade::Utility::Debug::nospace << "," << value.saturation
<< Corrade::Utility::Debug::nospace << "," << value.value
<< Corrade::Utility::Debug::nospace << ")";
}
/* Explicit instantiation for commonly used types */
#ifndef DOXYGEN_GENERATING_OUTPUT
extern template MAGNUM_EXPORT Corrade::Utility::Debug& operator<<(Corrade::Utility::Debug&, const ColorHsv<Float>&);
#endif
#endif
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
MAGNUM_VECTORn_OPERATOR_IMPLEMENTATION(4, Color4) MAGNUM_VECTORn_OPERATOR_IMPLEMENTATION(4, Color4)
#endif #endif

1
src/Magnum/Math/Math.h

@ -78,6 +78,7 @@ template<class> class Vector2;
template<class> class Vector3; template<class> class Vector3;
template<class> class Vector4; template<class> class Vector4;
template<class> struct ColorHsv;
template<class> class Color3; template<class> class Color3;
template<class> class Color4; template<class> class Color4;

235
src/Magnum/Math/Test/ColorTest.cpp

@ -83,6 +83,13 @@ struct ColorTest: Corrade::TestSuite::Tester {
void constructCopy(); void constructCopy();
void convert(); void convert();
void constructHsv();
void constructHsvDefault();
void constructHsvNoInit();
void constructHsvConversion();
void constructHsvCopy();
void compareHsv();
void data(); void data();
void literals(); void literals();
@ -114,6 +121,7 @@ struct ColorTest: Corrade::TestSuite::Tester {
void swizzleType(); void swizzleType();
void debug(); void debug();
void debugUb(); void debugUb();
void debugHsv();
#if defined(DOXYGEN_GENERATING_OUTPUT) || defined(CORRADE_TARGET_UNIX) || (defined(CORRADE_TARGET_WINDOWS) && !defined(CORRADE_TARGET_WINDOWS_RT)) || defined(CORRADE_TARGET_EMSCRIPTEN) #if defined(DOXYGEN_GENERATING_OUTPUT) || defined(CORRADE_TARGET_UNIX) || (defined(CORRADE_TARGET_WINDOWS) && !defined(CORRADE_TARGET_WINDOWS_RT)) || defined(CORRADE_TARGET_EMSCRIPTEN)
void tweakableRgb(); void tweakableRgb();
@ -144,6 +152,8 @@ typedef Math::Vector4<Float> Vector4;
typedef Math::Color4<Float> Color4; typedef Math::Color4<Float> Color4;
typedef Math::Color4<UnsignedByte> Color4ub; typedef Math::Color4<UnsignedByte> Color4ub;
typedef Math::ColorHsv<Float> ColorHsv;
typedef Math::Deg<Float> Deg; typedef Math::Deg<Float> Deg;
using namespace Literals; using namespace Literals;
@ -193,6 +203,13 @@ ColorTest::ColorTest() {
&ColorTest::constructCopy, &ColorTest::constructCopy,
&ColorTest::convert, &ColorTest::convert,
&ColorTest::constructHsv,
&ColorTest::constructHsvDefault,
&ColorTest::constructHsvNoInit,
&ColorTest::constructHsvConversion,
&ColorTest::constructHsvCopy,
&ColorTest::compareHsv,
&ColorTest::data, &ColorTest::data,
&ColorTest::literals, &ColorTest::literals,
@ -227,7 +244,8 @@ ColorTest::ColorTest() {
&ColorTest::swizzleType, &ColorTest::swizzleType,
&ColorTest::debug, &ColorTest::debug,
&ColorTest::debugUb}); &ColorTest::debugUb,
&ColorTest::debugHsv});
#if defined(DOXYGEN_GENERATING_OUTPUT) || defined(CORRADE_TARGET_UNIX) || (defined(CORRADE_TARGET_WINDOWS) && !defined(CORRADE_TARGET_WINDOWS_RT)) || defined(CORRADE_TARGET_EMSCRIPTEN) #if defined(DOXYGEN_GENERATING_OUTPUT) || defined(CORRADE_TARGET_UNIX) || (defined(CORRADE_TARGET_WINDOWS) && !defined(CORRADE_TARGET_WINDOWS_RT)) || defined(CORRADE_TARGET_EMSCRIPTEN)
addInstancedTests({&ColorTest::tweakableRgb, addInstancedTests({&ColorTest::tweakableRgb,
@ -432,6 +450,89 @@ void ColorTest::convert() {
CORRADE_VERIFY(!(std::is_convertible<Color4, Vec4>::value)); CORRADE_VERIFY(!(std::is_convertible<Color4, Vec4>::value));
} }
void ColorTest::constructHsv() {
ColorHsv a{135.0_degf, 0.5f, 0.9f};
CORRADE_COMPARE(a.hue, 135.0_degf);
CORRADE_COMPARE(a.saturation, 0.5f);
CORRADE_COMPARE(a.value, 0.9f);
constexpr ColorHsv ca{135.0_degf, 0.5f, 0.9f};
constexpr Deg hue = ca.hue;
constexpr Float saturation = ca.saturation;
constexpr Float value = ca.value;
CORRADE_COMPARE(hue, 135.0_degf);
CORRADE_COMPARE(saturation, 0.5f);
CORRADE_COMPARE(value, 0.9f);
CORRADE_VERIFY((std::is_nothrow_constructible<ColorHsv, Deg, Float, Float>::value));
}
void ColorTest::constructHsvDefault() {
ColorHsv a1;
ColorHsv a2{ZeroInit};
CORRADE_COMPARE(a1, (ColorHsv{0.0_degf, 0.0f, 0.0f}));
CORRADE_COMPARE(a2, (ColorHsv{0.0_degf, 0.0f, 0.0f}));
constexpr ColorHsv ca1;
constexpr ColorHsv ca2{ZeroInit};
CORRADE_COMPARE(ca1, (ColorHsv{0.0_degf, 0.0f, 0.0f}));
CORRADE_COMPARE(ca2, (ColorHsv{0.0_degf, 0.0f, 0.0f}));
CORRADE_VERIFY(std::is_nothrow_default_constructible<ColorHsv>::value);
CORRADE_VERIFY((std::is_nothrow_constructible<ColorHsv, ZeroInitT>::value));
}
void ColorTest::constructHsvNoInit() {
ColorHsv a{135.0_degf, 0.5f, 0.9f};
new(&a) ColorHsv{NoInit};
CORRADE_COMPARE(a, (ColorHsv{135.0_degf, 0.5f, 0.9f}));
CORRADE_VERIFY((std::is_nothrow_constructible<ColorHsv, NoInitT>::value));
/* Implicit construction is not allowed */
CORRADE_VERIFY(!(std::is_convertible<NoInitT, ColorHsv>::value));
}
void ColorTest::constructHsvConversion() {
typedef Math::ColorHsv<Double> ColorHsvd;
/* Converting from double to float and not the other way around because
0.9f is 0.899999976158142 */
ColorHsvd a{135.0_deg, 0.5, 0.9};
ColorHsv b{a};
CORRADE_COMPARE(b, (ColorHsv(135.0_degf, 0.5f, 0.9f)));
constexpr ColorHsvd ca{135.0_deg, 0.5, 0.9};
constexpr ColorHsv cb{ca};
CORRADE_COMPARE(cb, (ColorHsv(135.0_degf, 0.5f, 0.9f)));
/* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<ColorHsvd, ColorHsv>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<ColorHsv, ColorHsvd>::value));
}
void ColorTest::constructHsvCopy() {
ColorHsv a{135.0_degf, 0.5f, 0.9f};
ColorHsv b{a};
CORRADE_COMPARE(b, (ColorHsv(135.0_degf, 0.5f, 0.9f)));
constexpr ColorHsv ca{135.0_degf, 0.5f, 0.9f};
constexpr ColorHsv cb{ca};
CORRADE_COMPARE(cb, (ColorHsv(135.0_degf, 0.5f, 0.9f)));
CORRADE_VERIFY(std::is_nothrow_copy_constructible<ColorHsv>::value);
CORRADE_VERIFY(std::is_nothrow_copy_assignable<ColorHsv>::value);
}
void ColorTest::compareHsv() {
CORRADE_VERIFY((ColorHsv{135.0_degf, 0.5f, 0.9f} == ColorHsv{135.0_degf + Deg(TypeTraits<Float>::epsilon()*100.0f), 0.5f, 0.9f}));
CORRADE_VERIFY((ColorHsv{135.0_degf, 0.5f, 0.9f} != ColorHsv{135.0_degf + Deg(TypeTraits<Float>::epsilon()*400.0f), 0.5f, 0.9f}));
CORRADE_VERIFY((ColorHsv{135.0_degf, 0.5f, 0.9f} == ColorHsv{135.0_degf, 0.5f, 0.9f + TypeTraits<Float>::epsilon()*0.5f}));
CORRADE_VERIFY((ColorHsv{135.0_degf, 0.5f, 0.9f} != ColorHsv{135.0_degf, 0.5f, 0.9f + TypeTraits<Float>::epsilon()*2.0f}));
}
void ColorTest::data() { void ColorTest::data() {
Color4 c{1.0f, 2.0f, 3.0f, 4.0f}; Color4 c{1.0f, 2.0f, 3.0f, 4.0f};
constexpr const Color4 cc{1.0f, 2.0f, 3.0f, 4.0f}; constexpr const Color4 cc{1.0f, 2.0f, 3.0f, 4.0f};
@ -514,12 +615,12 @@ void ColorTest::colors() {
} }
void ColorTest::hue() { void ColorTest::hue() {
CORRADE_COMPARE(Color3::fromHsv( 27.0_degf, 1.0f, 1.0f), (Color3{1.0f, 0.45f, 0.0f})); CORRADE_COMPARE(Color3::fromHsv({ 27.0_degf, 1.0f, 1.0f}), (Color3{1.0f, 0.45f, 0.0f}));
CORRADE_COMPARE(Color3::fromHsv( 86.0_degf, 1.0f, 1.0f), (Color3{0.566667f, 1.0f, 0.0f})); CORRADE_COMPARE(Color3::fromHsv({ 86.0_degf, 1.0f, 1.0f}), (Color3{0.566667f, 1.0f, 0.0f}));
CORRADE_COMPARE(Color3::fromHsv(134.0_degf, 1.0f, 1.0f), (Color3{0.0f, 1.0f, 0.233333f})); CORRADE_COMPARE(Color3::fromHsv({134.0_degf, 1.0f, 1.0f}), (Color3{0.0f, 1.0f, 0.233333f}));
CORRADE_COMPARE(Color3::fromHsv(191.0_degf, 1.0f, 1.0f), (Color3{0.0f, 0.816667f, 1.0f})); CORRADE_COMPARE(Color3::fromHsv({191.0_degf, 1.0f, 1.0f}), (Color3{0.0f, 0.816667f, 1.0f}));
CORRADE_COMPARE(Color3::fromHsv(269.0_degf, 1.0f, 1.0f), (Color3{0.483333f, 0.0f, 1.0f})); CORRADE_COMPARE(Color3::fromHsv({269.0_degf, 1.0f, 1.0f}), (Color3{0.483333f, 0.0f, 1.0f}));
CORRADE_COMPARE(Color3::fromHsv(317.0_degf, 1.0f, 1.0f), (Color3{1.0f, 0.0f, 0.716667f})); CORRADE_COMPARE(Color3::fromHsv({317.0_degf, 1.0f, 1.0f}), (Color3{1.0f, 0.0f, 0.716667f}));
CORRADE_COMPARE((Color3{1.0f, 0.45f, 0.0f}).hue(), 27.0_degf); CORRADE_COMPARE((Color3{1.0f, 0.45f, 0.0f}).hue(), 27.0_degf);
CORRADE_COMPARE((Color3{0.566667f, 1.0f, 0.0f}).hue(), 86.0_degf); CORRADE_COMPARE((Color3{0.566667f, 1.0f, 0.0f}).hue(), 86.0_degf);
@ -529,20 +630,20 @@ void ColorTest::hue() {
CORRADE_COMPARE((Color3{1.0f, 0.0f, 0.716667f}).hue(), 317.0_degf); CORRADE_COMPARE((Color3{1.0f, 0.0f, 0.716667f}).hue(), 317.0_degf);
/* RGBA */ /* RGBA */
CORRADE_COMPARE(Color4::fromHsv(27.0_degf, 1.0f, 1.0f, 0.175f), (Color4{1.0f, 0.45f, 0.0f, 0.175f})); CORRADE_COMPARE(Color4::fromHsv({27.0_degf, 1.0f, 1.0f}, 0.175f), (Color4{1.0f, 0.45f, 0.0f, 0.175f}));
CORRADE_COMPARE((Color4{1.0f, 0.45f, 0.0f, 0.175f}).hue(), 27.0_degf); CORRADE_COMPARE((Color4{1.0f, 0.45f, 0.0f, 0.175f}).hue(), 27.0_degf);
/* Integral -- little precision loss */ /* Integral -- little precision loss */
CORRADE_COMPARE(Math::Color3<UnsignedShort>::fromHsv(27.0_degf, 1.0f, 1.0f), CORRADE_COMPARE(Math::Color3<UnsignedShort>::fromHsv({27.0_degf, 1.0f, 1.0f}),
(Math::Color3<UnsignedShort>{65535, 29491, 0})); (Math::Color3<UnsignedShort>{65535, 29491, 0}));
CORRADE_COMPARE(Math::Color4<UnsignedShort>::fromHsv(27.0_degf, 1.0f, 1.0f, 15239), CORRADE_COMPARE(Math::Color4<UnsignedShort>::fromHsv({27.0_degf, 1.0f, 1.0f}, 15239),
(Math::Color4<UnsignedShort>{65535, 29491, 0, 15239})); (Math::Color4<UnsignedShort>{65535, 29491, 0, 15239}));
CORRADE_COMPARE((Math::Color3<UnsignedShort>{65535, 29490, 0}).hue(), 26.9993_degf); CORRADE_COMPARE((Math::Color3<UnsignedShort>{65535, 29490, 0}).hue(), 26.9993_degf);
CORRADE_COMPARE((Math::Color4<UnsignedShort>{65535, 29490, 0, 15239}.hue()), 26.9993_degf); CORRADE_COMPARE((Math::Color4<UnsignedShort>{65535, 29490, 0, 15239}.hue()), 26.9993_degf);
} }
void ColorTest::saturation() { void ColorTest::saturation() {
CORRADE_COMPARE(Color3::fromHsv(0.0_degf, 0.702f, 1.0f), (Color3{1.0f, 0.298f, 0.298f})); CORRADE_COMPARE(Color3::fromHsv({0.0_degf, 0.702f, 1.0f}), (Color3{1.0f, 0.298f, 0.298f}));
CORRADE_COMPARE((Color3{1.0f, 0.298f, 0.298f}).saturation(), 0.702f); CORRADE_COMPARE((Color3{1.0f, 0.298f, 0.298f}).saturation(), 0.702f);
/* Extremes */ /* Extremes */
@ -550,20 +651,20 @@ void ColorTest::saturation() {
CORRADE_COMPARE((Color3{0.0f, 1.0f, 0.0f}).saturation(), 1.0f); CORRADE_COMPARE((Color3{0.0f, 1.0f, 0.0f}).saturation(), 1.0f);
/* RGBA */ /* RGBA */
CORRADE_COMPARE(Color4::fromHsv(0.0_degf, 0.702f, 1.0f, 0.175f), (Color4{1.0f, 0.298f, 0.298f, 0.175f})); CORRADE_COMPARE(Color4::fromHsv({0.0_degf, 0.702f, 1.0f}, 0.175f), (Color4{1.0f, 0.298f, 0.298f, 0.175f}));
CORRADE_COMPARE((Color4{1.0f, 0.298f, 0.298f, 0.175f}).saturation(), 0.702f); CORRADE_COMPARE((Color4{1.0f, 0.298f, 0.298f, 0.175f}).saturation(), 0.702f);
/* Integral -- little precision loss */ /* Integral -- little precision loss */
CORRADE_COMPARE(Math::Color3<UnsignedShort>::fromHsv(0.0_degf, 0.702f, 1.0f), CORRADE_COMPARE(Math::Color3<UnsignedShort>::fromHsv({0.0_degf, 0.702f, 1.0f}),
(Math::Color3<UnsignedShort>{65535, 19529, 19529})); (Math::Color3<UnsignedShort>{65535, 19529, 19529}));
CORRADE_COMPARE(Math::Color4<UnsignedShort>::fromHsv(0.0_degf, 0.702f, 1.0f, 15239), CORRADE_COMPARE(Math::Color4<UnsignedShort>::fromHsv({0.0_degf, 0.702f, 1.0f}, 15239),
(Math::Color4<UnsignedShort>{65535, 19529, 19529, 15239})); (Math::Color4<UnsignedShort>{65535, 19529, 19529, 15239}));
CORRADE_COMPARE((Math::Color3<UnsignedShort>{65535, 19529, 19529}.saturation()), 0.702007f); CORRADE_COMPARE((Math::Color3<UnsignedShort>{65535, 19529, 19529}.saturation()), 0.702007f);
CORRADE_COMPARE((Math::Color4<UnsignedShort>{65535, 19529, 19529, 15239}.saturation()), 0.702007f); CORRADE_COMPARE((Math::Color4<UnsignedShort>{65535, 19529, 19529, 15239}.saturation()), 0.702007f);
} }
void ColorTest::value() { void ColorTest::value() {
CORRADE_COMPARE(Color3::fromHsv(0.0_degf, 1.0f, 0.522f), (Color3{0.522f, 0.0f, 0.0f})); CORRADE_COMPARE(Color3::fromHsv({0.0_degf, 1.0f, 0.522f}), (Color3{0.522f, 0.0f, 0.0f}));
CORRADE_COMPARE((Color3{0.522f, 0.0f, 0.0f}).value(), 0.522f); CORRADE_COMPARE((Color3{0.522f, 0.0f, 0.0f}).value(), 0.522f);
/* Extremes */ /* Extremes */
@ -571,95 +672,81 @@ void ColorTest::value() {
CORRADE_COMPARE((Color3{0.0f, 1.0f, 0.0f}).value(), 1.0f); CORRADE_COMPARE((Color3{0.0f, 1.0f, 0.0f}).value(), 1.0f);
/* RGBA */ /* RGBA */
CORRADE_COMPARE(Color4::fromHsv(0.0_degf, 1.0f, 0.522f, 0.175f), (Color4{0.522f, 0.0f, 0.0f, 0.175f})); CORRADE_COMPARE(Color4::fromHsv({0.0_degf, 1.0f, 0.522f}, 0.175f), (Color4{0.522f, 0.0f, 0.0f, 0.175f}));
CORRADE_COMPARE((Color4{0.522f, 0.0f, 0.0f, 0.175f}).value(), 0.522f); CORRADE_COMPARE((Color4{0.522f, 0.0f, 0.0f, 0.175f}).value(), 0.522f);
/* Integral -- little precision loss */ /* Integral -- little precision loss */
CORRADE_COMPARE(Math::Color3<UnsignedShort>::fromHsv(0.0_degf, 1.0f, 0.522f), CORRADE_COMPARE(Math::Color3<UnsignedShort>::fromHsv({0.0_degf, 1.0f, 0.522f}),
(Math::Color3<UnsignedShort>{34209, 0, 0})); (Math::Color3<UnsignedShort>{34209, 0, 0}));
CORRADE_COMPARE(Math::Color4<UnsignedShort>::fromHsv(0.0_degf, 1.0f, 0.522f, 15239), CORRADE_COMPARE(Math::Color4<UnsignedShort>::fromHsv({0.0_degf, 1.0f, 0.522f}, 15239),
(Math::Color4<UnsignedShort>{34209, 0, 0, 15239})); (Math::Color4<UnsignedShort>{34209, 0, 0, 15239}));
CORRADE_COMPARE((Math::Color3<UnsignedShort>{34209, 0, 0}.value()), 0.521996f); CORRADE_COMPARE((Math::Color3<UnsignedShort>{34209, 0, 0}.value()), 0.521996f);
CORRADE_COMPARE((Math::Color4<UnsignedShort>{34209, 0, 0, 15239}.value()), 0.521996f); CORRADE_COMPARE((Math::Color4<UnsignedShort>{34209, 0, 0, 15239}.value()), 0.521996f);
} }
void ColorTest::hsv() { void ColorTest::hsv() {
CORRADE_COMPARE(Color3::fromHsv(std::make_tuple(230.0_degf, 0.749f, 0.427f)), CORRADE_COMPARE(Color3::fromHsv({230.0_degf, 0.749f, 0.427f}),
(Color3{0.107177f, 0.160481f, 0.427f}));
CORRADE_COMPARE(Color3::fromHsv(230.0_degf, 0.749f, 0.427f),
(Color3{0.107177f, 0.160481f, 0.427f})); (Color3{0.107177f, 0.160481f, 0.427f}));
Deg hue; ColorHsv hsv = Color3{0.107177f, 0.160481f, 0.427f}.toHsv();
Float saturation, value; CORRADE_COMPARE(hsv.hue, 230.0_degf);
std::tie(hue, saturation, value) = Color3{0.107177f, 0.160481f, 0.427f}.toHsv(); CORRADE_COMPARE(hsv.saturation, 0.749f);
CORRADE_COMPARE(hue, 230.0_degf); CORRADE_COMPARE(hsv.value, 0.427f);
CORRADE_COMPARE(saturation, 0.749f);
CORRADE_COMPARE(value, 0.427f);
/* RGBA */ /* RGBA */
CORRADE_COMPARE(Color4::fromHsv(std::make_tuple(230.0_degf, 0.749f, 0.427f), 0.175f), CORRADE_COMPARE(Color4::fromHsv({230.0_degf, 0.749f, 0.427f}, 0.175f),
(Color4{0.107177f, 0.160481f, 0.427f, 0.175f}));
CORRADE_COMPARE(Color4::fromHsv(230.0_degf, 0.749f, 0.427f, 0.175f),
(Color4{0.107177f, 0.160481f, 0.427f, 0.175f})); (Color4{0.107177f, 0.160481f, 0.427f, 0.175f}));
std::tie(hue, saturation, value) = Color4{0.107177f, 0.160481f, 0.427f, 0.175f}.toHsv(); hsv = Color4{0.107177f, 0.160481f, 0.427f, 0.175f}.toHsv();
CORRADE_COMPARE(hue, 230.0_degf); CORRADE_COMPARE(hsv.hue, 230.0_degf);
CORRADE_COMPARE(saturation, 0.749f); CORRADE_COMPARE(hsv.saturation, 0.749f);
CORRADE_COMPARE(value, 0.427f); CORRADE_COMPARE(hsv.value, 0.427f);
/* Integral -- little precision loss */ /* Integral -- little precision loss */
CORRADE_COMPARE(Math::Color3<UnsignedShort>::fromHsv(std::make_tuple(230.0_degf, 0.749f, 0.427f)), CORRADE_COMPARE(Math::Color3<UnsignedShort>::fromHsv({230.0_degf, 0.749f, 0.427f}),
(Math::Color3<UnsignedShort>{7024, 10517, 27983}));
CORRADE_COMPARE(Math::Color3<UnsignedShort>::fromHsv(230.0_degf, 0.749f, 0.427f),
(Math::Color3<UnsignedShort>{7024, 10517, 27983})); (Math::Color3<UnsignedShort>{7024, 10517, 27983}));
CORRADE_COMPARE(Math::Color4<UnsignedShort>::fromHsv(std::make_tuple(230.0_degf, 0.749f, 0.427f), 15239), CORRADE_COMPARE(Math::Color4<UnsignedShort>::fromHsv({230.0_degf, 0.749f, 0.427f}, 15239),
(Math::Color4<UnsignedShort>{7024, 10517, 27983, 15239}));
CORRADE_COMPARE(Math::Color4<UnsignedShort>::fromHsv(230.0_degf, 0.749f, 0.427f, 15239),
(Math::Color4<UnsignedShort>{7024, 10517, 27983, 15239})); (Math::Color4<UnsignedShort>{7024, 10517, 27983, 15239}));
std::tie(hue, saturation, value) = Math::Color3<UnsignedShort>{7023, 10517, 27983}.toHsv(); hsv = Math::Color3<UnsignedShort>{7023, 10517, 27983}.toHsv();
CORRADE_COMPARE(hue, 230.0_degf); CORRADE_COMPARE(hsv.hue, 230.0_degf);
CORRADE_COMPARE(saturation, 0.749026f); CORRADE_COMPARE(hsv.saturation, 0.749026f);
CORRADE_COMPARE(value, 0.426993f); CORRADE_COMPARE(hsv.value, 0.426993f);
std::tie(hue, saturation, value) = Math::Color4<UnsignedShort>{7023, 10517, 27983, 15239}.toHsv(); hsv = Math::Color4<UnsignedShort>{7023, 10517, 27983, 15239}.toHsv();
CORRADE_COMPARE(hue, 230.0_degf); CORRADE_COMPARE(hsv.hue, 230.0_degf);
CORRADE_COMPARE(saturation, 0.749026f); CORRADE_COMPARE(hsv.saturation, 0.749026f);
CORRADE_COMPARE(value, 0.426993f); CORRADE_COMPARE(hsv.value, 0.426993f);
/* Round-trip */ /* Round-trip */
CORRADE_COMPARE(Color3::fromHsv(230.0_degf, 0.749f, 0.427f).toHsv(), CORRADE_COMPARE(Color3::fromHsv({230.0_degf, 0.749f, 0.427f}).toHsv(),
std::make_tuple(230.0_degf, 0.749f, 0.427f)); (ColorHsv{230.0_degf, 0.749f, 0.427f}));
CORRADE_COMPARE(Color4::fromHsv(230.0_degf, 0.749f, 0.427f, 0.175f).toHsv(), CORRADE_COMPARE(Color4::fromHsv({230.0_degf, 0.749f, 0.427f}, 0.175f).toHsv(),
std::make_tuple(230.0_degf, 0.749f, 0.427f)); (ColorHsv{230.0_degf, 0.749f, 0.427f}));
} }
void ColorTest::fromHsvHueOverflow() { void ColorTest::fromHsvHueOverflow() {
CORRADE_COMPARE(Color3::fromHsv( 27.0_degf - 360.0_degf, 1.0f, 1.0f), (Color3{1.0f, 0.45f, 0.0f})); CORRADE_COMPARE(Color3::fromHsv({ 27.0_degf - 360.0_degf, 1.0f, 1.0f}), (Color3{1.0f, 0.45f, 0.0f}));
CORRADE_COMPARE(Color3::fromHsv( 86.0_degf - 360.0_degf, 1.0f, 1.0f), (Color3{0.566667f, 1.0f, 0.0f})); CORRADE_COMPARE(Color3::fromHsv({ 86.0_degf - 360.0_degf, 1.0f, 1.0f}), (Color3{0.566667f, 1.0f, 0.0f}));
CORRADE_COMPARE(Color3::fromHsv(134.0_degf - 360.0_degf, 1.0f, 1.0f), (Color3{0.0f, 1.0f, 0.233333f})); CORRADE_COMPARE(Color3::fromHsv({134.0_degf - 360.0_degf, 1.0f, 1.0f}), (Color3{0.0f, 1.0f, 0.233333f}));
CORRADE_COMPARE(Color3::fromHsv(191.0_degf - 360.0_degf, 1.0f, 1.0f), (Color3{0.0f, 0.816667f, 1.0f})); CORRADE_COMPARE(Color3::fromHsv({191.0_degf - 360.0_degf, 1.0f, 1.0f}), (Color3{0.0f, 0.816667f, 1.0f}));
CORRADE_COMPARE(Color3::fromHsv(269.0_degf - 360.0_degf, 1.0f, 1.0f), (Color3{0.483333f, 0.0f, 1.0f})); CORRADE_COMPARE(Color3::fromHsv({269.0_degf - 360.0_degf, 1.0f, 1.0f}), (Color3{0.483333f, 0.0f, 1.0f}));
CORRADE_COMPARE(Color3::fromHsv(317.0_degf - 360.0_degf, 1.0f, 1.0f), (Color3{1.0f, 0.0f, 0.716667f})); CORRADE_COMPARE(Color3::fromHsv({317.0_degf - 360.0_degf, 1.0f, 1.0f}), (Color3{1.0f, 0.0f, 0.716667f}));
CORRADE_COMPARE(Color3::fromHsv( 27.0_degf + 360.0_degf, 1.0f, 1.0f), (Color3{1.0f, 0.45f, 0.0f})); CORRADE_COMPARE(Color3::fromHsv({ 27.0_degf + 360.0_degf, 1.0f, 1.0f}), (Color3{1.0f, 0.45f, 0.0f}));
CORRADE_COMPARE(Color3::fromHsv( 86.0_degf + 360.0_degf, 1.0f, 1.0f), (Color3{0.566667f, 1.0f, 0.0f})); CORRADE_COMPARE(Color3::fromHsv({ 86.0_degf + 360.0_degf, 1.0f, 1.0f}), (Color3{0.566667f, 1.0f, 0.0f}));
CORRADE_COMPARE(Color3::fromHsv(134.0_degf + 360.0_degf, 1.0f, 1.0f), (Color3{0.0f, 1.0f, 0.233333f})); CORRADE_COMPARE(Color3::fromHsv({134.0_degf + 360.0_degf, 1.0f, 1.0f}), (Color3{0.0f, 1.0f, 0.233333f}));
CORRADE_COMPARE(Color3::fromHsv(191.0_degf + 360.0_degf, 1.0f, 1.0f), (Color3{0.0f, 0.816667f, 1.0f})); CORRADE_COMPARE(Color3::fromHsv({191.0_degf + 360.0_degf, 1.0f, 1.0f}), (Color3{0.0f, 0.816667f, 1.0f}));
CORRADE_COMPARE(Color3::fromHsv(269.0_degf + 360.0_degf, 1.0f, 1.0f), (Color3{0.483333f, 0.0f, 1.0f})); CORRADE_COMPARE(Color3::fromHsv({269.0_degf + 360.0_degf, 1.0f, 1.0f}), (Color3{0.483333f, 0.0f, 1.0f}));
CORRADE_COMPARE(Color3::fromHsv(317.0_degf + 360.0_degf, 1.0f, 1.0f), (Color3{1.0f, 0.0f, 0.716667f})); CORRADE_COMPARE(Color3::fromHsv({317.0_degf + 360.0_degf, 1.0f, 1.0f}), (Color3{1.0f, 0.0f, 0.716667f}));
} }
void ColorTest::fromHsvDefaultAlpha() { void ColorTest::fromHsvDefaultAlpha() {
CORRADE_COMPARE(Color4::fromHsv(std::make_tuple(230.0_degf, 0.749f, 0.427f)), CORRADE_COMPARE(Color4::fromHsv({230.0_degf, 0.749f, 0.427f}),
(Color4{0.107177f, 0.160481f, 0.427f, 1.0f}));
CORRADE_COMPARE(Color4::fromHsv(230.0_degf, 0.749f, 0.427f),
(Color4{0.107177f, 0.160481f, 0.427f, 1.0f})); (Color4{0.107177f, 0.160481f, 0.427f, 1.0f}));
/* Integral */ /* Integral */
CORRADE_COMPARE(Math::Color4<UnsignedShort>::fromHsv(std::make_tuple(230.0_degf, 0.749f, 0.427f)), CORRADE_COMPARE(Math::Color4<UnsignedShort>::fromHsv({230.0_degf, 0.749f, 0.427f}),
(Math::Color4<UnsignedShort>{7024, 10517, 27983, 65535}));
CORRADE_COMPARE(Math::Color4<UnsignedShort>::fromHsv(230.0_degf, 0.749f, 0.427f),
(Math::Color4<UnsignedShort>{7024, 10517, 27983, 65535})); (Math::Color4<UnsignedShort>{7024, 10517, 27983, 65535}));
} }
@ -924,6 +1011,12 @@ void ColorTest::debugUb() {
CORRADE_COMPARE(o.str(), "#12345678 #90abcdef\n"); CORRADE_COMPARE(o.str(), "#12345678 #90abcdef\n");
} }
void ColorTest::debugHsv() {
std::ostringstream out;
Debug{&out} << ColorHsv(135.0_degf, 0.75f, 0.3f);
CORRADE_COMPARE(out.str(), "ColorHsv(Deg(135), 0.75, 0.3)\n");
}
#if defined(DOXYGEN_GENERATING_OUTPUT) || defined(CORRADE_TARGET_UNIX) || (defined(CORRADE_TARGET_WINDOWS) && !defined(CORRADE_TARGET_WINDOWS_RT)) || defined(CORRADE_TARGET_EMSCRIPTEN) #if defined(DOXYGEN_GENERATING_OUTPUT) || defined(CORRADE_TARGET_UNIX) || (defined(CORRADE_TARGET_WINDOWS) && !defined(CORRADE_TARGET_WINDOWS_RT)) || defined(CORRADE_TARGET_EMSCRIPTEN)
void ColorTest::tweakableRgb() { void ColorTest::tweakableRgb() {
auto&& data = TweakableData[testCaseInstanceId()]; auto&& data = TweakableData[testCaseInstanceId()];

2
src/Magnum/Math/instantiation.cpp

@ -126,6 +126,8 @@ template Corrade::Utility::Debug& operator<<(Corrade::Utility::Debug&, const Dua
template Corrade::Utility::Debug& operator<<(Corrade::Utility::Debug&, const Quaternion<Float>&); template Corrade::Utility::Debug& operator<<(Corrade::Utility::Debug&, const Quaternion<Float>&);
template Corrade::Utility::Debug& operator<<(Corrade::Utility::Debug&, const Quaternion<Double>&); template Corrade::Utility::Debug& operator<<(Corrade::Utility::Debug&, const Quaternion<Double>&);
template Corrade::Utility::Debug& operator<<(Corrade::Utility::Debug&, const ColorHsv<Float>&);
/* Check proper size of GL types */ /* Check proper size of GL types */
static_assert(sizeof(Vector<2, Float>) == 8, "Improper size of 2-element Float vector"); static_assert(sizeof(Vector<2, Float>) == 8, "Improper size of 2-element Float vector");
static_assert(sizeof(Vector<3, Float>) == 12, "Improper size of 3-element Float vector"); static_assert(sizeof(Vector<3, Float>) == 12, "Improper size of 3-element Float vector");

Loading…
Cancel
Save