Browse Source

Math: allow creating a Vector from a BitVector.

And document the more flexible alternative using lerp().
pull/638/head
Vladimír Vondruš 2 years ago
parent
commit
279856f239
  1. 8
      doc/snippets/Math.cpp
  2. 6
      src/Magnum/Math/Color.h
  3. 1
      src/Magnum/Math/Functions.h
  4. 23
      src/Magnum/Math/Test/ColorTest.cpp
  5. 16
      src/Magnum/Math/Test/Vector2Test.cpp
  6. 16
      src/Magnum/Math/Test/Vector3Test.cpp
  7. 16
      src/Magnum/Math/Test/Vector4Test.cpp
  8. 16
      src/Magnum/Math/Test/VectorTest.cpp
  9. 17
      src/Magnum/Math/Vector.h
  10. 3
      src/Magnum/Math/Vector2.h
  11. 3
      src/Magnum/Math/Vector3.h
  12. 4
      src/Magnum/Math/Vector4.h

8
doc/snippets/Math.cpp

@ -1346,6 +1346,14 @@ Vector4i integral{floatingPoint}; // {1, 2, -15, 7}
/* [Vector-conversion] */
}
{
/* [Vector-conversion-bit] */
BitVector3 mask = DOXYGEN_ELLIPSIS({});
Vector3ub a = Math::lerp(Vector3ub{0}, Vector3ub{255}, mask);
/* [Vector-conversion-bit] */
static_cast<void>(a);
}
{
/* [Vector-length-integer] */
Vector2i a{25, -1};

6
src/Magnum/Math/Color.h

@ -571,6 +571,9 @@ template<class T> class Color3: public Vector3<T> {
*/
template<class U> constexpr explicit Color3(const Vector<3, U>& other) noexcept: Vector3<T>(other) {}
/** @copydoc Vector::Vector(const BitVector<size>&) */
constexpr explicit Color3(const BitVector3& other) noexcept: Vector3<T>{other} {}
/** @brief Construct color from external representation */
template<class U, class V =
#ifndef CORRADE_MSVC2015_COMPATIBILITY /* Causes ICE */
@ -1056,6 +1059,9 @@ class Color4: public Vector4<T> {
*/
template<class U> constexpr explicit Color4(const Vector<4, U>& other) noexcept: Vector4<T>(other) {}
/** @copydoc Vector::Vector(const BitVector<size>&) */
constexpr explicit Color4(const BitVector4& other) noexcept: Vector4<T>{other} {}
/** @brief Construct color from external representation */
template<class U, class V =
#ifndef CORRADE_MSVC2015_COMPATIBILITY /* Causes ICE */

1
src/Magnum/Math/Functions.h

@ -545,6 +545,7 @@ template<class T> inline T lerp(const T& a, const T& b, bool t) {
Similar to the above, but instead of multiplication and addition it just does
component-wise selection from either @p a or @p b based on values in @p t.
@m_keyword{mix(),GLSL mix(),}
@see @ref Vector::Vector(const BitVector<size>&)
*/
template<std::size_t size, class T> inline Vector<size, T> lerp(const Vector<size, T>& a, const Vector<size, T>& b, const BitVector<size>& t) {
Vector<size, T> out{Magnum::NoInit};

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

@ -84,6 +84,7 @@ struct ColorTest: TestSuite::Tester {
void constructOneValue();
void constructParts();
void constructConversion();
void constructBit();
void constructPacking();
void constructCopy();
void convert();
@ -212,6 +213,7 @@ ColorTest::ColorTest() {
&ColorTest::constructOneValue,
&ColorTest::constructParts,
&ColorTest::constructConversion,
&ColorTest::constructBit,
&ColorTest::constructPacking,
&ColorTest::constructCopy,
&ColorTest::convert,
@ -426,6 +428,27 @@ void ColorTest::constructConversion() {
CORRADE_VERIFY(std::is_nothrow_constructible<Color4, Color4ub>::value);
}
void ColorTest::constructBit() {
BitVector3 a3{'\x5'}; /* 0b101 */
BitVector4 a4{'\xa'}; /* 0b1010 */
CORRADE_COMPARE(Color3{a3}, (Color3{1.0f, 0.0f, 1.0f}));
CORRADE_COMPARE(Color4ub{a4}, (Color4ub{0, 1, 0, 1}));
constexpr BitVector3 ca3{'\x5'}; /* 0b101 */
constexpr BitVector4 ca4{'\xa'}; /* 0b1010 */
constexpr Color3 cb3{ca3};
constexpr Color4ub cb4{ca4};
CORRADE_COMPARE(cb3, (Color3{1.0f, 0.0f, 1.0f}));
CORRADE_COMPARE(cb4, (Color4ub{0, 1, 0, 1}));
/* Implicit conversion is not allowed */
CORRADE_VERIFY(!std::is_convertible<BitVector3, Color3>::value);
CORRADE_VERIFY(!std::is_convertible<BitVector4, Color4>::value);
CORRADE_VERIFY(std::is_nothrow_constructible<Color3, BitVector3>::value);
CORRADE_VERIFY(std::is_nothrow_constructible<Color4, BitVector4>::value);
}
void ColorTest::constructPacking() {
constexpr Color3 a(1.0f, 0.5f, 0.75f);
auto b = Math::pack<Color3ub>(a);

16
src/Magnum/Math/Test/Vector2Test.cpp

@ -61,6 +61,7 @@ struct Vector2Test: TestSuite::Tester {
void constructNoInit();
void constructOneValue();
void constructConversion();
void constructBit();
void constructCopy();
void convert();
@ -87,6 +88,7 @@ Vector2Test::Vector2Test() {
&Vector2Test::constructNoInit,
&Vector2Test::constructOneValue,
&Vector2Test::constructConversion,
&Vector2Test::constructBit,
&Vector2Test::constructCopy,
&Vector2Test::convert,
@ -165,6 +167,20 @@ void Vector2Test::constructConversion() {
CORRADE_VERIFY(std::is_nothrow_constructible<Vector2, Vector2i>::value);
}
void Vector2Test::constructBit() {
BitVector2 a{'\x1'}; /* 0b01 */
CORRADE_COMPARE(Vector2{a}, (Vector2{1.0f, 0.0f}));
constexpr BitVector2 ca{'\x1'}; /* 0b01 */
constexpr Vector2 cb{ca};
CORRADE_COMPARE(cb, (Vector2{1.0f, 0.0f}));
/* Implicit conversion is not allowed */
CORRADE_VERIFY(!std::is_convertible<BitVector2, Vector2>::value);
CORRADE_VERIFY(std::is_nothrow_constructible<Vector2, BitVector2>::value);
}
void Vector2Test::constructCopy() {
constexpr Vector<2, Float> a(1.5f, 2.5f);
#ifndef CORRADE_MSVC2015_COMPATIBILITY /* Why can't be copy constexpr? */

16
src/Magnum/Math/Test/Vector3Test.cpp

@ -62,6 +62,7 @@ struct Vector3Test: TestSuite::Tester {
void constructOneValue();
void constructParts();
void constructConversion();
void constructBit();
void constructCopy();
void convert();
@ -89,6 +90,7 @@ Vector3Test::Vector3Test() {
&Vector3Test::constructOneValue,
&Vector3Test::constructParts,
&Vector3Test::constructConversion,
&Vector3Test::constructBit,
&Vector3Test::constructCopy,
&Vector3Test::convert,
@ -174,6 +176,20 @@ void Vector3Test::constructConversion() {
CORRADE_VERIFY(std::is_nothrow_constructible<Vector3, Vector3i>::value);
}
void Vector3Test::constructBit() {
BitVector3 a{'\x5'}; /* 0b101 */
CORRADE_COMPARE(Vector3{a}, (Vector3{1.0f, 0.0f, 1.0f}));
constexpr BitVector3 ca{'\x5'}; /* 0b101 */
constexpr Vector3 cb{ca};
CORRADE_COMPARE(cb, (Vector3{1.0f, 0.0f, 1.0f}));
/* Implicit conversion is not allowed */
CORRADE_VERIFY(!std::is_convertible<BitVector3, Vector3>::value);
CORRADE_VERIFY(std::is_nothrow_constructible<Vector3, BitVector3>::value);
}
void Vector3Test::constructCopy() {
constexpr Vector<3, Float> a(1.0f, 2.5f, -3.0f);
#ifndef CORRADE_MSVC2015_COMPATIBILITY /* Why can't be copy constexpr? */

16
src/Magnum/Math/Test/Vector4Test.cpp

@ -63,6 +63,7 @@ struct Vector4Test: TestSuite::Tester {
void constructOneValue();
void constructParts();
void constructConversion();
void constructBit();
void constructCopy();
void convert();
@ -93,6 +94,7 @@ Vector4Test::Vector4Test() {
&Vector4Test::constructOneValue,
&Vector4Test::constructParts,
&Vector4Test::constructConversion,
&Vector4Test::constructBit,
&Vector4Test::constructCopy,
&Vector4Test::convert,
@ -195,6 +197,20 @@ void Vector4Test::constructConversion() {
CORRADE_VERIFY(std::is_nothrow_constructible<Vector4, Vector4i>::value);
}
void Vector4Test::constructBit() {
BitVector4 a{'\xa'}; /* 0b1010 */
CORRADE_COMPARE(Vector4{a}, (Vector4{0.0f, 1.0f, 0.0f, 1.0f}));
constexpr BitVector4 ca{'\xa'}; /* 0b1010 */
constexpr Vector4 cb{ca};
CORRADE_COMPARE(cb, (Vector4{0.0f, 1.0f, 0.0f, 1.0f}));
/* Implicit conversion is not allowed */
CORRADE_VERIFY(!std::is_convertible<BitVector4, Vector4>::value);
CORRADE_VERIFY(std::is_nothrow_constructible<Vector4, BitVector4>::value);
}
void Vector4Test::constructCopy() {
constexpr Vector<4, Float> a(1.0f, -2.5f, 3.0f, 4.1f);
#ifndef CORRADE_MSVC2015_COMPATIBILITY /* Why can't be copy constexpr? */

16
src/Magnum/Math/Test/VectorTest.cpp

@ -66,6 +66,7 @@ struct VectorTest: TestSuite::Tester {
void constructOneValue();
void constructOneComponent();
void constructConversion();
void constructBit();
void constructCopy();
void convert();
@ -144,6 +145,7 @@ VectorTest::VectorTest() {
&VectorTest::constructOneValue,
&VectorTest::constructOneComponent,
&VectorTest::constructConversion,
&VectorTest::constructBit,
&VectorTest::constructCopy,
&VectorTest::convert,
@ -294,6 +296,20 @@ void VectorTest::constructConversion() {
CORRADE_VERIFY(std::is_nothrow_constructible<Vector4, Vector4i>::value);
}
void VectorTest::constructBit() {
BitVector4 a{'\xa'}; /* 0b1010 */
CORRADE_COMPARE(Vector4{a}, (Vector4{0.0f, 1.0f, 0.0f, 1.0f}));
constexpr BitVector4 ca{'\xa'}; /* 0b1010 */
constexpr Vector4 cb{ca};
CORRADE_COMPARE(cb, (Vector4{0.0f, 1.0f, 0.0f, 1.0f}));
/* Implicit conversion is not allowed */
CORRADE_VERIFY(!std::is_convertible<BitVector4, Vector4>::value);
CORRADE_VERIFY(std::is_nothrow_constructible<Vector4, BitVector4>::value);
}
void VectorTest::constructCopy() {
constexpr Vector4 a(1.0f, 3.5f, 4.0f, -2.7f);
constexpr Vector4 b(a);

17
src/Magnum/Math/Vector.h

@ -235,6 +235,20 @@ template<std::size_t size, class T> class Vector {
*/
template<class U> constexpr explicit Vector(const Vector<size, U>& other) noexcept: Vector(typename Containers::Implementation::GenerateSequence<size>::Type{}, other) {}
/**
* @brief Construct a vector from a BitVector
* @m_since_latest
*
* Bits that are unset are converted to @cpp 0 @ce, set bits to
* @cpp 1 @ce. If you need a different behavior, for example converting
* a bit mask to @cpp 0 @ce or @cpp 255 @ce for a color representation,
* use @ref lerp(const Vector<size, T>&, const Vector<size, T>&, const BitVector<size>&)
* instead, for example:
*
* @snippet Math.cpp Vector-conversion-bit
*/
constexpr explicit Vector(const BitVector<size>& other) noexcept: Vector{typename Containers::Implementation::GenerateSequence<size>::Type{}, other} {}
/** @brief Construct a vector from external representation */
template<class U, class V = decltype(Implementation::VectorConverter<size, T, U>::from(std::declval<U>()))> constexpr explicit Vector(const U& other) noexcept: Vector(Implementation::VectorConverter<size, T, U>::from(other)) {}
@ -1252,6 +1266,9 @@ template<std::size_t size, class T> class Vector {
/* Implementation for Vector<size, T>::Vector(const Vector<size, U>&) */
template<class U, std::size_t ...sequence> constexpr explicit Vector(Containers::Implementation::Sequence<sequence...>, const Vector<size, U>& vector) noexcept: _data{T(vector._data[sequence])...} {}
/* Implementation for Vector<size, T>::Vector(const BitVector<size>&) */
template<std::size_t ...sequence> constexpr explicit Vector(Containers::Implementation::Sequence<sequence...>, const BitVector<size>& bitVector) noexcept: _data{T(bitVector[sequence])...} {}
/* Implementation for Vector<size, T>::Vector(U) */
template<std::size_t ...sequence> constexpr explicit Vector(Containers::Implementation::Sequence<sequence...>, T value) noexcept: _data{Implementation::repeat(value, sequence)...} {}

3
src/Magnum/Math/Vector2.h

@ -140,6 +140,9 @@ template<class T> class Vector2: public Vector<2, T> {
/** @copydoc Vector::Vector(const Vector<size, U>&) */
template<class U> constexpr explicit Vector2(const Vector<2, U>& other) noexcept: Vector<2, T>(other) {}
/** @copydoc Vector::Vector(const BitVector<size>&) */
constexpr explicit Vector2(const BitVector2& other) noexcept: Vector<2, T>{other} {}
/** @brief Construct a vector from external representation */
template<class U, class V =
#ifndef CORRADE_MSVC2015_COMPATIBILITY /* Causes ICE */

3
src/Magnum/Math/Vector3.h

@ -168,6 +168,9 @@ template<class T> class Vector3: public Vector<3, T> {
/** @copydoc Vector::Vector(const Vector<size, U>&) */
template<class U> constexpr explicit Vector3(const Vector<3, U>& other) noexcept: Vector<3, T>(other) {}
/** @copydoc Vector::Vector(const BitVector<size>&) */
constexpr explicit Vector3(const BitVector3& other) noexcept: Vector<3, T>{other} {}
/** @brief Construct a vector from external representation */
template<class U, class V =
#ifndef CORRADE_MSVC2015_COMPATIBILITY /* Causes ICE */

4
src/Magnum/Math/Vector4.h

@ -113,6 +113,10 @@ template<class T> class Vector4: public Vector<4, T> {
fire! FFS. */
template<class U> constexpr explicit Vector4(const Vector<4, U>& other) noexcept: Vector<4, T>(other) {}
/** @copydoc Magnum::Math::Vector::Vector(const BitVector<size>&) */
/* Lol and here too */
constexpr explicit Vector4(const BitVector4& other) noexcept: Vector<4, T>{other} {}
/** @brief Construct a vector from external representation */
template<class U, class V = decltype(Implementation::VectorConverter<4, T, U>::from(std::declval<U>()))> constexpr explicit Vector4(const U& other): Vector<4, T>(Implementation::VectorConverter<4, T, U>::from(other)) {}

Loading…
Cancel
Save