Browse Source

Trade: initial AnimationData implementation.

pull/191/head
Vladimír Vondruš 8 years ago
parent
commit
dd1c8052ff
  1. 141
      src/Magnum/Trade/AnimationData.cpp
  2. 386
      src/Magnum/Trade/AnimationData.h
  3. 2
      src/Magnum/Trade/CMakeLists.txt
  4. 320
      src/Magnum/Trade/Test/AnimationDataTest.cpp
  5. 8
      src/Magnum/Trade/Test/CMakeLists.txt
  6. 6
      src/Magnum/Trade/Trade.h

141
src/Magnum/Trade/AnimationData.cpp

@ -0,0 +1,141 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include "AnimationData.h"
#include <Corrade/Utility/Debug.h>
#include "Magnum/Math/Vector4.h"
#include "Magnum/Math/Quaternion.h"
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() = default;
AnimationData::AnimationData(AnimationData&&) noexcept = default;
AnimationData& AnimationData::operator=(AnimationData&&) noexcept = default;
AnimationTrackType AnimationData::trackType(UnsignedInt id) const {
CORRADE_ASSERT(id < _tracks.size(), "Trade::AnimationData::trackType(): index out of range", {});
return _tracks[id]._type;
}
AnimationTrackType AnimationData::trackResultType(UnsignedInt id) const {
CORRADE_ASSERT(id < _tracks.size(), "Trade::AnimationData::trackResultType(): index out of range", {});
return _tracks[id]._resultType;
}
AnimationTrackTarget AnimationData::trackTarget(UnsignedInt id) const {
CORRADE_ASSERT(id < _tracks.size(), "Trade::AnimationData::trackTarget(): index out of range", {});
return _tracks[id]._target;
}
UnsignedInt AnimationData::trackTargetId(UnsignedInt id) const {
CORRADE_ASSERT(id < _tracks.size(), "Trade::AnimationData::trackTargetId(): index out of range", {});
return _tracks[id]._targetId;
}
template<class V, class R> auto animationInterpolatorFor(Animation::Interpolation interpolation) -> R(*)(const V&, const V&, Float) {
return Animation::interpolatorFor<V, R>(interpolation);
}
#ifndef DOXYGEN_GENERATING_OUTPUT
template MAGNUM_TRADE_EXPORT auto animationInterpolatorFor<bool, bool>(Animation::Interpolation) -> bool(*)(const bool&, const bool&, Float);
template MAGNUM_TRADE_EXPORT auto animationInterpolatorFor<Float, Float>(Animation::Interpolation) -> Float(*)(const Float&, const Float&, Float);
template MAGNUM_TRADE_EXPORT auto animationInterpolatorFor<UnsignedInt, UnsignedInt>(Animation::Interpolation) -> UnsignedInt(*)(const UnsignedInt&, const UnsignedInt&, Float);
template MAGNUM_TRADE_EXPORT auto animationInterpolatorFor<Int, Int>(Animation::Interpolation) -> Int(*)(const Int&, const Int&, Float);
template MAGNUM_TRADE_EXPORT auto animationInterpolatorFor<Math::BoolVector<2>, Math::BoolVector<2>>(Animation::Interpolation) -> Math::BoolVector<2>(*)(const Math::BoolVector<2>&, const Math::BoolVector<2>&, Float);
template MAGNUM_TRADE_EXPORT auto animationInterpolatorFor<Math::BoolVector<3>, Math::BoolVector<3>>(Animation::Interpolation) -> Math::BoolVector<3>(*)(const Math::BoolVector<3>&, const Math::BoolVector<3>&, Float);
template MAGNUM_TRADE_EXPORT auto animationInterpolatorFor<Math::BoolVector<4>, Math::BoolVector<4>>(Animation::Interpolation) -> Math::BoolVector<4>(*)(const Math::BoolVector<4>&, const Math::BoolVector<4>&, Float);
template MAGNUM_TRADE_EXPORT auto animationInterpolatorFor<Vector2, Vector2>(Animation::Interpolation) -> Vector2(*)(const Vector2&, const Vector2&, Float);
template MAGNUM_TRADE_EXPORT auto animationInterpolatorFor<Vector2i, Vector2i>(Animation::Interpolation) -> Vector2i(*)(const Vector2i&, const Vector2i&, Float);
template MAGNUM_TRADE_EXPORT auto animationInterpolatorFor<Vector2ui, Vector2ui>(Animation::Interpolation) -> Vector2ui(*)(const Vector2ui&, const Vector2ui&, Float);
template MAGNUM_TRADE_EXPORT auto animationInterpolatorFor<Vector3, Vector3>(Animation::Interpolation) -> Vector3(*)(const Vector3&, const Vector3&, Float);
template MAGNUM_TRADE_EXPORT auto animationInterpolatorFor<Vector3i, Vector3i>(Animation::Interpolation) -> Vector3i(*)(const Vector3i&, const Vector3i&, Float);
template MAGNUM_TRADE_EXPORT auto animationInterpolatorFor<Vector3ui, Vector3ui>(Animation::Interpolation) -> Vector3ui(*)(const Vector3ui&, const Vector3ui&, Float);
template MAGNUM_TRADE_EXPORT auto animationInterpolatorFor<Vector4, Vector4>(Animation::Interpolation) -> Vector4(*)(const Vector4&, const Vector4&, Float);
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<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);
Debug& operator<<(Debug& debug, const AnimationTrackType value) {
switch(value) {
/* LCOV_EXCL_START */
#define _c(value) case AnimationTrackType::value: return debug << "Trade::AnimationTrackType::" #value;
_c(Bool)
_c(Float)
_c(UnsignedInt)
_c(Int)
_c(BoolVector2)
_c(BoolVector3)
_c(BoolVector4)
_c(Vector2)
_c(Vector2ui)
_c(Vector2i)
_c(Vector3)
_c(Vector3ui)
_c(Vector3i)
_c(Vector4)
_c(Vector4ui)
_c(Vector4i)
_c(Quaternion)
_c(DualQuaternion)
#undef _c
/* LCOV_EXCL_STOP */
}
return debug << "Trade::AnimationTrackType(" << Debug::nospace << reinterpret_cast<void*>(UnsignedByte(value)) << Debug::nospace << ")";
}
Debug& operator<<(Debug& debug, const AnimationTrackTarget value) {
if(UnsignedByte(value) >= UnsignedByte(AnimationTrackTarget::Custom))
return debug << "Trade::AnimationTrackTarget::Custom(" << Debug::nospace << UnsignedByte(value) << Debug::nospace << ")";
switch(value) {
/* LCOV_EXCL_START */
#define _c(value) case AnimationTrackTarget::value: return debug << "Trade::AnimationTrackTarget::" #value;
_c(Translation2D)
_c(Translation3D)
_c(Rotation2D)
_c(Rotation3D)
_c(Scaling2D)
_c(Scaling3D)
#undef _c
/* LCOV_EXCL_STOP */
/* To silence compiler warning about unhandled values */
case AnimationTrackTarget::Custom: CORRADE_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */
}
return debug << "Trade::AnimationTrackTarget(" << Debug::nospace << reinterpret_cast<void*>(UnsignedByte(value)) << Debug::nospace << ")";
}
#endif
}}

386
src/Magnum/Trade/AnimationData.h

@ -0,0 +1,386 @@
#ifndef Magnum_Trade_AnimationData_h
#define Magnum_Trade_AnimationData_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
/** @file
* @brief Class @ref Magnum::Trade::AnimationTrackData, @ref Magnum::Trade::AnimationData, enum @ref Magnum::Trade::AnimationTrackType, @ref Magnum::Trade::AnimationTrackTarget, function @ref Magnum::Trade::animationInterpolatorFor()
*/
#include "Magnum/Magnum.h"
#include "Magnum/Math/Math.h"
#include "Magnum/Animation/Track.h"
#include "Magnum/Trade/Trade.h"
#include "Magnum/Trade/visibility.h"
namespace Magnum { namespace Trade {
/**
@brief Type of animation track data
@see @ref AnimationData
@experimental
*/
enum class AnimationTrackType: UnsignedByte {
Bool, /**< @cpp bool @ce <b></b> */
Float, /**< @ref Magnum::Float "Float" */
UnsignedInt, /**< @ref Magnum::UnsignedInt "UnsignedInt" */
Int, /**< @ref Magnum::Int "Int" */
BoolVector2, /**< @ref Math::BoolVector "Math::BoolVector<2>" */
BoolVector3, /**< @ref Math::BoolVector "Math::BoolVector<3>" */
BoolVector4, /**< @ref Math::BoolVector "Math::BoolVector<4>" */
/**
* @ref Magnum::Vector2 "Vector2". Usually used for
* @ref AnimationTrackTarget::Translation2D and
* @ref AnimationTrackTarget::Scaling2D.
*/
Vector2,
Vector2ui, /**< @ref Magnum::Vector2ui "Vector2ui" */
Vector2i, /**< @ref Magnum::Vector2i "Vector2i" */
/**
* @ref Magnum::Vector3 "Vector3". Usually used for
* @ref AnimationTrackTarget::Translation3D and
* @ref AnimationTrackTarget::Scaling3D.
*/
Vector3,
Vector3ui, /**< @ref Magnum::Vector3ui "Vector3ui" */
Vector3i, /**< @ref Magnum::Vector3i "Vector3i" */
Vector4, /**< @ref Magnum::Vector4 "Vector4" */
Vector4ui, /**< @ref Magnum::Vector4ui "Vector4ui" */
Vector4i, /**< @ref Magnum::Vector4i "Vector4i" */
/**
* @ref Magnum::Quaternion "Quaternion". Usually used for
* @ref AnimationTrackTarget::Rotation3D.
*/
Quaternion,
DualQuaternion /**< @ref Magnum::DualQuaternion "DualQuaternion" */
};
/** @debugoperatorenum{AnimationTrackType} */
MAGNUM_TRADE_EXPORT Debug& operator<<(Debug& debug, AnimationTrackType value);
/**
@brief Target of an animation track
@see @ref AnimationData
@experimental
*/
enum class AnimationTrackTarget: UnsignedByte {
/**
* Modifies 2D object translation. Type is usually
* @ref Magnum::Vector2 "Vector2".
*
* @see @ref AnimationTrackType::Vector2, @ref ObjectData2D::translation()
*/
Translation2D,
/**
* Modifies 3D object translation. Type is usually
* @ref Magnum::Vector3 "Vector3".
*
* @see @ref AnimationTrackType::Vector3, @ref ObjectData3D::translation()
*/
Translation3D,
/**
* Modifies 2D object rotation. Type is usually
* @ref Magnum::Complex "Complex".
*
* @see @ref ObjectData2D::rotation()
*/
Rotation2D,
/**
* Modifies 3D object rotation. Type is usually
* @ref Magnum::Quaternion "Quaternion".
*
* @see @ref AnimationTrackType::Quaternion, @ref ObjectData3D::rotation()
*/
Rotation3D,
/**
* Modifies 2D object scaling. Type is usually
* @ref Magnum::Vector2 "Vector2".
*
* @see @ref AnimationTrackType::Vector2, @ref ObjectData2D::scaling()
*/
Scaling2D,
/**
* Modifies 3D object scaling. Type is usually
* @ref Magnum::Vector3 "Vector3".
*
* @see @ref AnimationTrackType::Vector3, @ref ObjectData3D::scaling()
*/
Scaling3D,
/**
* This and all higher values are for importer-specific targets. Can be of
* any type, @ref AnimationData::trackTargetId() might or might not point
* to an existing object. See documentation of particular importer for
* details.
*/
Custom = 128
};
/** @debugoperatorenum{AnimationTrackTarget} */
MAGNUM_TRADE_EXPORT Debug& operator<<(Debug& debug, AnimationTrackTarget value);
/**
@brief Animation track data
Used when constructing @ref AnimationData. Fields can be accessed through its
API.
@experimental
*/
class AnimationTrackData {
public:
/**
* @brief Constructor
* @param type Value type
* @param resultType Result type
* @param target Track target
* @param targetId Track target ID
* @param view Type-erased @ref Animation::TrackView instance
*/
/*implicit*/ AnimationTrackData(AnimationTrackType type, AnimationTrackType resultType, AnimationTrackTarget target, UnsignedInt targetId, Animation::TrackViewStorage view) noexcept: _type{type}, _resultType{resultType}, _target{target}, _targetId{targetId}, _view{view} {}
/** @overload
*
* Equivalent to the above with @p type used as both value type and
* result type.
*/
/*implicit*/ AnimationTrackData(AnimationTrackType type, AnimationTrackTarget target, UnsignedInt targetId, Animation::TrackViewStorage view) noexcept: _type{type}, _resultType{type}, _target{target}, _targetId{targetId}, _view{view} {}
private:
friend AnimationData;
AnimationTrackType _type, _resultType;
AnimationTrackTarget _target;
UnsignedInt _targetId;
Animation::TrackViewStorage _view;
};
/**
@brief Animation clip data
@see @ref AbstractImporter::animation()
@experimental
*/
class MAGNUM_TRADE_EXPORT AnimationData {
public:
/**
* @brief Constructor
* @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.
*/
explicit AnimationData(Containers::Array<char>&& data, Containers::Array<AnimationTrackData>&& tracks, const void* importerState = nullptr) noexcept;
~AnimationData();
/** @brief Copying is not allowed */
AnimationData(const AnimationData&) = delete;
/** @brief Move constructor */
AnimationData(AnimationData&&) noexcept;
/** @brief Copying is not allowed */
AnimationData& operator=(const AnimationData&) = delete;
/** @brief Move assignment */
AnimationData& operator=(AnimationData&&) noexcept;
/**
* @brief Raw data
*
* Contains data for all tracks contained in this clip.
* @see @ref release()
*/
Containers::ArrayView<char> data()
#ifndef CORRADE_GCC47_COMPATIBILITY
&
#endif
{ return _data; }
#ifndef CORRADE_GCC47_COMPATIBILITY
Containers::ArrayView<char> data() && = delete; /**< @overload */
#endif
/** @overload */
Containers::ArrayView<const char> data() const
#ifndef CORRADE_GCC47_COMPATIBILITY
&
#endif
{ return _data; }
#ifndef CORRADE_GCC47_COMPATIBILITY
Containers::ArrayView<const char> data() const && = delete; /**< @overload */
#endif
/** @brief Track count */
UnsignedInt trackCount() const { return _tracks.size(); }
/**
* @brief Track value type
* @param id Track index
*
* Data types are usually closely related to @ref trackTarget(), see
* @ref AnimationTrackTarget documentation for more information.
* @see @ref trackCount()
*/
AnimationTrackType trackType(UnsignedInt id) const;
/**
* @brief Track result type
* @param id Track index
*
* In case track values are packed, track result type is different from
* @ref trackType(). Data types are usually closely related to
* @ref trackTarget(), see @ref AnimationTrackTarget documentation for
* more information.
* @see @ref trackCount()
*/
AnimationTrackType trackResultType(UnsignedInt id) const;
/**
* @brief Track target
* @param id Track index
*
* Particular animation targets usually correspond to a common
* @ref trackType(), see @ref AnimationTrackTarget documentation for
* more information.
* @see @ref trackCount()
*/
AnimationTrackTarget trackTarget(UnsignedInt id) const;
/**
* @brief Track target index
* @param id Track index
*
* For @ref trackTarget() with @ref AnimationTrackTarget::Translation2D,
* @ref AnimationTrackTarget::Translation3D,
* @ref AnimationTrackTarget::Rotation2D,
* @ref AnimationTrackTarget::Rotation3D,
* @ref AnimationTrackTarget::Scaling2D,
* @ref AnimationTrackTarget::Scaling3D specifies object which property
* is modified.
* @see @ref trackCount(), @ref AbstractImporter::object2D(),
* @ref AbstractImporter::object3D()
*/
UnsignedInt trackTargetId(UnsignedInt id) const;
/**
* @brief Track data
* @tparam V Track value type
* @tparam R Track result type
*
* Expects that requested types are correct for given @ref trackType()
* and @ref trackResultType(). Note that the returned view is onto
* @ref data(), meaning you either need to ensure that the
* @cpp AnimationData @ce instance stays in scope for as long as you
* use the view or you need to release the data array using
* @ref release() and manage its lifetime yourself.
*/
template<class V, class R = Animation::ResultOf<V>> Animation::TrackView<Float, V, R> track(UnsignedInt id) const;
/**
* @brief Release data storage
*
* Releases the ownership of the data array and resets internal state
* to default.
* @see @ref data()
*/
Containers::Array<char> release() { return std::move(_data); }
/**
* @brief Importer-specific state
*
* See @ref AbstractImporter::importerState() for more information.
*/
const void* importerState() const { return _importerState; }
private:
Containers::Array<char> _data;
Containers::Array<AnimationTrackData> _tracks;
const void* _importerState;
};
/** @relatesalso AnimationData
@brief Animation interpolator function for given interpolation behavior
To be used from importer plugins --- unlike @ref Animation::interpolatorFor()
guarantees that the returned function pointer is not instantiated inside plugin
binary to avoid dangling function pointers on plugin unload. See
@ref Animation::interpolatorFor() for more information.
@see @ref AnimationData
@experimental
*/
template<class V, class R = Animation::ResultOf<V>> MAGNUM_TRADE_EXPORT auto animationInterpolatorFor(Animation::Interpolation interpolation) -> R(*)(const V&, const V&, Float);
#if !defined(CORRADE_NO_ASSERT) || defined(CORRADE_GRACEFUL_ASSERT)
namespace Implementation {
/* LCOV_EXCL_START */
template<class T> AnimationTrackType animationTypeFor();
template<> constexpr AnimationTrackType animationTypeFor<bool>() { return AnimationTrackType::Bool; }
template<> constexpr AnimationTrackType animationTypeFor<Float>() { return AnimationTrackType::Float; }
template<> constexpr AnimationTrackType animationTypeFor<UnsignedInt>() { return AnimationTrackType::UnsignedInt; }
template<> constexpr AnimationTrackType animationTypeFor<Int>() { return AnimationTrackType::Int; }
template<> constexpr AnimationTrackType animationTypeFor<Math::BoolVector<2>>() { return AnimationTrackType::BoolVector2; }
template<> constexpr AnimationTrackType animationTypeFor<Math::BoolVector<3>>() { return AnimationTrackType::BoolVector3; }
template<> constexpr AnimationTrackType animationTypeFor<Math::BoolVector<4>>() { return AnimationTrackType::BoolVector4; }
template<> constexpr AnimationTrackType animationTypeFor<Vector2>() { return AnimationTrackType::Vector2; }
template<> constexpr AnimationTrackType animationTypeFor<Vector2ui>() { return AnimationTrackType::Vector2ui; }
template<> constexpr AnimationTrackType animationTypeFor<Vector2i>() { return AnimationTrackType::Vector2i; }
template<> constexpr AnimationTrackType animationTypeFor<Vector3>() { return AnimationTrackType::Vector3; }
template<> constexpr AnimationTrackType animationTypeFor<Vector3ui>() { return AnimationTrackType::Vector3ui; }
template<> constexpr AnimationTrackType animationTypeFor<Vector3i>() { return AnimationTrackType::Vector3i; }
template<> constexpr AnimationTrackType animationTypeFor<Vector4>() { return AnimationTrackType::Vector4; }
template<> constexpr AnimationTrackType animationTypeFor<Vector4ui>() { return AnimationTrackType::Vector4ui; }
template<> constexpr AnimationTrackType animationTypeFor<Vector4i>() { return AnimationTrackType::Vector4i; }
template<> constexpr AnimationTrackType animationTypeFor<Quaternion>() { return AnimationTrackType::Quaternion; }
template<> constexpr AnimationTrackType animationTypeFor<DualQuaternion>() { return AnimationTrackType::DualQuaternion; }
/* LCOV_EXCL_STOP */
}
#endif
template<class V, class R> Animation::TrackView<Float, V, R> AnimationData::track(UnsignedInt id) const {
CORRADE_ASSERT(id < _tracks.size(), "Trade::AnimationData::track(): index out of range", (Animation::TrackView<Float, V, R>{}));
CORRADE_ASSERT(Implementation::animationTypeFor<V>() == _tracks[id]._type, "Trade::AnimationData::track(): improper type requested for" << _tracks[id]._type, (Animation::TrackView<Float, V, R>{}));
CORRADE_ASSERT(Implementation::animationTypeFor<R>() == _tracks[id]._resultType, "Trade::AnimationData::track(): improper result type requested for" << _tracks[id]._resultType, (Animation::TrackView<Float, V, R>{}));
return static_cast<const Animation::TrackView<Float, V, R>&>(_tracks[id]._view);
}
}}
#endif

2
src/Magnum/Trade/CMakeLists.txt

@ -38,6 +38,7 @@ set(MagnumTrade_SRCS
set(MagnumTrade_GracefulAssert_SRCS
AbstractImageConverter.cpp
AbstractImporter.cpp
AnimationData.cpp
ImageData.cpp
ObjectData2D.cpp
ObjectData3D.cpp
@ -47,6 +48,7 @@ set(MagnumTrade_HEADERS
AbstractImporter.h
AbstractImageConverter.h
AbstractMaterialData.h
AnimationData.h
CameraData.h
ImageData.h
LightData.h

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

@ -0,0 +1,320 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include <sstream>
#include <Corrade/TestSuite/Tester.h>
#include "Magnum/Math/Quaternion.h"
#include "Magnum/Trade/AnimationData.h"
namespace Magnum { namespace Trade { namespace Test {
struct AnimationDataTest: TestSuite::Tester {
explicit AnimationDataTest();
void construct();
void constructCopy();
void constructMove();
void trackCustomResultType();
void trackWrongIndex();
void trackWrongType();
void trackWrongResultType();
void debugAnimationTrackType();
void debugAnimationTrackTarget();
};
AnimationDataTest::AnimationDataTest() {
addTests({&AnimationDataTest::construct,
&AnimationDataTest::constructCopy,
&AnimationDataTest::constructMove,
&AnimationDataTest::trackCustomResultType,
&AnimationDataTest::trackWrongIndex,
&AnimationDataTest::trackWrongType,
&AnimationDataTest::trackWrongResultType,
&AnimationDataTest::debugAnimationTrackType,
&AnimationDataTest::debugAnimationTrackTarget});
}
using namespace Math::Literals;
void AnimationDataTest::construct() {
/* Ain't the prettiest, but trust me: you won't do it like this in the
plugins anyway */
struct Data {
Float time;
Vector3 position;
Quaternion rotation;
};
Containers::Array<char> buffer{sizeof(Data)*3};
auto view = Containers::arrayCast<Data>(buffer);
view[0] = {0.0f, {3.0f, 1.0f, 0.1f}, Quaternion::rotation(45.0_degf, Vector3::yAxis())};
view[1] = {5.0f, {0.3f, 0.6f, 1.0f}, Quaternion::rotation(20.0_degf, Vector3::yAxis())};
view[2] = {7.5f, {1.0f, 0.3f, 2.1f}, Quaternion{}};
const int state = 5;
AnimationData data{std::move(buffer), Containers::Array<AnimationTrackData>{Containers::InPlaceInit, {
{AnimationTrackType::Vector3,
AnimationTrackTarget::Translation3D, 42,
Animation::TrackView<Float, Vector3>{
{&view[0].time, view.size(), sizeof(Data)},
{&view[0].position, view.size(), sizeof(Data)},
Animation::Interpolation::Constant,
animationInterpolatorFor<Vector3>(Animation::Interpolation::Constant)}},
{AnimationTrackType::Quaternion,
AnimationTrackTarget::Rotation3D, 1337,
Animation::TrackView<Float, Quaternion>{
{&view[0].time, view.size(), sizeof(Data)},
{&view[0].rotation, view.size(), sizeof(Data)},
Animation::Interpolation::Linear,
animationInterpolatorFor<Quaternion>(Animation::Interpolation::Linear)}}
}}, &state};
CORRADE_COMPARE(data.data().size(), sizeof(Data)*3);
CORRADE_COMPARE(data.trackCount(), 2);
CORRADE_COMPARE(data.importerState(), &state);
{
CORRADE_COMPARE(data.trackType(0), AnimationTrackType::Vector3);
CORRADE_COMPARE(data.trackResultType(0), AnimationTrackType::Vector3);
CORRADE_COMPARE(data.trackTarget(0), AnimationTrackTarget::Translation3D);
CORRADE_COMPARE(data.trackTargetId(0), 42);
Animation::TrackView<Float, Vector3> track = data.track<Vector3>(0);
CORRADE_COMPARE(track.keys().size(), 3);
CORRADE_COMPARE(track.values().size(), 3);
CORRADE_COMPARE(track.interpolation(), Animation::Interpolation::Constant);
CORRADE_COMPARE(track.at(2.5f), (Vector3{3.0f, 1.0f, 0.1f}));
} {
CORRADE_COMPARE(data.trackType(1), AnimationTrackType::Quaternion);
CORRADE_COMPARE(data.trackResultType(1), AnimationTrackType::Quaternion);
CORRADE_COMPARE(data.trackTarget(1), AnimationTrackTarget::Rotation3D);
CORRADE_COMPARE(data.trackTargetId(1), 1337);
Animation::TrackView<Float, Quaternion> track = data.track<Quaternion>(1);
CORRADE_COMPARE(track.keys().size(), 3);
CORRADE_COMPARE(track.values().size(), 3);
CORRADE_COMPARE(track.interpolation(), Animation::Interpolation::Linear);
CORRADE_COMPARE(track.at(2.5f), Quaternion::rotation(32.5_degf, Vector3::yAxis()));
}
}
void AnimationDataTest::constructCopy() {
CORRADE_VERIFY(!(std::is_constructible<AnimationData, const AnimationData&>{}));
CORRADE_VERIFY(!(std::is_assignable<AnimationData, const AnimationData&>{}));
}
void AnimationDataTest::constructMove() {
/* Ugh and here we go again! */
struct Data {
Float time;
Vector3 position;
Quaternion rotation;
};
Containers::Array<char> buffer{sizeof(Data)*3};
auto view = Containers::arrayCast<Data>(buffer);
view[0] = {0.0f, {3.0f, 1.0f, 0.1f}, Quaternion::rotation(45.0_degf, Vector3::yAxis())};
view[1] = {5.0f, {0.3f, 0.6f, 1.0f}, Quaternion::rotation(20.0_degf, Vector3::yAxis())};
view[2] = {7.5f, {1.0f, 0.3f, 2.1f}, Quaternion{}};
const int state = 5;
AnimationData a{std::move(buffer), Containers::Array<AnimationTrackData>{Containers::InPlaceInit, {
{AnimationTrackType::Vector3,
AnimationTrackTarget::Translation3D, 42,
Animation::TrackView<Float, Vector3>{
{&view[0].time, view.size(), sizeof(Data)},
{&view[0].position, view.size(), sizeof(Data)},
Animation::Interpolation::Constant,
animationInterpolatorFor<Vector3>(Animation::Interpolation::Constant)}},
{AnimationTrackType::Quaternion,
AnimationTrackTarget::Rotation3D, 1337,
Animation::TrackView<Float, Quaternion>{
{&view[0].time, view.size(), sizeof(Data)},
{&view[0].rotation, view.size(), sizeof(Data)},
Animation::Interpolation::Linear,
animationInterpolatorFor<Quaternion>(Animation::Interpolation::Linear)}}
}}, &state};
AnimationData b{std::move(a)};
CORRADE_COMPARE(b.data().size(), sizeof(Data)*3);
CORRADE_COMPARE(b.trackCount(), 2);
CORRADE_COMPARE(b.importerState(), &state);
{
CORRADE_COMPARE(b.trackType(0), AnimationTrackType::Vector3);
CORRADE_COMPARE(b.trackResultType(0), AnimationTrackType::Vector3);
CORRADE_COMPARE(b.trackTarget(0), AnimationTrackTarget::Translation3D);
CORRADE_COMPARE(b.trackTargetId(0), 42);
Animation::TrackView<Float, Vector3> track = b.track<Vector3>(0);
CORRADE_COMPARE(track.keys().size(), 3);
CORRADE_COMPARE(track.values().size(), 3);
CORRADE_COMPARE(track.interpolation(), Animation::Interpolation::Constant);
CORRADE_COMPARE(track.at(2.5f), (Vector3{3.0f, 1.0f, 0.1f}));
} {
CORRADE_COMPARE(b.trackType(1), AnimationTrackType::Quaternion);
CORRADE_COMPARE(b.trackResultType(1), AnimationTrackType::Quaternion);
CORRADE_COMPARE(b.trackTarget(1), AnimationTrackTarget::Rotation3D);
CORRADE_COMPARE(b.trackTargetId(1), 1337);
Animation::TrackView<Float, Quaternion> track = b.track<Quaternion>(1);
CORRADE_COMPARE(track.keys().size(), 3);
CORRADE_COMPARE(track.values().size(), 3);
CORRADE_COMPARE(track.interpolation(), Animation::Interpolation::Linear);
CORRADE_COMPARE(track.at(2.5f), Quaternion::rotation(32.5_degf, Vector3::yAxis()));
}
int other;
AnimationData c{nullptr, nullptr, &other};
c = std::move(b);
CORRADE_COMPARE(c.data().size(), sizeof(Data)*3);
CORRADE_COMPARE(c.trackCount(), 2);
CORRADE_COMPARE(c.importerState(), &state);
{
CORRADE_COMPARE(c.trackType(0), AnimationTrackType::Vector3);
CORRADE_COMPARE(c.trackResultType(0), AnimationTrackType::Vector3);
CORRADE_COMPARE(c.trackTarget(0), AnimationTrackTarget::Translation3D);
CORRADE_COMPARE(c.trackTargetId(0), 42);
Animation::TrackView<Float, Vector3> track = c.track<Vector3>(0);
CORRADE_COMPARE(track.keys().size(), 3);
CORRADE_COMPARE(track.values().size(), 3);
CORRADE_COMPARE(track.interpolation(), Animation::Interpolation::Constant);
CORRADE_COMPARE(track.at(2.5f), (Vector3{3.0f, 1.0f, 0.1f}));
} {
CORRADE_COMPARE(c.trackType(1), AnimationTrackType::Quaternion);
CORRADE_COMPARE(c.trackResultType(1), AnimationTrackType::Quaternion);
CORRADE_COMPARE(c.trackTarget(1), AnimationTrackTarget::Rotation3D);
CORRADE_COMPARE(c.trackTargetId(1), 1337);
Animation::TrackView<Float, Quaternion> track = c.track<Quaternion>(1);
CORRADE_COMPARE(track.keys().size(), 3);
CORRADE_COMPARE(track.values().size(), 3);
CORRADE_COMPARE(track.interpolation(), Animation::Interpolation::Linear);
CORRADE_COMPARE(track.at(2.5f), Quaternion::rotation(32.5_degf, Vector3::yAxis()));
}
}
void AnimationDataTest::trackCustomResultType() {
using namespace Math::Literals;
struct Data {
Float time;
Vector3i position;
};
Containers::Array<char> buffer{sizeof(Data)*3};
auto view = Containers::arrayCast<Data>(buffer);
view[0] = {0.0f, {300, 100, 10}};
view[1] = {5.0f, {30, 60, 100}};
AnimationData data{std::move(buffer), Containers::Array<AnimationTrackData>{Containers::InPlaceInit, {
{AnimationTrackType::Vector3i,
AnimationTrackType::Vector3,
AnimationTrackTarget::Scaling3D, 0,
Animation::TrackView<Float, Vector3i, Vector3>{
{&view[0].time, view.size(), sizeof(Data)},
{&view[0].position, view.size(), sizeof(Data)},
[](const Vector3i& a, const Vector3i& b, Float t) -> Vector3 {
return Math::lerp(Vector3{a}*0.01f, Vector3{b}*0.01f, t);
}}}}
}};
CORRADE_COMPARE((data.track<Vector3i, Vector3>(0).at(2.5f)), (Vector3{1.65f, 0.8f, 0.55f}));
}
void AnimationDataTest::trackWrongIndex() {
std::ostringstream out;
Error redirectError{&out};
AnimationData data{nullptr, nullptr};
data.trackType(0);
data.trackResultType(0);
data.trackTarget(0);
data.trackTargetId(0);
data.track<Float>(0);
CORRADE_COMPARE(out.str(),
"Trade::AnimationData::trackType(): index out of range\n"
"Trade::AnimationData::trackResultType(): index out of range\n"
"Trade::AnimationData::trackTarget(): index out of range\n"
"Trade::AnimationData::trackTargetId(): index out of range\n"
"Trade::AnimationData::track(): index out of range\n");
}
void AnimationDataTest::trackWrongType() {
std::ostringstream out;
Error redirectError{&out};
AnimationData data{nullptr, Containers::Array<AnimationTrackData>{Containers::InPlaceInit, {
{AnimationTrackType::Vector3i,
AnimationTrackType::Vector3,
AnimationTrackTarget::Scaling3D, 0, {}}
}}};
data.track<Vector3>(0);
CORRADE_COMPARE(out.str(), "Trade::AnimationData::track(): improper type requested for Trade::AnimationTrackType::Vector3i\n");
}
void AnimationDataTest::trackWrongResultType() {
std::ostringstream out;
Error redirectError{&out};
AnimationData data{nullptr, Containers::Array<AnimationTrackData>{Containers::InPlaceInit, {
{AnimationTrackType::Vector3i,
AnimationTrackType::Vector3,
AnimationTrackTarget::Scaling3D, 0, {}}
}}};
data.track<Vector3i, Vector2>(0);
CORRADE_COMPARE(out.str(), "Trade::AnimationData::track(): improper result type requested for Trade::AnimationTrackType::Vector3\n");
}
void AnimationDataTest::debugAnimationTrackType() {
std::ostringstream out;
Debug{&out} << AnimationTrackType::DualQuaternion << AnimationTrackType(0xde);
CORRADE_COMPARE(out.str(), "Trade::AnimationTrackType::DualQuaternion Trade::AnimationTrackType(0xde)\n");
}
void AnimationDataTest::debugAnimationTrackTarget() {
std::ostringstream out;
Debug{&out} << AnimationTrackTarget::Rotation3D << AnimationTrackTarget(135) << AnimationTrackTarget(0x42);
CORRADE_COMPARE(out.str(), "Trade::AnimationTrackTarget::Rotation3D Trade::AnimationTrackTarget::Custom(135) Trade::AnimationTrackTarget(0x42)\n");
}
}}}
CORRADE_TEST_MAIN(Magnum::Trade::Test::AnimationDataTest)

8
src/Magnum/Trade/Test/CMakeLists.txt

@ -36,10 +36,13 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/configure.h.cmake
corrade_add_test(TradeAbstractImageConverterTest AbstractImageConverterTest.cpp LIBRARIES MagnumTradeTestLib)
target_include_directories(TradeAbstractImageConverterTest PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
corrade_add_test(TradeAbstractImporterTest AbstractImporterTest.cpp
LIBRARIES MagnumTradeTestLib
FILES file.bin)
target_include_directories(TradeAbstractImporterTest PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
corrade_add_test(TradeAnimationDataTest AnimationDataTest.cpp LIBRARIES MagnumTradeTestLib)
corrade_add_test(TradeCameraDataTest CameraDataTest.cpp LIBRARIES MagnumTrade)
corrade_add_test(TradeImageDataTest ImageDataTest.cpp LIBRARIES MagnumTradeTestLib)
corrade_add_test(TradeLightDataTest LightDataTest.cpp LIBRARIES MagnumTrade)
@ -51,9 +54,14 @@ corrade_add_test(TradeObjectData3DTest ObjectData3DTest.cpp LIBRARIES MagnumTrad
corrade_add_test(TradeSceneDataTest SceneDataTest.cpp LIBRARIES MagnumTrade)
corrade_add_test(TradeTextureDataTest TextureDataTest.cpp LIBRARIES MagnumTrade)
set_property(TARGET
TradeAnimationDataTest
APPEND PROPERTY COMPILE_DEFINITIONS "CORRADE_GRACEFUL_ASSERT")
set_target_properties(
TradeAbstractImageConverterTest
TradeAbstractImporterTest
TradeAnimationDataTest
TradeCameraDataTest
TradeImageDataTest
TradeLightDataTest

6
src/Magnum/Trade/Trade.h

@ -40,6 +40,12 @@ enum class ImporterFileCallbackPolicy: UnsignedByte;
class AbstractImporter;
class AbstractMaterialData;
enum class AnimationTrackTarget: UnsignedByte;
enum class AnimationTrackType: UnsignedByte;
class AnimationTrackData;
class AnimationData;
class CameraData;
template<UnsignedInt> class ImageData;

Loading…
Cancel
Save