Browse Source

Animation, Trade: support Complex for rotation animations.

Since there's now lerp() and slerp() for it.
pull/267/head
Vladimír Vondruš 8 years ago
parent
commit
ac11a8e815
  1. 13
      src/Magnum/Animation/Interpolation.cpp
  2. 8
      src/Magnum/Animation/Interpolation.h
  3. 23
      src/Magnum/Animation/Test/InterpolationTest.cpp
  4. 2
      src/Magnum/Animation/Track.h
  5. 2
      src/Magnum/Trade/AnimationData.cpp
  6. 9
      src/Magnum/Trade/AnimationData.h

13
src/Magnum/Animation/Interpolation.cpp

@ -25,6 +25,7 @@
#include "Interpolation.h"
#include "Magnum/Math/Complex.h"
#include "Magnum/Math/DualQuaternion.h"
namespace Magnum { namespace Animation {
@ -61,6 +62,17 @@ Debug& operator<<(Debug& debug, const Extrapolation value) {
namespace Implementation {
template<class T> auto TypeTraits<Math::Complex<T>, Math::Complex<T>>::interpolator(Interpolation interpolation) -> Interpolator {
switch(interpolation) {
case Interpolation::Constant: return Math::select;
case Interpolation::Linear: return Math::slerp;
case Interpolation::Custom: ; /* nope */
}
CORRADE_ASSERT(false, "Animation::interpolatorFor(): can't deduce interpolator function for" << interpolation, {});
}
template<class T> auto TypeTraits<Math::Quaternion<T>, Math::Quaternion<T>>::interpolator(Interpolation interpolation) -> Interpolator {
switch(interpolation) {
case Interpolation::Constant: return Math::select;
@ -83,6 +95,7 @@ template<class T> auto TypeTraits<Math::DualQuaternion<T>, Math::DualQuaternion<
CORRADE_ASSERT(false, "Animation::interpolatorFor(): can't deduce interpolator function for" << interpolation, {});
}
template struct MAGNUM_EXPORT TypeTraits<Math::Complex<Float>, Math::Complex<Float>>;
template struct MAGNUM_EXPORT TypeTraits<Math::Quaternion<Float>, Math::Quaternion<Float>>;
template struct MAGNUM_EXPORT TypeTraits<Math::DualQuaternion<Float>, Math::DualQuaternion<Float>>;

8
src/Magnum/Animation/Interpolation.h

@ -100,6 +100,7 @@ Interpolation type | Value type | Result type | Interpolator
@ref Interpolation::Linear | @ref Math::BoolVector | @ref Math::BoolVector | @ref Math::select()
@ref Interpolation::Linear | any scalar `V` | `V` | @ref Math::lerp()
@ref Interpolation::Linear | any vector `V` | `V` | @ref Math::lerp()
@ref Interpolation::Linear | @ref Math::Complex | @ref Math::Complex | @ref Math::slerp(const Complex<T>&, const Complex<T>&, T) "Math::slerp()"
@ref Interpolation::Linear | @ref Math::Quaternion | @ref Math::Quaternion | @ref Math::slerp(const Quaternion<T>&, const Quaternion<T>&, T) "Math::slerp()"
@ref Interpolation::Linear | @ref Math::DualQuaternion | @ref Math::DualQuaternion | @ref Math::sclerp(const DualQuaternion<T>&, const DualQuaternion<T>&, T) "Math::sclerp()"
@ -247,6 +248,13 @@ template<class T> auto TypeTraitsBool<T>::interpolator(Interpolation interpolati
template<> struct TypeTraits<bool, bool>: TypeTraitsBool<bool> {};
template<std::size_t size> struct TypeTraits<Math::BoolVector<size>, Math::BoolVector<size>>: TypeTraitsBool<Math::BoolVector<size>> {};
/* Complex, preferring slerp() as it is more precise */
template<class T> struct MAGNUM_EXPORT TypeTraits<Math::Complex<T>, Math::Complex<T>> {
typedef Math::Complex<T>(*Interpolator)(const Math::Complex<T>&, const Math::Complex<T>&, Float);
static Interpolator interpolator(Interpolation interpolation);
};
/* Quaternions and dual quaternions, preferring slerp() as it is more precise */
template<class T> struct MAGNUM_EXPORT TypeTraits<Math::Quaternion<T>, Math::Quaternion<T>> {
typedef Math::Quaternion<T>(*Interpolator)(const Math::Quaternion<T>&, const Math::Quaternion<T>&, Float);

23
src/Magnum/Animation/Test/InterpolationTest.cpp

@ -27,6 +27,7 @@
#include <Corrade/TestSuite/Tester.h>
#include "Magnum/Animation/Interpolation.h"
#include "Magnum/Math/Complex.h"
#include "Magnum/Math/DualQuaternion.h"
#include "Magnum/Math/Half.h"
@ -38,6 +39,7 @@ struct InterpolationTest: TestSuite::Tester {
void interpolatorFor();
void interpolatorForBool();
void interpolatorForBoolVector();
void interpolatorForComplex();
void interpolatorForQuaternion();
void interpolatorForDualQuaternion();
@ -138,6 +140,7 @@ InterpolationTest::InterpolationTest() {
addTests({&InterpolationTest::interpolatorFor,
&InterpolationTest::interpolatorForBool,
&InterpolationTest::interpolatorForBoolVector,
&InterpolationTest::interpolatorForComplex,
&InterpolationTest::interpolatorForQuaternion,
&InterpolationTest::interpolatorForDualQuaternion});
@ -215,6 +218,26 @@ void InterpolationTest::interpolatorForBoolVector() {
"Animation::interpolatorFor(): can't deduce interpolator function for Animation::Interpolation(0xde)\n");
}
void InterpolationTest::interpolatorForComplex() {
CORRADE_COMPARE(Animation::interpolatorFor<Complex>(Interpolation::Constant)(
Complex::rotation(25.0_degf),
Complex::rotation(75.0_degf), 0.5f),
Complex::rotation(25.0_degf));
CORRADE_COMPARE(Animation::interpolatorFor<Complex>(Interpolation::Linear)(
Complex::rotation(25.0_degf),
Complex::rotation(75.0_degf), 0.5f),
Complex::rotation(50.0_degf));
std::ostringstream out;
Error redirectError{&out};
Animation::interpolatorFor<Complex>(Interpolation::Custom);
Animation::interpolatorFor<Complex>(Interpolation(0xde));
CORRADE_COMPARE(out.str(),
"Animation::interpolatorFor(): can't deduce interpolator function for Animation::Interpolation::Custom\n"
"Animation::interpolatorFor(): can't deduce interpolator function for Animation::Interpolation(0xde)\n");
}
void InterpolationTest::interpolatorForQuaternion() {
CORRADE_COMPARE(Animation::interpolatorFor<Quaternion>(Interpolation::Constant)(
Quaternion::rotation(25.0_degf, Vector3::xAxis()),

2
src/Magnum/Animation/Track.h

@ -67,7 +67,9 @@ Linear | @cpp bool @ce <b></b> | @cpp bool @ce <b></b> | @ref Math::select()
Linear | @ref Math::BoolVector | @ref Math::BoolVector | @ref Math::select()
Linear | any scalar `V` | `V` | @ref Math::lerp()
Linear | any vector `V` | `V` | @ref Math::lerp()
Linear | @ref Math::Complex | @ref Math::Complex | @ref Math::lerp(const Complex<T>&, const Complex<T>&, T) "Math::lerp()"
Linear | @ref Math::Quaternion | @ref Math::Quaternion | @ref Math::lerp(const Quaternion<T>&, const Quaternion<T>&, T) "Math::lerp()"
Spherical linear | @ref Math::Complex | @ref Math::Complex | @ref Math::slerp(const Complex<T>&, const Complex<T>&, T) "Math::slerp()"
Spherical linear | @ref Math::Quaternion | @ref Math::Quaternion | @ref Math::slerp(const Quaternion<T>&, const Quaternion<T>&, T) "Math::slerp()"
Screw linear | @ref Math::DualQuaternion | @ref Math::DualQuaternion | @ref Math::sclerp(const DualQuaternion<T>&, const DualQuaternion<T>&, T) "Math::sclerp()"

2
src/Magnum/Trade/AnimationData.cpp

@ -97,6 +97,7 @@ template MAGNUM_TRADE_EXPORT auto animationInterpolatorFor<Vector4, Vector4>(Ani
template MAGNUM_TRADE_EXPORT auto animationInterpolatorFor<Vector4d, Vector4d>(Animation::Interpolation) -> Vector4d(*)(const Vector4d&, const Vector4d&, Float);
template MAGNUM_TRADE_EXPORT auto animationInterpolatorFor<Vector4i, Vector4i>(Animation::Interpolation) -> Vector4i(*)(const Vector4i&, const Vector4i&, Float);
template MAGNUM_TRADE_EXPORT auto animationInterpolatorFor<Vector4ui, Vector4ui>(Animation::Interpolation) -> Vector4ui(*)(const Vector4ui&, const Vector4ui&, Float);
template MAGNUM_TRADE_EXPORT auto animationInterpolatorFor<Complex, Complex>(Animation::Interpolation) -> Complex(*)(const Complex&, const Complex&, Float);
template MAGNUM_TRADE_EXPORT auto animationInterpolatorFor<Quaternion, Quaternion>(Animation::Interpolation) -> Quaternion(*)(const Quaternion&, const Quaternion&, Float);
template MAGNUM_TRADE_EXPORT auto animationInterpolatorFor<DualQuaternion, DualQuaternion>(Animation::Interpolation) -> DualQuaternion(*)(const DualQuaternion&, const DualQuaternion&, Float);
@ -120,6 +121,7 @@ Debug& operator<<(Debug& debug, const AnimationTrackType value) {
_c(Vector4)
_c(Vector4ui)
_c(Vector4i)
_c(Complex)
_c(Quaternion)
_c(DualQuaternion)
#undef _c

9
src/Magnum/Trade/AnimationData.h

@ -75,6 +75,12 @@ enum class AnimationTrackType: UnsignedByte {
Vector4ui, /**< @ref Magnum::Vector4ui "Vector4ui" */
Vector4i, /**< @ref Magnum::Vector4i "Vector4i" */
/**
* @ref Magnum::Complex "Complex". Usually used for
* @ref AnimationTrackTarget::Rotation2D.
*/
Complex,
/**
* @ref Magnum::Quaternion "Quaternion". Usually used for
* @ref AnimationTrackTarget::Rotation3D.
@ -114,7 +120,7 @@ enum class AnimationTrackTarget: UnsignedByte {
* Modifies 2D object rotation. Type is usually
* @ref Magnum::Complex "Complex".
*
* @see @ref ObjectData2D::rotation()
* @see @ref AnimationTrackType::Complex, @ref ObjectData2D::rotation()
*/
Rotation2D,
@ -441,6 +447,7 @@ namespace Implementation {
template<> constexpr AnimationTrackType animationTypeFor<Math::Vector<3, Int>>() { return AnimationTrackType::Vector3i; }
template<> constexpr AnimationTrackType animationTypeFor<Math::Vector<4, Int>>() { return AnimationTrackType::Vector4i; }
template<> constexpr AnimationTrackType animationTypeFor<Complex>() { return AnimationTrackType::Complex; }
template<> constexpr AnimationTrackType animationTypeFor<Quaternion>() { return AnimationTrackType::Quaternion; }
template<> constexpr AnimationTrackType animationTypeFor<DualQuaternion>() { return AnimationTrackType::DualQuaternion; }
/* LCOV_EXCL_STOP */

Loading…
Cancel
Save