diff --git a/doc/changelog.dox b/doc/changelog.dox index dedff6a26..ff5043bc1 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -280,6 +280,9 @@ See also: plugin if you specify `--importer raw:<format>`; and save raw imported data instead of going through a converter plugin if you specify `--converter raw` +- New convenience @ref Trade::AnimationTrackData constructor taking a + templated @ref Animation::TrackView type, autodetecting value and result + @ref Trade::AnimationTrackType out of it @subsection changelog-latest-buildsystem Build system diff --git a/src/Magnum/Trade/AnimationData.h b/src/Magnum/Trade/AnimationData.h index 0935c4813..02f13ebf3 100644 --- a/src/Magnum/Trade/AnimationData.h +++ b/src/Magnum/Trade/AnimationData.h @@ -231,7 +231,7 @@ class AnimationTrackData { /*implicit*/ AnimationTrackData() noexcept: _type{}, _resultType{}, _targetType{}, _target{}, _view{} {} /** - * @brief Constructor + * @brief Type-erased constructor * @param type Value type * @param resultType Result type * @param targetType Track target type @@ -247,6 +247,18 @@ class AnimationTrackData { */ /*implicit*/ AnimationTrackData(AnimationTrackType type, AnimationTrackTargetType targetType, UnsignedInt target, Animation::TrackViewStorage view) noexcept: _type{type}, _resultType{type}, _targetType{targetType}, _target{target}, _view{view} {} + /** + * @brief Constructor + * @param targetType Track target type + * @param target Track target + * @param view @ref Animation::TrackView instance + * @m_since_latest + * + * Detects @ref AnimationTrackType from @p view type and delegates to + * @ref AnimationTrackData(AnimationTrackType, AnimationTrackType, AnimationTrackTargetType, UnsignedInt, Animation::TrackViewStorage). + */ + template /*implicit*/ AnimationTrackData(AnimationTrackTargetType targetType, UnsignedInt target, Animation::TrackView view) noexcept; + private: friend AnimationData; @@ -611,6 +623,8 @@ namespace Implementation { } #endif +template inline AnimationTrackData::AnimationTrackData(AnimationTrackTargetType targetType, UnsignedInt target, Animation::TrackView view) noexcept: AnimationTrackData{Implementation::animationTypeFor(), Implementation::animationTypeFor(), targetType, target, view} {} + template const Animation::TrackView& AnimationData::track(UnsignedInt id) const { const Animation::TrackViewStorage& storage = track(id); CORRADE_ASSERT(Implementation::animationTypeFor() == _tracks[id]._type, "Trade::AnimationData::track(): improper type requested for" << _tracks[id]._type, (static_cast&>(storage))); diff --git a/src/Magnum/Trade/Test/AnimationDataTest.cpp b/src/Magnum/Trade/Test/AnimationDataTest.cpp index c61228eef..f5072512b 100644 --- a/src/Magnum/Trade/Test/AnimationDataTest.cpp +++ b/src/Magnum/Trade/Test/AnimationDataTest.cpp @@ -27,6 +27,7 @@ #include #include +#include "Magnum/Math/CubicHermite.h" #include "Magnum/Math/Quaternion.h" #include "Magnum/Trade/AnimationData.h" @@ -35,6 +36,11 @@ namespace Magnum { namespace Trade { namespace Test { namespace { struct AnimationDataTest: TestSuite::Tester { explicit AnimationDataTest(); + void constructTrackData(); + void constructTrackDataResultType(); + void constructTrackDataTemplate(); + void constructTrackDataDefault(); + void construct(); void constructNotOwned(); void constructImplicitDuration(); @@ -46,8 +52,6 @@ struct AnimationDataTest: TestSuite::Tester { void constructCopy(); void constructMove(); - void constructTrackDataDefault(); - void mutableAccessNotAllowed(); void trackCustomResultType(); @@ -70,7 +74,12 @@ struct { }; AnimationDataTest::AnimationDataTest() { - addTests({&AnimationDataTest::construct, + addTests({&AnimationDataTest::constructTrackData, + &AnimationDataTest::constructTrackDataResultType, + &AnimationDataTest::constructTrackDataTemplate, + &AnimationDataTest::constructTrackDataDefault, + + &AnimationDataTest::construct, &AnimationDataTest::constructImplicitDuration, &AnimationDataTest::constructImplicitDurationEmpty}); @@ -84,8 +93,6 @@ AnimationDataTest::AnimationDataTest() { &AnimationDataTest::constructCopy, &AnimationDataTest::constructMove, - &AnimationDataTest::constructTrackDataDefault, - &AnimationDataTest::mutableAccessNotAllowed, &AnimationDataTest::trackCustomResultType, @@ -101,6 +108,61 @@ AnimationDataTest::AnimationDataTest() { using namespace Math::Literals; +void AnimationDataTest::constructTrackData() { + AnimationTrackData trackData{ + AnimationTrackType::Vector3, + AnimationTrackTargetType::Translation3D, 42, + Animation::TrackView{ + nullptr, + Animation::Interpolation::Linear, + animationInterpolatorFor(Animation::Interpolation::Linear)}}; + AnimationData data{nullptr, Containers::Array{Containers::InPlaceInit, {trackData}}}; + CORRADE_COMPARE(data.trackType(0), AnimationTrackType::Vector3); + CORRADE_COMPARE(data.trackResultType(0), AnimationTrackType::Vector3); + CORRADE_COMPARE(data.trackTargetType(0), AnimationTrackTargetType::Translation3D); + CORRADE_COMPARE(data.trackTarget(0), 42); + CORRADE_COMPARE(data.track(0).interpolation(), Animation::Interpolation::Linear); +} + +void AnimationDataTest::constructTrackDataResultType() { + AnimationTrackData trackData{ + AnimationTrackType::CubicHermite3D, + AnimationTrackType::Vector3, + AnimationTrackTargetType::Translation3D, 42, + Animation::TrackView{ + nullptr, + Animation::Interpolation::Linear, + animationInterpolatorFor(Animation::Interpolation::Linear)}}; + AnimationData data{nullptr, Containers::Array{Containers::InPlaceInit, {trackData}}}; + CORRADE_COMPARE(data.trackType(0), AnimationTrackType::CubicHermite3D); + CORRADE_COMPARE(data.trackResultType(0), AnimationTrackType::Vector3); + CORRADE_COMPARE(data.trackTargetType(0), AnimationTrackTargetType::Translation3D); + CORRADE_COMPARE(data.trackTarget(0), 42); + CORRADE_COMPARE(data.track(0).interpolation(), Animation::Interpolation::Linear); +} + +void AnimationDataTest::constructTrackDataTemplate() { + AnimationTrackData trackData{ + AnimationTrackTargetType::Translation3D, 42, + Animation::TrackView{ + nullptr, + Animation::Interpolation::Linear, + animationInterpolatorFor(Animation::Interpolation::Linear)}}; + AnimationData data{nullptr, Containers::Array{Containers::InPlaceInit, {trackData}}}; + CORRADE_COMPARE(data.trackType(0), AnimationTrackType::CubicHermite3D); + CORRADE_COMPARE(data.trackResultType(0), AnimationTrackType::Vector3); + CORRADE_COMPARE(data.trackTargetType(0), AnimationTrackTargetType::Translation3D); + CORRADE_COMPARE(data.trackTarget(0), 42); + CORRADE_COMPARE(data.track(0).interpolation(), Animation::Interpolation::Linear); +} + +void AnimationDataTest::constructTrackDataDefault() { + AnimationTrackData data; + /* no public accessors here, so nothing to check -- and such a track + shouldn't get added to AnimationData anyway */ + CORRADE_VERIFY(true); +} + void AnimationDataTest::construct() { /* Ain't the prettiest, but trust me: you won't do it like this in the plugins anyway */ @@ -117,15 +179,13 @@ void AnimationDataTest::construct() { const int state = 5; AnimationData data{std::move(buffer), Containers::Array{Containers::InPlaceInit, { - {AnimationTrackType::Vector3, - AnimationTrackTargetType::Translation3D, 42, + {AnimationTrackTargetType::Translation3D, 42, Animation::TrackView{ {view, &view[0].time, view.size(), sizeof(Data)}, {view, &view[0].position, view.size(), sizeof(Data)}, Animation::Interpolation::Constant, animationInterpolatorFor(Animation::Interpolation::Constant)}}, - {AnimationTrackType::Quaternion, - AnimationTrackTargetType::Rotation3D, 1337, + {AnimationTrackTargetType::Rotation3D, 1337, Animation::TrackView{ {view, &view[0].time, view.size(), sizeof(Data)}, {view, &view[0].rotation, view.size(), sizeof(Data)}, @@ -189,14 +249,12 @@ void AnimationDataTest::constructImplicitDuration() { const int state = 5; AnimationData data{std::move(buffer), Containers::Array{Containers::InPlaceInit, { - {AnimationTrackType::Bool, - AnimationTrackTargetType(129), 0, + {AnimationTrackTargetType(129), 0, Animation::TrackView{ {view, &view[0].time, 2, sizeof(Data)}, {view, &view[0].value, 2, sizeof(Data)}, Animation::Interpolation::Constant}}, - {AnimationTrackType::Bool, - AnimationTrackTargetType(130), 1, + {AnimationTrackTargetType(130), 1, Animation::TrackView{ {view, &view[2].time, 2, sizeof(Data)}, {view, &view[2].value, 2, sizeof(Data)}, @@ -259,8 +317,7 @@ void AnimationDataTest::constructNotOwned() { const int state = 5; AnimationData data{instanceData.dataFlags, keyframes, Containers::Array{Containers::InPlaceInit, { - {AnimationTrackType::Vector3, - AnimationTrackTargetType::Translation3D, 42, + {AnimationTrackTargetType::Translation3D, 42, Animation::TrackView{ keyframes, Animation::Interpolation::Constant, @@ -308,8 +365,7 @@ void AnimationDataTest::constructImplicitDurationNotOwned() { const int state = 5; AnimationData data{instanceData.dataFlags, keyframes, Containers::Array{Containers::InPlaceInit, { - {AnimationTrackType::Bool, - AnimationTrackTargetType(129), 0, + {AnimationTrackTargetType(129), 0, Animation::TrackView{keyframes, Animation::Interpolation::Constant}}, }}, &state}; @@ -381,15 +437,13 @@ void AnimationDataTest::constructMove() { const int state = 5; AnimationData a{std::move(buffer), Containers::Array{Containers::InPlaceInit, { - {AnimationTrackType::Vector3, - AnimationTrackTargetType::Translation3D, 42, + {AnimationTrackTargetType::Translation3D, 42, Animation::TrackView{ {view, &view[0].time, view.size(), sizeof(Data)}, {view, &view[0].position, view.size(), sizeof(Data)}, Animation::Interpolation::Constant, animationInterpolatorFor(Animation::Interpolation::Constant)}}, - {AnimationTrackType::Quaternion, - AnimationTrackTargetType::Rotation3D, 1337, + {AnimationTrackTargetType::Rotation3D, 1337, Animation::TrackView{ {view, &view[0].time, view.size(), sizeof(Data)}, {view, &view[0].rotation, view.size(), sizeof(Data)}, @@ -465,11 +519,6 @@ void AnimationDataTest::constructMove() { CORRADE_VERIFY(std::is_nothrow_move_assignable::value); } -void AnimationDataTest::constructTrackDataDefault() { - AnimationTrackData data; - CORRADE_VERIFY(true); /* no public accessors here, so nothing to check */ -} - void AnimationDataTest::mutableAccessNotAllowed() { const std::pair keyframes[] { {1.0f, true}, @@ -477,8 +526,7 @@ void AnimationDataTest::mutableAccessNotAllowed() { }; AnimationData data{{}, keyframes, Containers::Array{Containers::InPlaceInit, { - {AnimationTrackType::Bool, - AnimationTrackTargetType(129), 0, + {AnimationTrackTargetType(129), 0, Animation::TrackView{keyframes, Animation::Interpolation::Constant}}, }}}; CORRADE_COMPARE(data.dataFlags(), DataFlags{}); @@ -507,9 +555,7 @@ void AnimationDataTest::trackCustomResultType() { view[1] = {5.0f, {30, 60, 100}}; AnimationData data{std::move(buffer), Containers::Array{Containers::InPlaceInit, { - {AnimationTrackType::Vector3i, - AnimationTrackType::Vector3, - AnimationTrackTargetType::Scaling3D, 0, + {AnimationTrackTargetType::Scaling3D, 0, Animation::TrackView{ {view, &view[0].time, view.size(), sizeof(Data)}, {view, &view[0].position, view.size(), sizeof(Data)}, @@ -577,8 +623,7 @@ void AnimationDataTest::release() { }; AnimationData data{{}, keyframes, Containers::Array{Containers::InPlaceInit, { - {AnimationTrackType::Bool, - AnimationTrackTargetType(129), 0, + {AnimationTrackTargetType(129), 0, Animation::TrackView{keyframes, Animation::Interpolation::Constant}}, }}}; CORRADE_COMPARE(data.trackCount(), 1);