Browse Source

Math: add Quaternion::xyzw() and wxyz().

pull/659/head
Vladimír Vondruš 1 year ago
parent
commit
8f05ef141c
  1. 2
      doc/changelog.dox
  2. 3
      src/Magnum/Math/Complex.h
  3. 38
      src/Magnum/Math/Quaternion.h
  4. 25
      src/Magnum/Math/Test/QuaternionTest.cpp

2
doc/changelog.dox

@ -285,6 +285,8 @@ See also:
@ref Math::Quaternion::reflectVector(), but mainly just for documentation
purposes as reflections cannot be combined with rotations and thus are
mostly useless in practice
- Added @ref Math::Quaternion::xyzw() and @ref Math::Quaternion::wxyz()
helpers for converting to a @ref Vector4 in chosen component order
- New @ref Magnum/Math/ColorBatch.h header with utilities for performing Y
flip of various block-compressed formats
- New @ref Math::Nanoseconds and @ref Math::Seconds classes for strongly

3
src/Magnum/Math/Complex.h

@ -257,7 +257,8 @@ template<class T> class Complex {
* @f[
* \boldsymbol v = \begin{pmatrix} a \\ b \end{pmatrix}
* @f]
* @see @ref Complex(const Vector2<T>&)
* @see @ref Complex(const Vector2<T>&), @ref Quaternion::xyzw(),
* @ref Quaternion::wxyz()
*/
constexpr explicit operator Vector2<T>() const {
return {_real, _imaginary};

38
src/Magnum/Math/Quaternion.h

@ -469,16 +469,50 @@ template<class T> class Quaternion {
return Implementation::isNormalizedSquared(dot());
}
/** @brief Vector part (@f$ \boldsymbol{q}_V @f$) */
/**
* @brief Vector part (@f$ \boldsymbol{q}_V @f$)
*
* @see @ref xyzw(), @ref wxyz()
*/
Vector3<T>& vector() { return _vector; }
/* Returning const so it's possible to call constexpr functions on the
result. WTF, C++?! */
constexpr const Vector3<T> vector() const { return _vector; } /**< @overload */
/** @brief Scalar part (@f$ q_S @f$) */
/**
* @brief Scalar part (@f$ q_S @f$)
*
* @see @ref xyzw(), @ref wxyz()
*/
T& scalar() { return _scalar; }
constexpr T scalar() const { return _scalar; } /**< @overload */
/**
* @brief Quaternion components in a XYZW order
* @m_since_latest
*
* Returns a four-component vector containing @ref vector() in the XYZ
* components and @ref scalar() in W: @f[
* v = [q_{V_x}, q_{V_y}, q_{V_z}, s]
* @f]
* @see @ref Complex::operator Vector2<T>()
*/
constexpr Vector4<T> xyzw() const { return {_vector, _scalar}; }
/**
* @brief Quaternion components in a WXYZ order
* @m_since_latest
*
* Returns a four-component vector containing @ref scalar() in the X
* component and @ref vector() in YZW: @f[
* v = [s, q_{V_x}, q_{V_y}, q_{V_z}]
* @f]
* @see @ref Complex::operator Vector2<T>()
*/
constexpr Vector4<T> wxyz() const {
return {_scalar, _vector.x(), _vector.y(), _vector.z()};
}
/**
* @brief Rotation angle of a unit quaternion
*

25
src/Magnum/Math/Test/QuaternionTest.cpp

@ -339,24 +339,31 @@ void QuaternionTest::convert() {
}
void QuaternionTest::data() {
Quaternion a{{1.0f, 2.0f, 3.0f}, -4.0f};
CORRADE_COMPARE(a.vector(), (Vector3{1.0f, 2.0f, 3.0f}));
CORRADE_COMPARE(a.scalar(), -4.0f);
CORRADE_COMPARE(a.xyzw(), (Vector4{1.0f, 2.0f, 3.0f, -4.0f}));
CORRADE_COMPARE(a.wxyz(), (Vector4{-4.0f, 1.0f, 2.0f, 3.0f}));
a.vector().y() = 4.3f;
a.scalar() = 1.1f;
CORRADE_COMPARE(a, (Quaternion{{1.0f, 4.3f, 3.0f}, 1.1f}));
CORRADE_COMPARE(a.data()[3], 1.1f);
CORRADE_COMPARE(Containers::arraySize(a.data()), 4);
constexpr Quaternion ca{{1.0f, 2.0f, 3.0f}, -4.0f};
constexpr Vector3 vector = ca.vector();
constexpr Float scalar = ca.scalar();
constexpr Vector4 xyzw = ca.xyzw();
constexpr Vector4 wxyz = ca.wxyz();
CORRADE_COMPARE(vector, (Vector3{1.0f, 2.0f, 3.0f}));
CORRADE_COMPARE(scalar, -4.0f);
Quaternion a{{1.0f, 2.0f, 3.0f}, -4.0f};
a.vector().y() = 4.3f;
a.scalar() = 1.1f;
CORRADE_COMPARE(a, (Quaternion{{1.0f, 4.3f, 3.0f}, 1.1f}));
CORRADE_COMPARE(xyzw, (Vector4{1.0f, 2.0f, 3.0f, -4.0f}));
CORRADE_COMPARE(wxyz, (Vector4{-4.0f, 1.0f, 2.0f, 3.0f}));
/* Not constexpr anymore, as it has to reinterpret to return a
correctly-sized array */
CORRADE_COMPARE(a.data()[3], 1.1f);
CORRADE_COMPARE(ca.data()[1], 2.0f);
/* It actually returns an array */
CORRADE_COMPARE(Containers::arraySize(a.data()), 4);
CORRADE_COMPARE(Containers::arraySize(ca.data()), 4);
}

Loading…
Cancel
Save