Browse Source

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

Still undocumented feature.
pull/107/head
Vladimír Vondruš 11 years ago
parent
commit
52434fb55c
  1. 12
      src/Magnum/Math/DualQuaternion.h
  2. 49
      src/Magnum/Math/Test/DualQuaternionTest.cpp

12
src/Magnum/Math/DualQuaternion.h

@ -35,6 +35,10 @@
namespace Magnum { namespace Math {
namespace Implementation {
template<class, class> struct DualQuaternionConverter;
}
/**
@brief Dual quaternion
@tparam T Underlying data type
@ -134,9 +138,17 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
constexpr explicit DualQuaternion(const Vector3<T>& vector): Dual<Quaternion<T>>({}, {vector, T(0)}) {}
#endif
/** @brief Construct dual quaternion from external representation */
template<class U, class V = decltype(Implementation::DualQuaternionConverter<T, U>::from(std::declval<U>()))> constexpr explicit DualQuaternion(const U& other): DualQuaternion{Implementation::DualQuaternionConverter<T, U>::from(other)} {}
/** @brief Copy constructor */
constexpr DualQuaternion(const Dual<Quaternion<T>>& other): Dual<Quaternion<T>>(other) {}
/** @brief Convert dual quaternion to external representation */
template<class U, class V = decltype(Implementation::DualQuaternionConverter<T, U>::to(std::declval<DualQuaternion<T>>()))> constexpr explicit operator U() const {
return Implementation::DualQuaternionConverter<T, U>::to(*this);
}
/**
* @brief Whether the dual quaternion is normalized
*

49
src/Magnum/Math/Test/DualQuaternionTest.cpp

@ -28,7 +28,30 @@
#include "Magnum/Math/DualQuaternion.h"
namespace Magnum { namespace Math { namespace Test {
struct DualQuat {
struct { float x, y, z, w; } re;
struct { float x, y, z, w; } du;
};
namespace Magnum { namespace Math {
namespace Implementation {
template<> struct DualQuaternionConverter<Float, DualQuat> {
constexpr static DualQuaternion<Float> from(const DualQuat& other) {
return {{{other.re.x, other.re.y, other.re.z}, other.re.w},
{{other.du.x, other.du.y, other.du.z}, other.du.w}};
}
constexpr static DualQuat to(const DualQuaternion<Float>& other) {
return {{other.real().vector().x(), other.real().vector().y(), other.real().vector().z(), other.real().scalar()},
{other.dual().vector().x(), other.dual().vector().y(), other.dual().vector().z(), other.dual().scalar()}};
}
};
}
namespace Test {
struct DualQuaternionTest: Corrade::TestSuite::Tester {
explicit DualQuaternionTest();
@ -37,6 +60,7 @@ struct DualQuaternionTest: Corrade::TestSuite::Tester {
void constructDefault();
void constructFromVector();
void constructCopy();
void convert();
void isNormalized();
@ -73,6 +97,7 @@ DualQuaternionTest::DualQuaternionTest() {
&DualQuaternionTest::constructDefault,
&DualQuaternionTest::constructFromVector,
&DualQuaternionTest::constructCopy,
&DualQuaternionTest::convert,
&DualQuaternionTest::isNormalized,
@ -130,6 +155,28 @@ void DualQuaternionTest::constructCopy() {
CORRADE_COMPARE(b, DualQuaternion({{1.0f, 2.0f, -3.0f}, -3.5f}, {{4.5f, -7.0f, 2.0f}, 1.0f}));
}
void DualQuaternionTest::convert() {
constexpr DualQuat a{{1.5f, -3.5f, 7.0f, -0.5f}, {15.0f, 0.25f, -9.5f, 0.8f}};
constexpr DualQuaternion b{{{1.5f, -3.5f, 7.0f}, -0.5f}, {{15.0f, 0.25f, -9.5f}, 0.8f}};
constexpr DualQuaternion c{a};
CORRADE_COMPARE(c, b);
constexpr DualQuat d(b);
CORRADE_COMPARE(d.re.x, a.re.x);
CORRADE_COMPARE(d.re.y, a.re.y);
CORRADE_COMPARE(d.re.z, a.re.z);
CORRADE_COMPARE(d.re.w, a.re.w);
CORRADE_COMPARE(d.du.x, a.du.x);
CORRADE_COMPARE(d.du.y, a.du.y);
CORRADE_COMPARE(d.du.z, a.du.z);
CORRADE_COMPARE(d.du.w, a.du.w);
/* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<DualQuat, DualQuaternion>::value));
CORRADE_VERIFY(!(std::is_convertible<DualQuaternion, DualQuat>::value));
}
void DualQuaternionTest::isNormalized() {
CORRADE_VERIFY(!DualQuaternion({{1.0f, 2.0f, 3.0f}, 4.0f}, {}).isNormalized());
CORRADE_VERIFY((DualQuaternion::rotation(Deg(23.0f), Vector3::xAxis())*DualQuaternion::translation({3.0f, 1.0f, -0.5f})).isNormalized());

Loading…
Cancel
Save