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 @ref Math::Quaternion::reflectVector(), but mainly just for documentation
purposes as reflections cannot be combined with rotations and thus are purposes as reflections cannot be combined with rotations and thus are
mostly useless in practice 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 - New @ref Magnum/Math/ColorBatch.h header with utilities for performing Y
flip of various block-compressed formats flip of various block-compressed formats
- New @ref Math::Nanoseconds and @ref Math::Seconds classes for strongly - 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[ * @f[
* \boldsymbol v = \begin{pmatrix} a \\ b \end{pmatrix} * \boldsymbol v = \begin{pmatrix} a \\ b \end{pmatrix}
* @f] * @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 { constexpr explicit operator Vector2<T>() const {
return {_real, _imaginary}; return {_real, _imaginary};

38
src/Magnum/Math/Quaternion.h

@ -469,16 +469,50 @@ template<class T> class Quaternion {
return Implementation::isNormalizedSquared(dot()); 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; } Vector3<T>& vector() { return _vector; }
/* Returning const so it's possible to call constexpr functions on the /* Returning const so it's possible to call constexpr functions on the
result. WTF, C++?! */ result. WTF, C++?! */
constexpr const Vector3<T> vector() const { return _vector; } /**< @overload */ 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; } T& scalar() { return _scalar; }
constexpr T scalar() const { return _scalar; } /**< @overload */ 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 * @brief Rotation angle of a unit quaternion
* *

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

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

Loading…
Cancel
Save