mirror of https://github.com/mosra/magnum.git
6 changed files with 863 additions and 0 deletions
@ -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 |
||||||
|
|
||||||
|
}} |
||||||
@ -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 |
||||||
@ -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) |
||||||
Loading…
Reference in new issue