Browse Source

Trade: support both implicit and explicit duration in AnimationData.

pull/191/head
Vladimír Vondruš 8 years ago
parent
commit
1b583454b4
  1. 12
      src/Magnum/Trade/AnimationData.cpp
  2. 22
      src/Magnum/Trade/AnimationData.h
  3. 76
      src/Magnum/Trade/Test/AnimationDataTest.cpp

12
src/Magnum/Trade/AnimationData.cpp

@ -32,7 +32,17 @@
namespace Magnum { namespace Trade {
AnimationData::AnimationData(Containers::Array<char>&& data, Containers::Array<AnimationTrackData>&& tracks, const void* importerState) noexcept: _data{std::move(data)}, _tracks{std::move(tracks)}, _importerState{importerState} {}
AnimationData::AnimationData(Containers::Array<char>&& data, Containers::Array<AnimationTrackData>&& tracks, const Range1D& duration, const void* importerState) noexcept: _duration{duration}, _data{std::move(data)}, _tracks{std::move(tracks)}, _importerState{importerState} {}
AnimationData::AnimationData(Containers::Array<char>&& data, Containers::Array<AnimationTrackData>&& tracks, const void* importerState) noexcept: _data{std::move(data)}, _tracks{std::move(tracks)}, _importerState{importerState} {
if(!_tracks.empty()) {
/* Reset duration to duration of the first track so it properly support
cases where tracks don't start at 0 */
_duration = _tracks.front()._view.duration();
for(std::size_t i = 1; i != _tracks.size(); ++i)
_duration = Math::join(_duration, _tracks[i]._view.duration());
}
}
AnimationData::~AnimationData() = default;

22
src/Magnum/Trade/AnimationData.h

@ -207,17 +207,31 @@ class AnimationTrackData {
class MAGNUM_TRADE_EXPORT AnimationData {
public:
/**
* @brief Constructor
* @brief Construct with implicit duration
* @param data Buffer containing all keyframe data for this
* animation clip
* @param tracks Track data
* @param importerState Importer-specific state
*
* Each item of @p track should have an @ref Animation::TrackView
* instance pointing its key/value views to @p data.
* instance pointing its key/value views to @p data. The @ref duration()
* is automatically calculated from durations of all tracks.
*/
explicit AnimationData(Containers::Array<char>&& data, Containers::Array<AnimationTrackData>&& tracks, const void* importerState = nullptr) noexcept;
/**
* @brief Construct with explicit duration
* @param data Buffer containing all keyframe data for this
* animation clip
* @param tracks Track data
* @param duration Animation track duration
* @param importerState Importer-specific state
*
* Each item of @p track should have an @ref Animation::TrackView
* instance pointing its key/value views to @p data.
*/
explicit AnimationData(Containers::Array<char>&& data, Containers::Array<AnimationTrackData>&& tracks, const Range1D& duration, const void* importerState = nullptr) noexcept;
~AnimationData();
/** @brief Copying is not allowed */
@ -257,6 +271,9 @@ class MAGNUM_TRADE_EXPORT AnimationData {
Containers::ArrayView<const char> data() const && = delete; /**< @overload */
#endif
/** @brief Duration */
Range1D duration() const { return _duration; }
/** @brief Track count */
UnsignedInt trackCount() const { return _tracks.size(); }
@ -340,6 +357,7 @@ class MAGNUM_TRADE_EXPORT AnimationData {
const void* importerState() const { return _importerState; }
private:
Range1D _duration;
Containers::Array<char> _data;
Containers::Array<AnimationTrackData> _tracks;
const void* _importerState;

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

@ -35,6 +35,8 @@ struct AnimationDataTest: TestSuite::Tester {
explicit AnimationDataTest();
void construct();
void constructImplicitDuration();
void constructImplicitDurationEmpty();
void constructCopy();
void constructMove();
@ -52,6 +54,8 @@ struct AnimationDataTest: TestSuite::Tester {
AnimationDataTest::AnimationDataTest() {
addTests({&AnimationDataTest::construct,
&AnimationDataTest::constructImplicitDuration,
&AnimationDataTest::constructImplicitDurationEmpty,
&AnimationDataTest::constructCopy,
&AnimationDataTest::constructMove,
@ -99,8 +103,9 @@ void AnimationDataTest::construct() {
{&view[0].rotation, view.size(), sizeof(Data)},
Animation::Interpolation::Linear,
animationInterpolatorFor<Quaternion>(Animation::Interpolation::Linear)}}
}}, &state};
}}, {-1.0f, 7.0f}, &state};
CORRADE_COMPARE(data.duration(), (Range1D{-1.0f, 7.0f}));
CORRADE_COMPARE(data.data().size(), sizeof(Data)*3);
CORRADE_COMPARE(data.trackCount(), 2);
CORRADE_COMPARE(data.importerState(), &state);
@ -130,6 +135,71 @@ void AnimationDataTest::construct() {
}
}
void AnimationDataTest::constructImplicitDuration() {
/* Ain't the prettiest, but trust me: you won't do it like this in the
plugins anyway */
struct Data {
Float time;
bool value;
};
Containers::Array<char> buffer{sizeof(Data)*4};
auto view = Containers::arrayCast<Data>(buffer);
view[0] = {1.0f, true};
view[1] = {5.0f, false};
view[2] = {3.0f, true};
view[3] = {7.0f, false};
const int state = 5;
AnimationData data{std::move(buffer), Containers::Array<AnimationTrackData>{Containers::InPlaceInit, {
{AnimationTrackType::Bool,
AnimationTrackTarget(129), 0,
Animation::TrackView<Float, bool>{
{&view[0].time, 2, sizeof(Data)},
{&view[0].value, 2, sizeof(Data)},
Animation::Interpolation::Constant}},
{AnimationTrackType::Bool,
AnimationTrackTarget(130), 1,
Animation::TrackView<Float, bool>{
{&view[2].time, 2, sizeof(Data)},
{&view[2].value, 2, sizeof(Data)},
Animation::Interpolation::Linear}}
}}, &state};
CORRADE_COMPARE(data.duration(), (Range1D{1.0f, 7.0f}));
CORRADE_COMPARE(data.trackCount(), 2);
CORRADE_COMPARE(data.importerState(), &state);
{
CORRADE_COMPARE(data.trackType(0), AnimationTrackType::Bool);
CORRADE_COMPARE(data.trackResultType(0), AnimationTrackType::Bool);
CORRADE_COMPARE(data.trackTarget(0), AnimationTrackTarget(129));
CORRADE_COMPARE(data.trackTargetId(0), 0);
Animation::TrackView<Float, bool> track = data.track<bool>(0);
CORRADE_COMPARE(track.duration(), (Range1D{1.0f, 5.0f}));
CORRADE_COMPARE(track.keys().size(), 2);
CORRADE_COMPARE(track.values().size(), 2);
CORRADE_COMPARE(track.interpolation(), Animation::Interpolation::Constant);
CORRADE_COMPARE(track.at(6.0f), false);
} {
CORRADE_COMPARE(data.trackType(1), AnimationTrackType::Bool);
CORRADE_COMPARE(data.trackResultType(1), AnimationTrackType::Bool);
CORRADE_COMPARE(data.trackTarget(1), AnimationTrackTarget(130));
CORRADE_COMPARE(data.trackTargetId(1), 1);
Animation::TrackView<Float, bool> track = data.track<bool>(1);
CORRADE_COMPARE(track.duration(), (Range1D{3.0f, 7.0f}));
CORRADE_COMPARE(track.keys().size(), 2);
CORRADE_COMPARE(track.values().size(), 2);
CORRADE_COMPARE(track.interpolation(), Animation::Interpolation::Linear);
CORRADE_COMPARE(track.at(4.5f), true);
}
}
void AnimationDataTest::constructImplicitDurationEmpty() {
AnimationData data{nullptr, nullptr};
CORRADE_COMPARE(data.duration(), Range1D{});
}
void AnimationDataTest::constructCopy() {
CORRADE_VERIFY(!(std::is_constructible<AnimationData, const AnimationData&>{}));
CORRADE_VERIFY(!(std::is_assignable<AnimationData, const AnimationData&>{}));
@ -164,10 +234,11 @@ void AnimationDataTest::constructMove() {
{&view[0].rotation, view.size(), sizeof(Data)},
Animation::Interpolation::Linear,
animationInterpolatorFor<Quaternion>(Animation::Interpolation::Linear)}}
}}, &state};
}}, {-1.0f, 7.0f}, &state};
AnimationData b{std::move(a)};
CORRADE_COMPARE(b.duration(), (Range1D{-1.0f, 7.0f}));
CORRADE_COMPARE(b.data().size(), sizeof(Data)*3);
CORRADE_COMPARE(b.trackCount(), 2);
CORRADE_COMPARE(b.importerState(), &state);
@ -200,6 +271,7 @@ void AnimationDataTest::constructMove() {
AnimationData c{nullptr, nullptr, &other};
c = std::move(b);
CORRADE_COMPARE(c.duration(), (Range1D{-1.0f, 7.0f}));
CORRADE_COMPARE(c.data().size(), sizeof(Data)*3);
CORRADE_COMPARE(c.trackCount(), 2);
CORRADE_COMPARE(c.importerState(), &state);

Loading…
Cancel
Save