Browse Source

Math: ability to convert quaternions from/to external representation.

Still undocumented feature.
pull/107/head
Vladimír Vondruš 11 years ago
parent
commit
94c4225165
  1. 14
      src/Magnum/Math/Quaternion.h
  2. 42
      src/Magnum/Math/Test/QuaternionTest.cpp

14
src/Magnum/Math/Quaternion.h

@ -39,6 +39,10 @@
namespace Magnum { namespace Math {
namespace Implementation {
template<class, class> struct QuaternionConverter;
}
/** @relatesalso Quaternion
@brief Dot product between two quaternions
@ -214,6 +218,14 @@ template<class T> class Quaternion {
*/
constexpr explicit Quaternion(const Vector3<T>& vector): _vector(vector), _scalar(T(0)) {}
/** @brief Construct quaternion from external representation */
template<class U, class V = decltype(Implementation::QuaternionConverter<T, U>::from(std::declval<U>()))> constexpr explicit Quaternion(const U& other): Quaternion{Implementation::QuaternionConverter<T, U>::from(other)} {}
/** @brief Convert quaternion to external representation */
template<class U, class V = decltype(Implementation::QuaternionConverter<T, U>::to(std::declval<Quaternion<T>>()))> constexpr explicit operator U() const {
return Implementation::QuaternionConverter<T, U>::to(*this);
}
/** @brief Equality comparison */
bool operator==(const Quaternion<T>& other) const {
return _vector == other._vector && TypeTraits<T>::equals(_scalar, other._scalar);
@ -237,7 +249,7 @@ template<class T> class Quaternion {
}
/** @brief Vector part */
constexpr Vector3<T> vector() const { return _vector; }
constexpr const Vector3<T> vector() const { return _vector; }
/** @brief Scalar part */
constexpr T scalar() const { return _scalar; }

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

@ -29,7 +29,27 @@
#include "Magnum/Math/Matrix4.h"
#include "Magnum/Math/Quaternion.h"
namespace Magnum { namespace Math { namespace Test {
struct Quat {
float x, y, z, w;
};
namespace Magnum { namespace Math {
namespace Implementation {
template<> struct QuaternionConverter<Float, Quat> {
constexpr static Quaternion<Float> from(const Quat& other) {
return {{other.x, other.y, other.z}, other.w};
}
constexpr static Quat to(const Quaternion<Float>& other) {
return {other.vector().x(), other.vector().y(), other.vector().z(), other.scalar() };
}
};
}
namespace Test {
struct QuaternionTest: Corrade::TestSuite::Tester {
explicit QuaternionTest();
@ -38,6 +58,7 @@ struct QuaternionTest: Corrade::TestSuite::Tester {
void constructDefault();
void constructFromVector();
void constructCopy();
void convert();
void compare();
void isNormalized();
@ -80,6 +101,7 @@ QuaternionTest::QuaternionTest() {
&QuaternionTest::constructDefault,
&QuaternionTest::constructFromVector,
&QuaternionTest::constructCopy,
&QuaternionTest::convert,
&QuaternionTest::compare,
&QuaternionTest::isNormalized,
@ -139,6 +161,24 @@ void QuaternionTest::constructCopy() {
CORRADE_COMPARE(b, Quaternion({1.0f, -3.0f, 7.0f}, 2.5f));
}
void QuaternionTest::convert() {
constexpr Quat a{1.5f, -3.5f, 7.0f, -0.5f};
constexpr Quaternion b{{1.5f, -3.5f, 7.0f}, -0.5f};
constexpr Quaternion c{a};
CORRADE_COMPARE(c, b);
constexpr Quat d(b);
CORRADE_COMPARE(d.x, a.x);
CORRADE_COMPARE(d.y, a.y);
CORRADE_COMPARE(d.z, a.z);
CORRADE_COMPARE(d.w, a.w);
/* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Quat, Quaternion>::value));
CORRADE_VERIFY(!(std::is_convertible<Quaternion, Quat>::value));
}
void QuaternionTest::compare() {
CORRADE_VERIFY(Quaternion({1.0f+TypeTraits<Float>::epsilon()/2, 2.0f, 3.0f}, -4.0f) == Quaternion({1.0f, 2.0f, 3.0f}, -4.0f));
CORRADE_VERIFY(Quaternion({1.0f+TypeTraits<Float>::epsilon()*2, 2.0f, 3.0f}, -4.0f) != Quaternion({1.0f, 2.0f, 3.0f}, -4.0f));

Loading…
Cancel
Save