diff --git a/src/Magnum/Animation/Interpolation.cpp b/src/Magnum/Animation/Interpolation.cpp index 10b2c1e67..fcb4e9c4e 100644 --- a/src/Magnum/Animation/Interpolation.cpp +++ b/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 auto TypeTraits, Math::Complex>::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 auto TypeTraits, Math::Quaternion>::interpolator(Interpolation interpolation) -> Interpolator { switch(interpolation) { case Interpolation::Constant: return Math::select; @@ -83,6 +95,7 @@ template auto TypeTraits, Math::DualQuaternion< CORRADE_ASSERT(false, "Animation::interpolatorFor(): can't deduce interpolator function for" << interpolation, {}); } +template struct MAGNUM_EXPORT TypeTraits, Math::Complex>; template struct MAGNUM_EXPORT TypeTraits, Math::Quaternion>; template struct MAGNUM_EXPORT TypeTraits, Math::DualQuaternion>; diff --git a/src/Magnum/Animation/Interpolation.h b/src/Magnum/Animation/Interpolation.h index aed2ce90a..cc946f326 100644 --- a/src/Magnum/Animation/Interpolation.h +++ b/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&, const Complex&, T) "Math::slerp()" @ref Interpolation::Linear | @ref Math::Quaternion | @ref Math::Quaternion | @ref Math::slerp(const Quaternion&, const Quaternion&, T) "Math::slerp()" @ref Interpolation::Linear | @ref Math::DualQuaternion | @ref Math::DualQuaternion | @ref Math::sclerp(const DualQuaternion&, const DualQuaternion&, T) "Math::sclerp()" @@ -247,6 +248,13 @@ template auto TypeTraitsBool::interpolator(Interpolation interpolati template<> struct TypeTraits: TypeTraitsBool {}; template struct TypeTraits, Math::BoolVector>: TypeTraitsBool> {}; +/* Complex, preferring slerp() as it is more precise */ +template struct MAGNUM_EXPORT TypeTraits, Math::Complex> { + typedef Math::Complex(*Interpolator)(const Math::Complex&, const Math::Complex&, Float); + + static Interpolator interpolator(Interpolation interpolation); +}; + /* Quaternions and dual quaternions, preferring slerp() as it is more precise */ template struct MAGNUM_EXPORT TypeTraits, Math::Quaternion> { typedef Math::Quaternion(*Interpolator)(const Math::Quaternion&, const Math::Quaternion&, Float); diff --git a/src/Magnum/Animation/Test/InterpolationTest.cpp b/src/Magnum/Animation/Test/InterpolationTest.cpp index 91bb92dfa..2e5a4aae4 100644 --- a/src/Magnum/Animation/Test/InterpolationTest.cpp +++ b/src/Magnum/Animation/Test/InterpolationTest.cpp @@ -27,6 +27,7 @@ #include #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(Interpolation::Constant)( + Complex::rotation(25.0_degf), + Complex::rotation(75.0_degf), 0.5f), + Complex::rotation(25.0_degf)); + CORRADE_COMPARE(Animation::interpolatorFor(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(Interpolation::Custom); + Animation::interpolatorFor(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(Interpolation::Constant)( Quaternion::rotation(25.0_degf, Vector3::xAxis()), diff --git a/src/Magnum/Animation/Track.h b/src/Magnum/Animation/Track.h index ad118938e..a7fa77b20 100644 --- a/src/Magnum/Animation/Track.h +++ b/src/Magnum/Animation/Track.h @@ -67,7 +67,9 @@ Linear | @cpp bool @ce | @cpp bool @ce | @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&, const Complex&, T) "Math::lerp()" Linear | @ref Math::Quaternion | @ref Math::Quaternion | @ref Math::lerp(const Quaternion&, const Quaternion&, T) "Math::lerp()" +Spherical linear | @ref Math::Complex | @ref Math::Complex | @ref Math::slerp(const Complex&, const Complex&, T) "Math::slerp()" Spherical linear | @ref Math::Quaternion | @ref Math::Quaternion | @ref Math::slerp(const Quaternion&, const Quaternion&, T) "Math::slerp()" Screw linear | @ref Math::DualQuaternion | @ref Math::DualQuaternion | @ref Math::sclerp(const DualQuaternion&, const DualQuaternion&, T) "Math::sclerp()" diff --git a/src/Magnum/Trade/AnimationData.cpp b/src/Magnum/Trade/AnimationData.cpp index 5208ac45a..c2f8f3278 100644 --- a/src/Magnum/Trade/AnimationData.cpp +++ b/src/Magnum/Trade/AnimationData.cpp @@ -97,6 +97,7 @@ template MAGNUM_TRADE_EXPORT auto animationInterpolatorFor(Ani template MAGNUM_TRADE_EXPORT auto animationInterpolatorFor(Animation::Interpolation) -> Vector4d(*)(const Vector4d&, const Vector4d&, Float); template MAGNUM_TRADE_EXPORT auto animationInterpolatorFor(Animation::Interpolation) -> Vector4i(*)(const Vector4i&, const Vector4i&, Float); template MAGNUM_TRADE_EXPORT auto animationInterpolatorFor(Animation::Interpolation) -> Vector4ui(*)(const Vector4ui&, const Vector4ui&, Float); +template MAGNUM_TRADE_EXPORT auto animationInterpolatorFor(Animation::Interpolation) -> Complex(*)(const Complex&, const Complex&, Float); template MAGNUM_TRADE_EXPORT auto animationInterpolatorFor(Animation::Interpolation) -> Quaternion(*)(const Quaternion&, const Quaternion&, Float); template MAGNUM_TRADE_EXPORT auto animationInterpolatorFor(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 diff --git a/src/Magnum/Trade/AnimationData.h b/src/Magnum/Trade/AnimationData.h index d8196cd3d..5d3781957 100644 --- a/src/Magnum/Trade/AnimationData.h +++ b/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>() { return AnimationTrackType::Vector3i; } template<> constexpr AnimationTrackType animationTypeFor>() { return AnimationTrackType::Vector4i; } + template<> constexpr AnimationTrackType animationTypeFor() { return AnimationTrackType::Complex; } template<> constexpr AnimationTrackType animationTypeFor() { return AnimationTrackType::Quaternion; } template<> constexpr AnimationTrackType animationTypeFor() { return AnimationTrackType::DualQuaternion; } /* LCOV_EXCL_STOP */