Browse Source

Trade: provide better AnimationTrackData constructors.

Taking Animation::TrackViewStorage wasn't really a good idea, as it
wasn't solving anything -- in order to create it, there needs to be a
TrackView of a concrete type first anyway, and even then it required a
lot of additional verbose typing.

The new constructors take basically what TrackView takes, plus there's
additionally a constructor that takes a typeless value view together
with explicitly specified value and result types, allowing a truly
type-erased usage. On the other hand, the templated variants directly
deduce the types without any additional typing, making the construction
similarly straightforward to e.g. SceneFieldData.

In case of the type-erased constructors, if the interpolator function
isn't supplied explicitly, an implicit one is picked based on the value
type, result type and interpolation. Not all combinations make sense of
course, so this is a new assertion point, however compared to the
previous way where the interpolator was picked from a *typed* TrackView,
this doesn't add any new restriction -- what asserted there, asserts now
as well, and additionally you can't have e.g. a Quaternion track with a
boolean result. I may also be eventually adding assertions to check that
the target name matches the result type -- so e.g. a rotation isn't
specified as an integer and such. Compared to newer APIs like MeshData,
MaterialData or SceneData the AnimationData API has a significant lack
of sanity asserts like this.
pull/617/head
Vladimír Vondruš 3 years ago
parent
commit
94e9961a30
  1. 8
      doc/changelog.dox
  2. 75
      src/Magnum/Trade/AnimationData.cpp
  3. 250
      src/Magnum/Trade/AnimationData.h
  4. 5
      src/Magnum/Trade/Test/AbstractImporterTest.cpp
  5. 379
      src/Magnum/Trade/Test/AnimationDataTest.cpp

8
doc/changelog.dox

@ -1053,6 +1053,14 @@ See also:
- @cpp Trade::AbstractMaterialData @ce as well as its containing header
`Magnum/Trade/AbstractMaterialData.h` is now a deprecated alias to the new
and more flexible @ref Trade::MaterialData.
- @ref Trade::AnimationTrackData constructors taking
@ref Animation::TrackViewStorage are deprecated in favor of significantly
less verbose variants that take key/value views and other track parameters
directly, allowing them to either directly deduce the value type or be
truly type-erased, no longer requiring user code to manually handle all
possible cases. The variant taking an @ref Animation::TrackView is kept
however as it may be convenient when exporting already-populated animation
instances.
- @cpp Trade::LightData::Type::Infinite @ce, originally adapted from the
OpenGEX specification, is deprecated in favor of
@ref Trade::LightData::Type::Directional as that's the more commonly used

75
src/Magnum/Trade/AnimationData.cpp

@ -33,17 +33,78 @@
namespace Magnum { namespace Trade {
AnimationTrackData::AnimationTrackData(const AnimationTrackType type, const AnimationTrackType resultType, const AnimationTrackTarget targetName, const UnsignedLong target, const Animation::TrackViewStorage<const Float>& view) noexcept: _type{type}, _resultType{resultType}, _targetName{targetName}, _interpolation{view.interpolation()}, _before{view.before()}, _after{view.after()}, _target{target}, _size{UnsignedInt(view.size())}, _keysStride{Short(view.keys().stride())}, _valuesStride{Short(view.values().stride())}, _keysData{view.keys().data()}, _valuesData{view.values().data()}, _interpolator{view.interpolator()} {
namespace {
auto animationInterpolatorFor(const Animation::Interpolation interpolation, const AnimationTrackType type, const AnimationTrackType resultType) -> void(*)() {
switch(type) {
/* LCOV_EXCL_START */
#define _ct(value, type_) \
case AnimationTrackType::value: \
if(type == resultType) \
return reinterpret_cast<void(*)()>(Trade::animationInterpolatorFor<type_, type_>(interpolation)); \
break;
#define _c(type_) _ct(type_, type_)
_ct(Bool, bool)
_c(Float)
_c(UnsignedInt)
_c(Int)
_c(BitVector2)
_c(BitVector3)
_c(BitVector4)
_c(Vector2)
_c(Vector2ui)
_c(Vector2i)
_c(Vector3)
_c(Vector3ui)
_c(Vector3i)
_c(Vector4)
_c(Vector4ui)
_c(Vector4i)
_c(Complex)
_c(Quaternion)
_c(DualQuaternion)
#undef _c
#undef _ct
/* LCOV_EXCL_STOP */
/* LCOV_EXCL_START */
#define _cr(type_, resultType_) \
case AnimationTrackType::type_: \
if(resultType == AnimationTrackType::resultType_) \
return reinterpret_cast<void(*)()>(Trade::animationInterpolatorFor<type_, resultType_>(interpolation)); \
break;
_cr(CubicHermite1D, Float)
_cr(CubicHermite2D, Vector2)
_cr(CubicHermite3D, Vector3)
_cr(CubicHermiteComplex, Complex)
_cr(CubicHermiteQuaternion, Quaternion)
#undef _cr
/* LCOV_EXCL_STOP */
}
/** @todo this doesn't print the types when e.g. a spline interpolation is
requested for bool, how to fix? */
CORRADE_ASSERT_UNREACHABLE("Trade::AnimationTrackData: can't deduce interpolator function for" << type << Debug::nospace << "," << resultType << "and" << interpolation, {});
}
}
AnimationTrackData::AnimationTrackData(const AnimationTrackTarget targetName, const UnsignedLong target, const AnimationTrackType type, const AnimationTrackType resultType, const Containers::StridedArrayView1D<const Float>& keys, const Containers::StridedArrayView1D<const void>& values, const Animation::Interpolation interpolation, void(*const interpolator)(), const Animation::Extrapolation before, const Animation::Extrapolation after) noexcept: _type{type}, _resultType{resultType}, _targetName{targetName}, _interpolation{interpolation}, _before{before}, _after{after}, _target{target}, _size{UnsignedInt(keys.size())}, _keysStride{Short(keys.stride())}, _valuesStride{Short(values.stride())}, _keysData{keys.data()}, _valuesData{values.data()}, _interpolator{interpolator} {
CORRADE_ASSERT(keys.size() == values.size(),
"Trade::AnimationTrackData: expected key and value view to have the same size but got" << keys.size() << "and" << values.size(), );
#ifndef CORRADE_TARGET_32BIT
CORRADE_ASSERT(view.size() <= 0xffffffffu,
"Trade::AnimationTrackData: expected keyframe count to fit into 32 bits but got" << view.size(), );
CORRADE_ASSERT(keys.size() <= 0xffffffffu,
"Trade::AnimationTrackData: expected keyframe count to fit into 32 bits but got" << keys.size(), );
#endif
CORRADE_ASSERT(view.keys().stride() >= -32768 && view.keys().stride() <= 32767,
"Trade::AnimationTrackData: expected key stride to fit into 16 bits but got" << view.keys().stride(), );
CORRADE_ASSERT(view.values().stride() >= -32768 && view.values().stride() <= 32767,
"Trade::AnimationTrackData: expected value stride to fit into 16 bits but got" << view.values().stride(), );
CORRADE_ASSERT(keys.stride() >= -32768 && keys.stride() <= 32767,
"Trade::AnimationTrackData: expected key stride to fit into 16 bits but got" << keys.stride(), );
CORRADE_ASSERT(values.stride() >= -32768 && values.stride() <= 32767,
"Trade::AnimationTrackData: expected value stride to fit into 16 bits but got" << values.stride(), );
}
AnimationTrackData::AnimationTrackData(const AnimationTrackTarget targetName, const UnsignedLong target, const AnimationTrackType type, const AnimationTrackType resultType, const Containers::StridedArrayView1D<const Float>& keys, const Containers::StridedArrayView1D<const void>& values, const Animation::Interpolation interpolation, const Animation::Extrapolation before, const Animation::Extrapolation after) noexcept: AnimationTrackData{targetName, target, type, resultType, keys, values, interpolation, animationInterpolatorFor(interpolation, type, resultType), before, after} {}
Animation::TrackViewStorage<const Float> AnimationTrackData::track() const {
return Animation::TrackViewStorage<const Float>{
/* We're sure the views are correct, circumventing the asserts */

250
src/Magnum/Trade/AnimationData.h

@ -349,6 +349,150 @@ class MAGNUM_TRADE_EXPORT AnimationTrackData {
*/
explicit AnimationTrackData() noexcept: _type{}, _resultType{}, _targetName{}, _interpolation{}, _before{}, _after{}, _target{}, _size{}, _keysStride{}, _valuesStride{}, _keysData{}, _valuesData{}, _interpolator{} {}
/**
* @brief Type-erased constructor with generic interpolation behavior
* @param targetName Track target name
* @param target Track target ID
* @param type Value type
* @param resultType Result type
* @param keys Frame keys
* @param values Frame values
* @param interpolation Interpolation behavior
* @param before Extrapolation behavior before
* @param after Extrapolation behavior after
* @m_since_latest
*
* The keyframe data are assumed to be stored in sorted order. It's not
* an error to have two successive keyframes with the same frame value.
* Expects that @p keys and @p values strides both fit into signed
* 16-bit values, that they both have the same size and that keyframe
* count fits into 32 bits.
*
* The interpolator function is picked implicitly for given
* @p interpolation, @p type and @p resultType and the combination is
* expected to make sense. Use
* @ref AnimationTrackData(AnimationTrackTarget, UnsignedLong, AnimationTrackType, AnimationTrackType, const Containers::StridedArrayView1D<const Float>&, const Containers::StridedArrayView1D<const void>&, Animation::Interpolation, void(*)(), Animation::Extrapolation, Animation::Extrapolation)
* to supply it explicitly.
*/
explicit AnimationTrackData(AnimationTrackTarget targetName, UnsignedLong target, AnimationTrackType type, AnimationTrackType resultType, const Containers::StridedArrayView1D<const Float>& keys, const Containers::StridedArrayView1D<const void>& values, Animation::Interpolation interpolation, Animation::Extrapolation before, Animation::Extrapolation after) noexcept;
/** @overload
* @m_since_latest
*
* Equivalent to calling @ref AnimationTrackData(AnimationTrackTarget, UnsignedLong, AnimationTrackType, AnimationTrackType, const Containers::StridedArrayView1D<const Float>&, const Containers::StridedArrayView1D<const void>&, Animation::Interpolation, Animation::Extrapolation, Animation::Extrapolation)
* with both @p type and @p resultType set to @p type.
*/
explicit AnimationTrackData(AnimationTrackTarget targetName, UnsignedLong target, AnimationTrackType type, const Containers::StridedArrayView1D<const Float>& keys, const Containers::StridedArrayView1D<const void>& values, Animation::Interpolation interpolation, Animation::Extrapolation before, Animation::Extrapolation after) noexcept: AnimationTrackData{targetName, target, type, type, keys, values, interpolation, before, after} {}
/** @overload
* @m_since_latest
*
* Equivalent to calling @ref AnimationTrackData(AnimationTrackTarget, UnsignedLong, AnimationTrackType, AnimationTrackType, const Containers::StridedArrayView1D<const Float>&, const Containers::StridedArrayView1D<const void>&, Animation::Interpolation, Animation::Extrapolation, Animation::Extrapolation)
* with both @p before and @p after set to @p extrapolation.
*/
explicit AnimationTrackData(AnimationTrackTarget targetName, UnsignedLong target, AnimationTrackType type, AnimationTrackType resultType, const Containers::StridedArrayView1D<const Float>& keys, const Containers::StridedArrayView1D<const void>& values, Animation::Interpolation interpolation, Animation::Extrapolation extrapolation = Animation::Extrapolation::Constant) noexcept: AnimationTrackData{targetName, target, type, resultType, keys, values, interpolation, extrapolation, extrapolation} {}
/** @overload
* @m_since_latest
*
* Equivalent to calling @ref AnimationTrackData(AnimationTrackTarget, UnsignedLong, AnimationTrackType, AnimationTrackType, const Containers::StridedArrayView1D<const Float>&, const Containers::StridedArrayView1D<const void>&, Animation::Interpolation, Animation::Extrapolation, Animation::Extrapolation)
* with both @p type and @p resultType set to @p type, and both
* @p before and @p after set to @p extrapolation.
*/
explicit AnimationTrackData(AnimationTrackTarget targetName, UnsignedLong target, AnimationTrackType type, const Containers::StridedArrayView1D<const Float>& keys, const Containers::StridedArrayView1D<const void>& values, Animation::Interpolation interpolation, Animation::Extrapolation extrapolation = Animation::Extrapolation::Constant) noexcept: AnimationTrackData{targetName, target, type, keys, values, interpolation, extrapolation, extrapolation} {}
/**
* @brief Type-erased constructor with both generic and custom interpolator
* @param targetName Track target name
* @param target Track target ID
* @param type Value type
* @param resultType Result type
* @param keys Frame keys
* @param values Frame values
* @param interpolation Interpolation behavior
* @param interpolator Interpolator function
* @param before Extrapolation behavior before
* @param after Extrapolation behavior after
* @m_since_latest
*
* Compared to @ref AnimationTrackData(AnimationTrackTarget, UnsignedLong, AnimationTrackType, AnimationTrackType, const Containers::StridedArrayView1D<const Float>&, const Containers::StridedArrayView1D<const void>&, Animation::Interpolation, Animation::Extrapolation, Animation::Extrapolation)
* which picks an interpolator function based on the value of
* @p interpolation, @p type and @p resultType, here it's taken
* explicitly. Even though it accepts the function cast to a
* @cpp void(*)() @ce, it's expected to be of a right type for @p type
* and @p resultType.
*/
explicit AnimationTrackData(AnimationTrackTarget targetName, UnsignedLong target, AnimationTrackType type, AnimationTrackType resultType, const Containers::StridedArrayView1D<const Float>& keys, const Containers::StridedArrayView1D<const void>& values, Animation::Interpolation interpolation, void(*interpolator)(), Animation::Extrapolation before, Animation::Extrapolation after) noexcept;
/** @overload
* @m_since_latest
*
* Equivalent to calling @ref AnimationTrackData(AnimationTrackTarget, UnsignedLong, AnimationTrackType, AnimationTrackType, const Containers::StridedArrayView1D<const Float>&, const Containers::StridedArrayView1D<const void>&, Animation::Interpolation, void(*)(), Animation::Extrapolation, Animation::Extrapolation)
* with both @p type and @p resultType set to @p type.
*/
explicit AnimationTrackData(AnimationTrackTarget targetName, UnsignedLong target, AnimationTrackType type, const Containers::StridedArrayView1D<const Float>& keys, const Containers::StridedArrayView1D<const void>& values, Animation::Interpolation interpolation, void(*interpolator)(), Animation::Extrapolation before, Animation::Extrapolation after) noexcept: AnimationTrackData{targetName, target, type, type, keys, values, interpolation, interpolator, before, after} {}
/** @overload
* @m_since_latest
*
* Equivalent to calling @ref AnimationTrackData(AnimationTrackTarget, UnsignedLong, AnimationTrackType, AnimationTrackType, const Containers::StridedArrayView1D<const Float>&, const Containers::StridedArrayView1D<const void>&, Animation::Interpolation, void(*)(), Animation::Extrapolation, Animation::Extrapolation)
* with both @p before and @p after set to @p extrapolation.
*/
explicit AnimationTrackData(AnimationTrackTarget targetName, UnsignedLong target, AnimationTrackType type, AnimationTrackType resultType, const Containers::StridedArrayView1D<const Float>& keys, const Containers::StridedArrayView1D<const void>& values, Animation::Interpolation interpolation, void(*interpolator)(), Animation::Extrapolation extrapolation = Animation::Extrapolation::Constant) noexcept: AnimationTrackData{targetName, target, type, resultType, keys, values, interpolation, interpolator, extrapolation, extrapolation} {}
/** @overload
* @m_since_latest
*
* Equivalent to calling @ref AnimationTrackData(AnimationTrackTarget, UnsignedLong, AnimationTrackType, AnimationTrackType, const Containers::StridedArrayView1D<const Float>&, const Containers::StridedArrayView1D<const void>&, Animation::Interpolation, void(*)(), Animation::Extrapolation, Animation::Extrapolation)
* with both @p type and @p resultType set to @p type, and both
* @p before and @p after set to @p extrapolation.
*/
explicit AnimationTrackData(AnimationTrackTarget targetName, UnsignedLong target, AnimationTrackType type, const Containers::StridedArrayView1D<const Float>& keys, const Containers::StridedArrayView1D<const void>& values, Animation::Interpolation interpolation, void(*interpolator)(), Animation::Extrapolation extrapolation = Animation::Extrapolation::Constant) noexcept: AnimationTrackData{targetName, target, type, keys, values, interpolation, interpolator, extrapolation, extrapolation} {}
/**
* @brief Type-erased constructor with custom interpolator
* @param targetName Track target name
* @param target Track target ID
* @param type Value type
* @param resultType Result type
* @param keys Frame keys
* @param values Frame values
* @param interpolator Interpolator function
* @param before Extrapolation behavior before
* @param after Extrapolation behavior after
* @m_since_latest
*
* Calls @ref AnimationTrackData(AnimationTrackTarget, UnsignedLong, AnimationTrackType, AnimationTrackType, const Containers::StridedArrayView1D<const Float>&, const Containers::StridedArrayView1D<const void>&, Animation::Interpolation, void(*)(), Animation::Extrapolation, Animation::Extrapolation)
* with @p interpolation set to @ref Animation::Interpolation::Custom.
*/
explicit AnimationTrackData(AnimationTrackTarget targetName, UnsignedLong target, AnimationTrackType type, AnimationTrackType resultType, const Containers::StridedArrayView1D<const Float>& keys, const Containers::StridedArrayView1D<const void>& values, void(*interpolator)(), Animation::Extrapolation before, Animation::Extrapolation after) noexcept: AnimationTrackData{targetName, target, type, resultType, keys, values, Animation::Interpolation::Custom, interpolator, before, after} {}
/** @overload
* @m_since_latest
*
* Equivalent to calling @ref AnimationTrackData(AnimationTrackTarget, UnsignedLong, AnimationTrackType, AnimationTrackType, const Containers::StridedArrayView1D<const Float>&, const Containers::StridedArrayView1D<const void>&, void(*)(), Extrapolation, Extrapolation)
* with both @p type and @p resultType set to @p type.
*/
explicit AnimationTrackData(AnimationTrackTarget targetName, UnsignedLong target, AnimationTrackType type, const Containers::StridedArrayView1D<const Float>& keys, const Containers::StridedArrayView1D<const void>& values, void(*interpolator)(), Animation::Extrapolation before, Animation::Extrapolation after) noexcept: AnimationTrackData{targetName, target, type, type, keys, values, interpolator, before, after} {}
/** @overload
* @m_since_latest
*
* Equivalent to calling @ref AnimationTrackData(AnimationTrackTarget, UnsignedLong, AnimationTrackType, AnimationTrackType, const Containers::StridedArrayView1D<const Float>&, const Containers::StridedArrayView1D<const void>&, void(*)(), Extrapolation, Extrapolation)
* with both @p before and @p after set to @p extrapolation.
*/
explicit AnimationTrackData(AnimationTrackTarget targetName, UnsignedLong target, AnimationTrackType type, AnimationTrackType resultType, const Containers::StridedArrayView1D<const Float>& keys, const Containers::StridedArrayView1D<const void>& values, void(*interpolator)(), Animation::Extrapolation extrapolation = Animation::Extrapolation::Constant) noexcept: AnimationTrackData{targetName, target, type, resultType, keys, values, interpolator, extrapolation, extrapolation} {}
/** @overload
* @m_since_latest
*
* Equivalent to calling @ref AnimationTrackData(AnimationTrackTarget, UnsignedLong, AnimationTrackType, AnimationTrackType, const Containers::StridedArrayView1D<const Float>&, const Containers::StridedArrayView1D<const void>&, void(*)(), Extrapolation, Extrapolation)
* with both @p type and @p resultType set to @p type, and both
* @p before and @p after set to @p extrapolation.
*/
explicit AnimationTrackData(AnimationTrackTarget targetName, UnsignedLong target, AnimationTrackType type, const Containers::StridedArrayView1D<const Float>& keys, const Containers::StridedArrayView1D<const void>& values, void(*interpolator)(), Animation::Extrapolation extrapolation = Animation::Extrapolation::Constant) noexcept: AnimationTrackData{targetName, target, type, keys, values, interpolator, extrapolation, extrapolation} {}
#ifdef MAGNUM_BUILD_DEPRECATED
/**
* @brief Type-erased constructor
* @param type Value type
@ -359,30 +503,112 @@ class MAGNUM_TRADE_EXPORT AnimationTrackData {
*
* Expects that @p view key and value strides both fit into signed
* 16-bit values and that keyframe count fits into 32 bits.
*
* @m_deprecated_since_latest Use either the typed
* @ref AnimationTrackData(AnimationTrackTarget, UnsignedLong, const Animation::TrackView<const Float, const V, R>&)
* constructor or the type-erased
* @ref AnimationTrackData(AnimationTrackTarget, UnsignedLong, AnimationTrackType, AnimationTrackType, const Containers::StridedArrayView1D<const Float>&, const Containers::StridedArrayView1D<const void>&, Animation::Interpolation, Animation::Extrapolation, Animation::Extrapolation)
* etc. constructors instead.
*/
/** @todo stop taking TrackViewStorage and instead directly take the
key/value views, interpolator/interpolation and extrapolation --
it's just 6 overloads and makes usage much better */
explicit AnimationTrackData(AnimationTrackType type, AnimationTrackType resultType, AnimationTrackTarget targetName, UnsignedLong target, const Animation::TrackViewStorage<const Float>& view) noexcept;
explicit CORRADE_DEPRECATED("use either the typed TrackView constructor or the type-erased constructors taking key/value views directly") AnimationTrackData(AnimationTrackType type, AnimationTrackType resultType, AnimationTrackTarget targetName, UnsignedLong target, const Animation::TrackViewStorage<const Float>& view) noexcept: AnimationTrackData{targetName, target, type, resultType, view.keys(), view.values(), view.interpolation(), view.interpolator(), view.before(), view.after()} {}
/** @overload
*
* Equivalent to the above with @p type used as both value type and
* result type.
*
* @m_deprecated_since_latest Use either the typed
* @ref AnimationTrackData(AnimationTrackTarget, UnsignedLong, const Animation::TrackView<const Float, const V, R>&)
* constructor or the type-erased
* @ref AnimationTrackData(AnimationTrackTarget, UnsignedLong, AnimationTrackType, const Containers::StridedArrayView1D<const Float>&, const Containers::StridedArrayView1D<const void>&, Animation::Interpolation, Animation::Extrapolation, Animation::Extrapolation)
* etc. constructors instead.
*/
explicit AnimationTrackData(AnimationTrackType type, AnimationTrackTarget targetName, UnsignedLong target, const Animation::TrackViewStorage<const Float>& view) noexcept: AnimationTrackData{type, type, targetName, target, view} {}
explicit CORRADE_DEPRECATED("use either the typed TrackView constructor or the type-erased constructors taking key/value views directly") AnimationTrackData(AnimationTrackType type, AnimationTrackTarget targetName, UnsignedLong target, const Animation::TrackViewStorage<const Float>& view) noexcept: AnimationTrackData{targetName, target, type, view.keys(), view.values(), view.interpolation(), view.interpolator(), view.before(), view.after()} {}
#endif
/**
* @brief Constructor
* @brief Construct with generic interpolation behavior
* @param targetName Track target name
* @param target Track target ID
* @param view @ref Animation::TrackView instance
* @param keys Frame keys
* @param values Frame values
* @param interpolation Interpolation behavior
* @param before Extrapolation behavior before
* @param after Extrapolation behavior after
* @m_since_latest
*
* Detects @ref AnimationTrackType from @p values and delegates to
* @ref AnimationTrackData(AnimationTrackTarget, UnsignedLong, AnimationTrackType, AnimationTrackType, const Containers::StridedArrayView1D<const Float>&, const Containers::StridedArrayView1D<const void>&, Animation::Interpolation, Animation::Extrapolation, Animation::Extrapolation).
*/
template<class V, class R = Animation::ResultOf<V>> AnimationTrackData(AnimationTrackTarget targetName, UnsignedLong target, const Containers::StridedArrayView1D<const Float>& keys, const Containers::StridedArrayView1D<V>& values, Animation::Interpolation interpolation, Animation::Extrapolation before, Animation::Extrapolation after) noexcept;
/** @overload
* @m_since_latest
*
* Equivalent to calling @ref AnimationTrackData(AnimationTrackTarget, UnsignedLong, const Containers::StridedArrayView1D<const Float>&, const Containers::StridedArrayView1D<V>&, Animation::Interpolation, Animation::Extrapolation, Animation::Extrapolation)
* with both @p before and @p after set to @p extrapolation.
*/
template<class V, class R = Animation::ResultOf<V>> AnimationTrackData(AnimationTrackTarget targetName, UnsignedLong target, const Containers::StridedArrayView1D<const Float>& keys, const Containers::StridedArrayView1D<V>& values, Animation::Interpolation interpolation, Animation::Extrapolation extrapolation = Animation::Extrapolation::Constant) noexcept: AnimationTrackData{targetName, target, keys, values, interpolation, extrapolation, extrapolation} {}
/**
* @brief Construct with both generic and custom interpolator
* @param targetName Track target name
* @param target Track target ID
* @param keys Frame keys
* @param values Frame values
* @param interpolation Interpolation behavior
* @param interpolator Interpolator function
* @param before Extrapolation behavior before
* @param after Extrapolation behavior after
* @m_since_latest
*
* Detects @ref AnimationTrackType from @p values and delegates to
* @ref AnimationTrackData(AnimationTrackTarget, UnsignedLong, AnimationTrackType, AnimationTrackType, const Containers::StridedArrayView1D<const Float>&, const Containers::StridedArrayView1D<const void>&, Animation::Interpolation, void(*)(), Animation::Extrapolation, Animation::Extrapolation).
*/
template<class V, class R = Animation::ResultOf<V>> AnimationTrackData(AnimationTrackTarget targetName, UnsignedLong target, const Containers::StridedArrayView1D<const Float>& keys, const Containers::StridedArrayView1D<V>& values, Animation::Interpolation interpolation, R(*interpolator)(const typename std::remove_const<V>::type&, const typename std::remove_const<V>::type&, Float), Animation::Extrapolation before, Animation::Extrapolation after) noexcept;
/** @overload
* @m_since_latest
*
* Equivalent to calling @ref AnimationTrackData(AnimationTrackTarget, UnsignedLong, const Containers::StridedArrayView1D<const Float>&, const Containers::StridedArrayView1D<const V>&, Animation::Interpolation, R(*)(const V&, const V&, Float), Animation::Extrapolation, Animation::Extrapolation)
* with both @p before and @p after set to @p extrapolation.
*/
template<class V, class R = Animation::ResultOf<V>> AnimationTrackData(AnimationTrackTarget targetName, UnsignedLong target, const Containers::StridedArrayView1D<const Float>& keys, const Containers::StridedArrayView1D<V>& values, Animation::Interpolation interpolation, R(*interpolator)(const typename std::remove_const<V>::type&, const typename std::remove_const<V>::type&, Float), Animation::Extrapolation extrapolation = Animation::Extrapolation::Constant) noexcept: AnimationTrackData{targetName, target, keys, values, interpolation, interpolator, extrapolation, extrapolation} {}
/**
* @brief Construct with custom interpolator
* @param targetName Track target name
* @param target Track target ID
* @param keys Frame keys
* @param values Frame values
* @param interpolator Interpolator function
* @param before Extrapolation behavior before
* @param after Extrapolation behavior after
* @m_since_latest
*
* Calls @ref AnimationTrackData(AnimationTrackTarget, UnsignedLong, AnimationTrackType, AnimationTrackType, const Containers::StridedArrayView1D<const Float>&, const Containers::StridedArrayView1D<const V>&, Interpolation, R(*)(const V&, const V&, Float), Extrapolation, Extrapolation)
* with @p interpolation set to @ref Animation::Interpolation::Custom.
*/
template<class V, class R = Animation::ResultOf<V>> AnimationTrackData(AnimationTrackTarget targetName, UnsignedLong target, const Containers::StridedArrayView1D<const Float>& keys, const Containers::StridedArrayView1D<V>& values, R(*interpolator)(const typename std::remove_const<V>::type&, const typename std::remove_const<V>::type&, Float), Animation::Extrapolation before, Animation::Extrapolation after) noexcept: AnimationTrackData{targetName, target, keys, values, Animation::Interpolation::Custom, interpolator, before, after} {}
/** @overload
* @m_since_latest
*
* Equivalent to calling @ref AnimationTrackData(AnimationTrackTarget, UnsignedLong, const Containers::StridedArrayView1D<const Float>&, const Containers::StridedArrayView1D<const V>&, R(*)(const V&, const V&, Float), Extrapolation, Extrapolation)
* with both @p before and @p after set to @p extrapolation.
*/
template<class V, class R = Animation::ResultOf<V>> AnimationTrackData(AnimationTrackTarget targetName, UnsignedLong target, const Containers::StridedArrayView1D<const Float>& keys, const Containers::StridedArrayView1D<V>& values, R(*interpolator)(const typename std::remove_const<V>::type&, const typename std::remove_const<V>::type&, Float), Animation::Extrapolation extrapolation = Animation::Extrapolation::Constant) noexcept: AnimationTrackData{targetName, target, keys, values, interpolator, extrapolation, extrapolation} {}
/**
* @brief Construct from a track view
* @param targetName Track target name
* @param target Track target ID
* @param view Track view
* @m_since{2020,06}
*
* Detects @ref AnimationTrackType from @p view type and delegates to
* @ref AnimationTrackData(AnimationTrackType, AnimationTrackType, AnimationTrackTarget, UnsignedLong, Animation::TrackViewStorage<const Float>).
* Delegates to @ref AnimationTrackData(AnimationTrackTarget, UnsignedLong, AnimationTrackType, AnimationTrackType, const Containers::StridedArrayView1D<const Float>&, const Containers::StridedArrayView1D<const V>&, Animation::Interpolation, R(*)(const V&, const V&, Float), Animation::Extrapolation, Animation::Extrapolation).
*/
template<class V, class R> explicit AnimationTrackData(AnimationTrackTarget targetName, UnsignedLong target, const Animation::TrackView<const Float, const V, R>& view) noexcept;
template<class V, class R = Animation::ResultOf<V>> explicit AnimationTrackData(AnimationTrackTarget targetName, UnsignedLong target, const Animation::TrackView<const Float, const V, R>& view) noexcept: AnimationTrackData{targetName, target, view.keys(), view.values(), view.interpolation(), view.interpolator(), view.before(), view.after()} {}
/**
* @brief Value type
@ -820,7 +1046,9 @@ namespace Implementation {
/* LCOV_EXCL_STOP */
}
template<class V, class R> inline AnimationTrackData::AnimationTrackData(AnimationTrackTarget targetName, UnsignedLong target, const Animation::TrackView<const Float, const V, R>& view) noexcept: AnimationTrackData{Implementation::animationTypeFor<V>(), Implementation::animationTypeFor<R>(), targetName, target, view} {}
template<class V, class R> inline AnimationTrackData::AnimationTrackData(const AnimationTrackTarget targetName, const UnsignedLong target, const Containers::StridedArrayView1D<const Float>& keys, const Containers::StridedArrayView1D<V>& values, const Animation::Interpolation interpolation, const Animation::Extrapolation before, const Animation::Extrapolation after) noexcept: AnimationTrackData{targetName, target, Implementation::animationTypeFor<typename std::remove_const<V>::type>(), Implementation::animationTypeFor<R>(), keys, values, interpolation, before, after} {}
template<class V, class R> inline AnimationTrackData::AnimationTrackData(const AnimationTrackTarget targetName, const UnsignedLong target, const Containers::StridedArrayView1D<const Float>& keys, const Containers::StridedArrayView1D<V>& values, const Animation::Interpolation interpolation, R(*interpolator)(const typename std::remove_const<V>::type&, const typename std::remove_const<V>::type&, Float), const Animation::Extrapolation before, const Animation::Extrapolation after) noexcept: AnimationTrackData{targetName, target, Implementation::animationTypeFor<typename std::remove_const<V>::type>(), Implementation::animationTypeFor<R>(), keys, values, interpolation, reinterpret_cast<void(*)()>(interpolator), before, after} {}
template<class V, class R> Animation::TrackView<const Float, const V, R> AnimationData::track(UnsignedInt id) const {
const Animation::TrackViewStorage<const Float> storage = track(id);

5
src/Magnum/Trade/Test/AbstractImporterTest.cpp

@ -3852,9 +3852,8 @@ void AbstractImporterTest::animation() {
/* Verify that initializer list is converted to an array with
the default deleter and not something disallowed */
if(id == 7) return AnimationData{nullptr, {
AnimationTrackData{AnimationTrackType::Vector3,
AnimationTrackTarget::Scaling3D, 0, {}}
}, &state};
AnimationTrackData{AnimationTrackTarget::Scaling3D, 0, AnimationTrackType::Vector3, nullptr, nullptr, Animation::Interpolation::Constant}
}, &state};
return AnimationData{{}, {}};
}
} importer;

379
src/Magnum/Trade/Test/AnimationDataTest.cpp

@ -45,10 +45,23 @@ struct AnimationDataTest: TestSuite::Tester {
void debugTrackTarget();
void debugTrackTargetPacked();
void constructTrack();
void constructTrackResultType();
void constructTrackTemplate();
void constructTrackDefault();
void constructTrack();
void constructTrackTypeErased();
void constructTrackTypeErasedImplicitResultType();
void constructTrackExplicitInterpolator();
void constructTrackExplicitInterpolatorTypeErased();
void constructTrackExplicitInterpolatorTypeErasedImplicitResultType();
void constructTrackCustomInterpolator();
void constructTrackCustomInterpolatorTypeErased();
void constructTrackCustomInterpolatorTypeErasedImplicitResultType();
void constructTrackFromView();
#ifdef MAGNUM_BUILD_DEPRECATED
void constructTrackDeprecated();
void constructTrackDeprecatedImplicitResultType();
#endif
void constructTrackInconsitentViewSize();
void constructTrackUnknownInterpolator();
#ifndef CORRADE_TARGET_32BIT
void constructTrackWrongSize();
#endif
@ -93,10 +106,23 @@ AnimationDataTest::AnimationDataTest() {
&AnimationDataTest::debugTrackTarget,
&AnimationDataTest::debugTrackTargetPacked,
&AnimationDataTest::constructTrack,
&AnimationDataTest::constructTrackResultType,
&AnimationDataTest::constructTrackTemplate,
&AnimationDataTest::constructTrackDefault,
&AnimationDataTest::constructTrack,
&AnimationDataTest::constructTrackTypeErased,
&AnimationDataTest::constructTrackTypeErasedImplicitResultType,
&AnimationDataTest::constructTrackExplicitInterpolator,
&AnimationDataTest::constructTrackExplicitInterpolatorTypeErased,
&AnimationDataTest::constructTrackExplicitInterpolatorTypeErasedImplicitResultType,
&AnimationDataTest::constructTrackCustomInterpolator,
&AnimationDataTest::constructTrackCustomInterpolatorTypeErased,
&AnimationDataTest::constructTrackCustomInterpolatorTypeErasedImplicitResultType,
&AnimationDataTest::constructTrackFromView,
#ifdef MAGNUM_BUILD_DEPRECATED
&AnimationDataTest::constructTrackDeprecated,
&AnimationDataTest::constructTrackDeprecatedImplicitResultType,
#endif
&AnimationDataTest::constructTrackInconsitentViewSize,
&AnimationDataTest::constructTrackUnknownInterpolator,
#ifndef CORRADE_TARGET_32BIT
&AnimationDataTest::constructTrackWrongSize,
#endif
@ -196,22 +222,275 @@ void AnimationDataTest::debugTrackTargetPacked() {
CORRADE_COMPARE(out.str(), "Rotation3D Custom(120) 0x4242 Trade::AnimationTrackType::Float\n");
}
void AnimationDataTest::constructTrackDefault() {
AnimationTrackData data;
CORRADE_COMPARE(data.type(), AnimationTrackType{});
CORRADE_COMPARE(data.resultType(), AnimationTrackType{});
CORRADE_COMPARE(data.targetName(), AnimationTrackTarget{});
CORRADE_COMPARE(data.target(), 0);
CORRADE_COMPARE(data.track().interpolation(), Animation::Interpolation::Constant);
CORRADE_COMPARE(data.track().before(), Animation::Extrapolation::Extrapolated);
CORRADE_COMPARE(data.track().after(), Animation::Extrapolation::Extrapolated);
CORRADE_COMPARE(data.track().size(), 0);
CORRADE_COMPARE(data.track().interpolator(), nullptr);
CORRADE_COMPARE(data.track().keys().data(), nullptr);
CORRADE_COMPARE(data.track().values().data(), nullptr);
}
void AnimationDataTest::constructTrack() {
struct Keyframe {
Float time;
CubicHermite2D value;
} keyframes[3]{};
AnimationTrackData data{
AnimationTrackTarget::Scaling2D, 42,
Containers::stridedArrayView(keyframes).slice(&Keyframe::time),
Containers::stridedArrayView(keyframes).slice(&Keyframe::value),
Animation::Interpolation::Linear,
Animation::Extrapolation::Constant};
CORRADE_COMPARE(data.targetName(), AnimationTrackTarget::Scaling2D);
CORRADE_COMPARE(data.target(), 42);
CORRADE_COMPARE(data.type(), AnimationTrackType::CubicHermite2D);
CORRADE_COMPARE(data.resultType(), AnimationTrackType::Vector2);
CORRADE_COMPARE(data.track().keys().data(), &keyframes[0].time);
CORRADE_COMPARE(data.track().values().data(), &keyframes[0].value);
CORRADE_COMPARE(data.track().interpolation(), Animation::Interpolation::Linear);
CORRADE_COMPARE(data.track().interpolator(), reinterpret_cast<void(*)()>(animationInterpolatorFor<CubicHermite2D>(Animation::Interpolation::Linear)));
CORRADE_COMPARE(data.track().before(), Animation::Extrapolation::Constant);
CORRADE_COMPARE(data.track().after(), Animation::Extrapolation::Constant);
}
void AnimationDataTest::constructTrackTypeErased() {
struct Keyframe {
Float time;
CubicHermite3D value;
} keyframes[3]{};
AnimationTrackData data{
AnimationTrackTarget::Translation3D, 42,
AnimationTrackType::CubicHermite3D,
AnimationTrackType::Vector3,
Containers::stridedArrayView(keyframes).slice(&Keyframe::time),
Containers::stridedArrayView(keyframes).slice(&Keyframe::value),
Animation::Interpolation::Spline,
Animation::Extrapolation::DefaultConstructed};
CORRADE_COMPARE(data.targetName(), AnimationTrackTarget::Translation3D);
CORRADE_COMPARE(data.target(), 42);
CORRADE_COMPARE(data.type(), AnimationTrackType::CubicHermite3D);
CORRADE_COMPARE(data.resultType(), AnimationTrackType::Vector3);
CORRADE_COMPARE(data.track().keys().data(), &keyframes[0].time);
CORRADE_COMPARE(data.track().values().data(), &keyframes[0].value);
CORRADE_COMPARE(data.track().interpolation(), Animation::Interpolation::Spline);
CORRADE_COMPARE(data.track().interpolator(), reinterpret_cast<void(*)()>(animationInterpolatorFor<CubicHermite3D>(Animation::Interpolation::Spline)));
CORRADE_COMPARE(data.track().before(), Animation::Extrapolation::DefaultConstructed);
CORRADE_COMPARE(data.track().after(), Animation::Extrapolation::DefaultConstructed);
}
void AnimationDataTest::constructTrackTypeErasedImplicitResultType() {
struct Keyframe {
Float time;
Quaternion value;
} keyframes[3]{};
AnimationTrackData data{
AnimationTrackTarget::Rotation3D, 42,
AnimationTrackType::Quaternion,
Containers::stridedArrayView(keyframes).slice(&Keyframe::time),
Containers::stridedArrayView(keyframes).slice(&Keyframe::value),
Animation::Interpolation::Linear,
Animation::Extrapolation::DefaultConstructed};
CORRADE_COMPARE(data.targetName(), AnimationTrackTarget::Rotation3D);
CORRADE_COMPARE(data.target(), 42);
CORRADE_COMPARE(data.type(), AnimationTrackType::Quaternion);
CORRADE_COMPARE(data.resultType(), AnimationTrackType::Quaternion);
CORRADE_COMPARE(data.track().keys().data(), &keyframes[0].time);
CORRADE_COMPARE(data.track().values().data(), &keyframes[0].value);
CORRADE_COMPARE(data.track().interpolation(), Animation::Interpolation::Linear);
CORRADE_COMPARE(data.track().interpolator(), reinterpret_cast<void(*)()>(animationInterpolatorFor<Quaternion>(Animation::Interpolation::Linear)));
CORRADE_COMPARE(data.track().before(), Animation::Extrapolation::DefaultConstructed);
CORRADE_COMPARE(data.track().after(), Animation::Extrapolation::DefaultConstructed);
}
void AnimationDataTest::constructTrackExplicitInterpolator() {
struct Keyframe {
Float time;
CubicHermite2D value;
} keyframes[3]{};
AnimationTrackData data{
AnimationTrackTarget::Scaling2D, 42,
Containers::stridedArrayView(keyframes).slice(&Keyframe::time),
Containers::stridedArrayView(keyframes).slice(&Keyframe::value),
Animation::Interpolation::Spline,
Math::splerp,
Animation::Extrapolation::Constant};
CORRADE_COMPARE(data.targetName(), AnimationTrackTarget::Scaling2D);
CORRADE_COMPARE(data.target(), 42);
CORRADE_COMPARE(data.type(), AnimationTrackType::CubicHermite2D);
CORRADE_COMPARE(data.resultType(), AnimationTrackType::Vector2);
CORRADE_COMPARE(data.track().keys().data(), &keyframes[0].time);
CORRADE_COMPARE(data.track().values().data(), &keyframes[0].value);
CORRADE_COMPARE(data.track().interpolation(), Animation::Interpolation::Spline);
CORRADE_COMPARE(data.track().interpolator(), reinterpret_cast<void(*)()>(static_cast<Vector2(*)(const CubicHermite2D&, const CubicHermite2D&, Float)>(Math::splerp)));
CORRADE_COMPARE(data.track().before(), Animation::Extrapolation::Constant);
CORRADE_COMPARE(data.track().after(), Animation::Extrapolation::Constant);
}
void AnimationDataTest::constructTrackExplicitInterpolatorTypeErased() {
struct Keyframe {
Float time;
CubicHermite2D value;
} keyframes[3]{};
auto interpolator = reinterpret_cast<void(*)()>(static_cast<Vector2(*)(const CubicHermite2D&, const CubicHermite2D&, Float)>(Math::splerp));
AnimationTrackData data{
AnimationTrackTarget::Scaling2D, 42,
AnimationTrackType::CubicHermite2D,
AnimationTrackType::Vector2,
Containers::stridedArrayView(keyframes).slice(&Keyframe::time),
Containers::stridedArrayView(keyframes).slice(&Keyframe::value),
Animation::Interpolation::Spline,
interpolator,
Animation::Extrapolation::Constant};
CORRADE_COMPARE(data.targetName(), AnimationTrackTarget::Scaling2D);
CORRADE_COMPARE(data.target(), 42);
CORRADE_COMPARE(data.type(), AnimationTrackType::CubicHermite2D);
CORRADE_COMPARE(data.resultType(), AnimationTrackType::Vector2);
CORRADE_COMPARE(data.track().keys().data(), &keyframes[0].time);
CORRADE_COMPARE(data.track().values().data(), &keyframes[0].value);
CORRADE_COMPARE(data.track().interpolation(), Animation::Interpolation::Spline);
CORRADE_COMPARE(data.track().interpolator(), interpolator);
CORRADE_COMPARE(data.track().before(), Animation::Extrapolation::Constant);
CORRADE_COMPARE(data.track().after(), Animation::Extrapolation::Constant);
}
void AnimationDataTest::constructTrackExplicitInterpolatorTypeErasedImplicitResultType() {
struct Keyframe {
Float time;
Vector3 value;
} keyframes[3]{};
auto interpolator = reinterpret_cast<void(*)()>(static_cast<Vector3(*)(const Vector3&, const Vector3&, Float)>(Math::lerp));
AnimationTrackData data{
AnimationTrackTarget::Translation3D, 42,
Animation::TrackView<const Float, const Vector3>{
AnimationTrackType::Vector3,
Containers::stridedArrayView(keyframes).slice(&Keyframe::time),
Containers::stridedArrayView(keyframes).slice(&Keyframe::value),
Animation::Interpolation::Linear,
interpolator,
Animation::Extrapolation::DefaultConstructed};
CORRADE_COMPARE(data.targetName(), AnimationTrackTarget::Translation3D);
CORRADE_COMPARE(data.target(), 42);
CORRADE_COMPARE(data.type(), AnimationTrackType::Vector3);
CORRADE_COMPARE(data.resultType(), AnimationTrackType::Vector3);
CORRADE_COMPARE(data.track().keys().data(), &keyframes[0].time);
CORRADE_COMPARE(data.track().values().data(), &keyframes[0].value);
CORRADE_COMPARE(data.track().interpolation(), Animation::Interpolation::Linear);
CORRADE_COMPARE(data.track().interpolator(), interpolator);
CORRADE_COMPARE(data.track().before(), Animation::Extrapolation::DefaultConstructed);
CORRADE_COMPARE(data.track().after(), Animation::Extrapolation::DefaultConstructed);
}
void AnimationDataTest::constructTrackCustomInterpolator() {
struct Keyframe {
Float time;
CubicHermite2D value;
} keyframes[3]{};
AnimationTrackData data{
AnimationTrackTarget::Scaling2D, 42,
Containers::stridedArrayView(keyframes).slice(&Keyframe::time),
Containers::stridedArrayView(keyframes).slice(&Keyframe::value),
Math::splerp,
Animation::Extrapolation::Constant};
CORRADE_COMPARE(data.targetName(), AnimationTrackTarget::Scaling2D);
CORRADE_COMPARE(data.target(), 42);
CORRADE_COMPARE(data.type(), AnimationTrackType::CubicHermite2D);
CORRADE_COMPARE(data.resultType(), AnimationTrackType::Vector2);
CORRADE_COMPARE(data.track().keys().data(), &keyframes[0].time);
CORRADE_COMPARE(data.track().values().data(), &keyframes[0].value);
CORRADE_COMPARE(data.track().interpolation(), Animation::Interpolation::Custom);
CORRADE_COMPARE(data.track().interpolator(), reinterpret_cast<void(*)()>(static_cast<Vector2(*)(const CubicHermite2D&, const CubicHermite2D&, Float)>(Math::splerp)));
CORRADE_COMPARE(data.track().before(), Animation::Extrapolation::Constant);
CORRADE_COMPARE(data.track().after(), Animation::Extrapolation::Constant);
}
void AnimationDataTest::constructTrackCustomInterpolatorTypeErased() {
struct Keyframe {
Float time;
CubicHermite2D value;
} keyframes[3]{};
auto interpolator = reinterpret_cast<void(*)()>(static_cast<Vector2(*)(const CubicHermite2D&, const CubicHermite2D&, Float)>(Math::splerp));
AnimationTrackData data{
AnimationTrackTarget::Scaling2D, 42,
AnimationTrackType::CubicHermite2D,
AnimationTrackType::Vector2,
Containers::stridedArrayView(keyframes).slice(&Keyframe::time),
Containers::stridedArrayView(keyframes).slice(&Keyframe::value),
interpolator,
Animation::Extrapolation::Constant};
CORRADE_COMPARE(data.targetName(), AnimationTrackTarget::Scaling2D);
CORRADE_COMPARE(data.target(), 42);
CORRADE_COMPARE(data.type(), AnimationTrackType::CubicHermite2D);
CORRADE_COMPARE(data.resultType(), AnimationTrackType::Vector2);
CORRADE_COMPARE(data.track().keys().data(), &keyframes[0].time);
CORRADE_COMPARE(data.track().values().data(), &keyframes[0].value);
CORRADE_COMPARE(data.track().interpolation(), Animation::Interpolation::Custom);
CORRADE_COMPARE(data.track().interpolator(), interpolator);
CORRADE_COMPARE(data.track().before(), Animation::Extrapolation::Constant);
CORRADE_COMPARE(data.track().after(), Animation::Extrapolation::Constant);
}
void AnimationDataTest::constructTrackCustomInterpolatorTypeErasedImplicitResultType() {
struct Keyframe {
Float time;
Vector3 value;
} keyframes[3]{};
auto interpolator = reinterpret_cast<void(*)()>(static_cast<Vector3(*)(const Vector3&, const Vector3&, Float)>(Math::lerp));
AnimationTrackData data{
AnimationTrackTarget::Translation3D, 42,
AnimationTrackType::Vector3,
Containers::stridedArrayView(keyframes).slice(&Keyframe::time),
Containers::stridedArrayView(keyframes).slice(&Keyframe::value),
interpolator,
Animation::Extrapolation::DefaultConstructed};
CORRADE_COMPARE(data.targetName(), AnimationTrackTarget::Translation3D);
CORRADE_COMPARE(data.target(), 42);
CORRADE_COMPARE(data.type(), AnimationTrackType::Vector3);
CORRADE_COMPARE(data.resultType(), AnimationTrackType::Vector3);
CORRADE_COMPARE(data.track().keys().data(), &keyframes[0].time);
CORRADE_COMPARE(data.track().values().data(), &keyframes[0].value);
CORRADE_COMPARE(data.track().interpolation(), Animation::Interpolation::Custom);
CORRADE_COMPARE(data.track().interpolator(), interpolator);
CORRADE_COMPARE(data.track().before(), Animation::Extrapolation::DefaultConstructed);
CORRADE_COMPARE(data.track().after(), Animation::Extrapolation::DefaultConstructed);
}
void AnimationDataTest::constructTrackFromView() {
AnimationTrackData data{
AnimationTrackTarget::Translation3D, 42,
Animation::TrackView<const Float, const CubicHermite3D>{
nullptr,
Animation::Interpolation::Linear,
animationInterpolatorFor<Vector3>(Animation::Interpolation::Linear)}};
CORRADE_COMPARE(data.type(), AnimationTrackType::Vector3);
animationInterpolatorFor<CubicHermite3D>(Animation::Interpolation::Linear)}};
CORRADE_COMPARE(data.type(), AnimationTrackType::CubicHermite3D);
CORRADE_COMPARE(data.resultType(), AnimationTrackType::Vector3);
CORRADE_COMPARE(data.targetName(), AnimationTrackTarget::Translation3D);
CORRADE_COMPARE(data.target(), 42);
CORRADE_COMPARE(data.track().interpolation(), Animation::Interpolation::Linear);
}
void AnimationDataTest::constructTrackResultType() {
#ifdef MAGNUM_BUILD_DEPRECATED
void AnimationDataTest::constructTrackDeprecated() {
CORRADE_IGNORE_DEPRECATED_PUSH
AnimationTrackData data{
AnimationTrackType::CubicHermite3D,
AnimationTrackType::Vector3,
@ -220,6 +499,7 @@ void AnimationDataTest::constructTrackResultType() {
nullptr,
Animation::Interpolation::Linear,
animationInterpolatorFor<CubicHermite3D>(Animation::Interpolation::Linear)}};
CORRADE_IGNORE_DEPRECATED_POP
CORRADE_COMPARE(data.type(), AnimationTrackType::CubicHermite3D);
CORRADE_COMPARE(data.resultType(), AnimationTrackType::Vector3);
CORRADE_COMPARE(data.targetName(), AnimationTrackTarget::Translation3D);
@ -227,34 +507,62 @@ void AnimationDataTest::constructTrackResultType() {
CORRADE_COMPARE(data.track().interpolation(), Animation::Interpolation::Linear);
}
void AnimationDataTest::constructTrackTemplate() {
void AnimationDataTest::constructTrackDeprecatedImplicitResultType() {
CORRADE_IGNORE_DEPRECATED_PUSH
AnimationTrackData data{
AnimationTrackType::Vector3,
AnimationTrackTarget::Translation3D, 42,
Animation::TrackView<const Float, const CubicHermite3D>{
Animation::TrackView<const Float, const Vector3>{
nullptr,
Animation::Interpolation::Linear,
animationInterpolatorFor<CubicHermite3D>(Animation::Interpolation::Linear)}};
CORRADE_COMPARE(data.type(), AnimationTrackType::CubicHermite3D);
animationInterpolatorFor<Vector3>(Animation::Interpolation::Linear)}};
CORRADE_IGNORE_DEPRECATED_POP
CORRADE_COMPARE(data.type(), AnimationTrackType::Vector3);
CORRADE_COMPARE(data.resultType(), AnimationTrackType::Vector3);
CORRADE_COMPARE(data.targetName(), AnimationTrackTarget::Translation3D);
CORRADE_COMPARE(data.target(), 42);
CORRADE_COMPARE(data.track().interpolation(), Animation::Interpolation::Linear);
}
#endif
void AnimationDataTest::constructTrackDefault() {
AnimationTrackData data;
CORRADE_COMPARE(data.type(), AnimationTrackType{});
CORRADE_COMPARE(data.resultType(), AnimationTrackType{});
CORRADE_COMPARE(data.targetName(), AnimationTrackTarget{});
CORRADE_COMPARE(data.target(), 0);
void AnimationDataTest::constructTrackInconsitentViewSize() {
CORRADE_SKIP_IF_NO_ASSERT();
CORRADE_COMPARE(data.track().interpolation(), Animation::Interpolation::Constant);
CORRADE_COMPARE(data.track().before(), Animation::Extrapolation::Extrapolated);
CORRADE_COMPARE(data.track().after(), Animation::Extrapolation::Extrapolated);
CORRADE_COMPARE(data.track().size(), 0);
CORRADE_COMPARE(data.track().interpolator(), nullptr);
CORRADE_COMPARE(data.track().keys().data(), nullptr);
CORRADE_COMPARE(data.track().values().data(), nullptr);
Float time[2];
Vector2 value[3];
std::ostringstream out;
Error redirectError{&out};
AnimationTrackData{
AnimationTrackTarget::Rotation3D, 42,
Containers::stridedArrayView(time),
Containers::stridedArrayView(value),
Animation::Interpolation::Linear};
CORRADE_COMPARE(out.str(), "Trade::AnimationTrackData: expected key and value view to have the same size but got 2 and 3\n");
}
void AnimationDataTest::constructTrackUnknownInterpolator() {
CORRADE_SKIP_IF_NO_ASSERT();
std::ostringstream out;
Error redirectError{&out};
AnimationTrackData{
AnimationTrackTarget::Rotation3D, 42,
AnimationTrackType::CubicHermite1D,
AnimationTrackType::Vector2,
nullptr,
nullptr,
Animation::Interpolation::Linear};
AnimationTrackData{
AnimationTrackTarget::Rotation3D, 42,
AnimationTrackType::Vector3,
nullptr,
nullptr,
Animation::Interpolation::Spline};
CORRADE_COMPARE(out.str(),
"Trade::AnimationTrackData: can't deduce interpolator function for Trade::AnimationTrackType::CubicHermite1D, Trade::AnimationTrackType::Vector2 and Animation::Interpolation::Linear\n"
/* This assertion is from the delegated-to interpolationFor(), which
unfortunately doesn't print the types */
"Animation::interpolatorFor(): can't deduce interpolator function for Animation::Interpolation::Spline\n");
}
#ifndef CORRADE_TARGET_32BIT
@ -739,9 +1047,8 @@ void AnimationDataTest::trackWrongIndex() {
Error redirectError{&out};
AnimationData data{nullptr, {
AnimationTrackData{AnimationTrackType::Vector3,
AnimationTrackTarget::Scaling3D, 0, {}}
}};
AnimationTrackData{AnimationTrackTarget::Scaling3D, 0, AnimationTrackType::Vector3, nullptr, nullptr, Animation::Interpolation::Constant}
}};
data.trackType(1);
data.trackResultType(1);
data.trackTargetName(1);
@ -765,10 +1072,8 @@ void AnimationDataTest::trackWrongType() {
Error redirectError{&out};
AnimationData data{nullptr, {
AnimationTrackData{AnimationTrackType::Vector3i,
AnimationTrackType::Vector3,
AnimationTrackTarget::Scaling3D, 0, {}}
}};
AnimationTrackData{AnimationTrackTarget::Scaling3D, 0, AnimationTrackType::Vector3i, AnimationTrackType::Vector3, nullptr, nullptr, Animation::Interpolation::Constant, nullptr}
}};
data.track<Vector3>(0);
@ -782,10 +1087,8 @@ void AnimationDataTest::trackWrongResultType() {
Error redirectError{&out};
AnimationData data{nullptr, {
AnimationTrackData{AnimationTrackType::Vector3i,
AnimationTrackType::Vector3,
AnimationTrackTarget::Scaling3D, 0, {}}
}};
AnimationTrackData{AnimationTrackTarget::Scaling3D, 0, AnimationTrackType::Vector3i, AnimationTrackType::Vector3, nullptr, nullptr, Animation::Interpolation::Constant, nullptr}
}};
data.track<Vector3i, Vector2>(0);

Loading…
Cancel
Save