mirror of https://github.com/mosra/magnum.git
7 changed files with 378 additions and 1 deletions
@ -0,0 +1,60 @@
|
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, |
||||
2020 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 "SkinData.h" |
||||
|
||||
#include "Magnum/Math/Matrix3.h" |
||||
#include "Magnum/Math/Matrix4.h" |
||||
#include "Magnum/Trade/Data.h" |
||||
|
||||
namespace Magnum { namespace Trade { |
||||
|
||||
template<UnsignedInt dimensions> SkinData<dimensions>::SkinData(Containers::Array<UnsignedInt>&& jointData, Containers::Array<MatrixTypeFor<dimensions, Float>>&& inverseBindMatrixData, const void* const importerState) noexcept: _jointData{std::move(jointData)}, _inverseBindMatrixData{std::move(inverseBindMatrixData)}, _importerState{importerState} { |
||||
CORRADE_ASSERT(_jointData.size() == _inverseBindMatrixData.size(), |
||||
"Trade::SkinData: joint and inverse bind matrix arrays have different size, got" << _jointData.size() << "and" << _inverseBindMatrixData.size(), ); |
||||
} |
||||
|
||||
template<UnsignedInt dimensions> SkinData<dimensions>::SkinData(const std::initializer_list<UnsignedInt> joints, const std::initializer_list<MatrixTypeFor<dimensions, Float>> inverseBindMatrices, const void* const importerState): SkinData{Containers::array(joints), Containers::array(inverseBindMatrices), importerState} {} |
||||
|
||||
template<UnsignedInt dimensions> SkinData<dimensions>::SkinData(DataFlags, const Containers::ArrayView<const UnsignedInt> jointData, DataFlags, const Containers::ArrayView<const MatrixTypeFor<dimensions, Float>> inverseBindMatrixData, const void* const importerState) noexcept: SkinData<dimensions>{Containers::Array<UnsignedInt>{const_cast<UnsignedInt*>(jointData.data()), jointData.size(), reinterpret_cast<void(*)(UnsignedInt*, std::size_t)>(Implementation::nonOwnedArrayDeleter)}, Containers::Array<MatrixTypeFor<dimensions, Float>>{const_cast<MatrixTypeFor<dimensions, Float>*>(inverseBindMatrixData.data()), inverseBindMatrixData.size(), reinterpret_cast<void(*)(MatrixTypeFor<dimensions, Float>*, std::size_t)>(Implementation::nonOwnedArrayDeleter)}, importerState} {} |
||||
|
||||
template<UnsignedInt dimensions> SkinData<dimensions>::SkinData(SkinData<dimensions>&&) noexcept = default; |
||||
|
||||
template<UnsignedInt dimensions> SkinData<dimensions>& SkinData<dimensions>::operator=(SkinData<dimensions>&&) noexcept = default; |
||||
|
||||
template<UnsignedInt dimensions> Containers::Array<UnsignedInt> SkinData<dimensions>::releaseJointData() { |
||||
return std::move(_jointData); |
||||
} |
||||
|
||||
template<UnsignedInt dimensions> Containers::Array<MatrixTypeFor<dimensions, Float>> SkinData<dimensions>::releaseInverseBindMatrixData() { |
||||
return std::move(_inverseBindMatrixData); |
||||
} |
||||
|
||||
#ifndef DOXYGEN_GENERATING_OUTPUT |
||||
template class MAGNUM_TRADE_EXPORT SkinData<2>; |
||||
template class MAGNUM_TRADE_EXPORT SkinData<3>; |
||||
#endif |
||||
|
||||
}} |
||||
@ -0,0 +1,154 @@
|
||||
#ifndef Magnum_Trade_SkinData_h |
||||
#define Magnum_Trade_SkinData_h |
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, |
||||
2020 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::SkinData |
||||
* @m_since_latest |
||||
*/ |
||||
|
||||
#include <Corrade/Containers/Array.h> |
||||
|
||||
#include "Magnum/DimensionTraits.h" |
||||
#include "Magnum/Trade/Trade.h" |
||||
#include "Magnum/Trade/visibility.h" |
||||
|
||||
namespace Magnum { namespace Trade { |
||||
|
||||
/**
|
||||
@brief Skin data |
||||
@m_since_latest |
||||
|
||||
@see @ref SkinData2D, @ref SkinData3D, @ref AbstractImporter::skin2D(), |
||||
@ref AbstractImporter::skin3D() |
||||
*/ |
||||
template<UnsignedInt dimensions> class SkinData { |
||||
public: |
||||
/**
|
||||
* @brief Constructor |
||||
* @param jointData IDs of objects that act as joints |
||||
* @param inverseBindMatrixData Inverse bind matrix for each joint |
||||
* @param importerState Importer-specific state |
||||
* |
||||
* The @p jointData and @p inverseBindMatrixData arrays are expected to |
||||
* have the same size. |
||||
*/ |
||||
explicit SkinData(Containers::Array<UnsignedInt>&& jointData, Containers::Array<MatrixTypeFor<dimensions, Float>>&& inverseBindMatrixData, const void* importerState = nullptr) noexcept; |
||||
|
||||
/** @overload */ |
||||
explicit SkinData(std::initializer_list<UnsignedInt> joints, std::initializer_list<MatrixTypeFor<dimensions, Float>> inverseBindMatrices, const void* importerState = nullptr); |
||||
|
||||
/**
|
||||
* @brief Construct a non-owned skin data |
||||
* @param jointDataFlags Ignored. Used only for a safer distinction |
||||
* from the owning constructor. |
||||
* @param jointData IDs of objects that act as joints |
||||
* @param inverseBindMatrixDataFlags Ignored. Used only for a safer |
||||
* distinction from the owning constructor. |
||||
* @param inverseBindMatrixData Inverse bind matrix for each joint |
||||
* @param importerState Importer-specific state |
||||
* |
||||
* The @p jointData and @p inverseBindMatrixData arrays are expected to |
||||
* have the same size. |
||||
*/ |
||||
explicit SkinData(DataFlags jointDataFlags, Containers::ArrayView<const UnsignedInt> jointData, DataFlags inverseBindMatrixDataFlags, Containers::ArrayView<const MatrixTypeFor<dimensions, Float>> inverseBindMatrixData, const void* importerState = nullptr) noexcept; |
||||
|
||||
/** @brief Copying is not allowed */ |
||||
SkinData(const SkinData<dimensions>&) = delete; |
||||
|
||||
/** @brief Move constructor */ |
||||
SkinData(SkinData<dimensions>&& other) noexcept; |
||||
|
||||
/** @brief Copying is not allowed */ |
||||
SkinData<dimensions>& operator=(const SkinData<dimensions>&) = delete; |
||||
|
||||
/** @brief Move assignment */ |
||||
SkinData<dimensions>& operator=(SkinData<dimensions>&& other) noexcept; |
||||
|
||||
/**
|
||||
* @brief Joint IDs |
||||
* |
||||
* IDs of objects that act as joints. |
||||
* @see @ref AbstractImporter::object2D(), |
||||
* @ref AbstractImporter::object3D(), @ref releaseJointData() |
||||
*/ |
||||
Containers::ArrayView<const UnsignedInt> joints() const { return _jointData; } |
||||
|
||||
/**
|
||||
* @brief Inverse bind matrices |
||||
* |
||||
* Transforms each joint to the initial state for skinning to be |
||||
* applied. The returned array has the same size as @ref joints(). |
||||
*/ |
||||
Containers::ArrayView<const MatrixTypeFor<dimensions, Float>> inverseBindMatrices() const { return _inverseBindMatrixData; } |
||||
|
||||
/**
|
||||
* @brief Release joint data storage |
||||
* |
||||
* Releases the ownership of the joint ID array. The material then |
||||
* behaves like if it has no joints. |
||||
* @see @ref joints() |
||||
*/ |
||||
Containers::Array<UnsignedInt> releaseJointData(); |
||||
|
||||
/**
|
||||
* @brief Release inverse bind matrix data storage |
||||
* |
||||
* Releases the ownership of the inverse bind matrix array. The |
||||
* material then behaves like if it has no matrices. |
||||
* @see @ref inverseBindMatrices() |
||||
*/ |
||||
Containers::Array<MatrixTypeFor<dimensions, Float>> releaseInverseBindMatrixData(); |
||||
|
||||
/** @brief Importer-specific state */ |
||||
const void* importerState() const { return _importerState; } |
||||
|
||||
private: |
||||
/** @todo skeleton object ID? gltf has that but the use is unclear */ |
||||
Containers::Array<UnsignedInt> _jointData; |
||||
Containers::Array<MatrixTypeFor<dimensions, Float>> _inverseBindMatrixData; |
||||
const void* _importerState; |
||||
}; |
||||
|
||||
/**
|
||||
@brief Two-dimensional skin data |
||||
@m_since_latest |
||||
|
||||
@see @ref AbstractImporter::skin2D() |
||||
*/ |
||||
typedef SkinData<2> SkinData2D; |
||||
|
||||
/**
|
||||
@brief Three-dimensional skin data |
||||
@m_since_latest |
||||
|
||||
@see @ref AbstractImporter::skin3D() |
||||
*/ |
||||
typedef SkinData<3> SkinData3D; |
||||
|
||||
}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,155 @@
|
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, |
||||
2020 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 <Corrade/Utility/DebugStl.h> |
||||
|
||||
#include "Magnum/Math/Matrix3.h" |
||||
#include "Magnum/Math/Matrix4.h" |
||||
#include "Magnum/Trade/SkinData.h" |
||||
|
||||
namespace Magnum { namespace Trade { namespace Test { namespace { |
||||
|
||||
struct SkinDataTest: TestSuite::Tester { |
||||
explicit SkinDataTest(); |
||||
|
||||
void construct(); |
||||
void constructNonOwned(); |
||||
void constructDifferentSize(); |
||||
void constructCopy(); |
||||
void constructMove(); |
||||
|
||||
void release(); |
||||
}; |
||||
|
||||
SkinDataTest::SkinDataTest() { |
||||
addTests({&SkinDataTest::construct, |
||||
&SkinDataTest::constructNonOwned, |
||||
&SkinDataTest::constructDifferentSize, |
||||
&SkinDataTest::constructCopy, |
||||
&SkinDataTest::constructMove, |
||||
|
||||
&SkinDataTest::release}); |
||||
} |
||||
|
||||
void SkinDataTest::construct() { |
||||
int state; |
||||
SkinData3D data{{0, 2, 3}, { |
||||
Matrix4::translation(Vector3::zAxis(0.0f)), |
||||
Matrix4::translation(Vector3::zAxis(2.0f)), |
||||
Matrix4::translation(Vector3::zAxis(4.0f)), |
||||
}, &state}; |
||||
|
||||
CORRADE_COMPARE(data.joints()[1], 2); |
||||
CORRADE_COMPARE(data.inverseBindMatrices()[1], Matrix4::translation(Vector3::zAxis(2.0f))); |
||||
CORRADE_COMPARE(data.importerState(), &state); |
||||
} |
||||
|
||||
void SkinDataTest::constructNonOwned() { |
||||
int state; |
||||
const UnsignedInt jointData[]{0, 2, 3}; |
||||
const Matrix4 inverseBindMatrixData[]{ |
||||
Matrix4::translation(Vector3::zAxis(0.0f)), |
||||
Matrix4::translation(Vector3::zAxis(2.0f)), |
||||
Matrix4::translation(Vector3::zAxis(4.0f)) |
||||
}; |
||||
SkinData3D data{{}, jointData, {}, inverseBindMatrixData, &state}; |
||||
|
||||
CORRADE_COMPARE(data.joints().size(), 3); |
||||
CORRADE_COMPARE(data.joints().data(), jointData); |
||||
CORRADE_COMPARE(data.inverseBindMatrices().size(), 3); |
||||
CORRADE_COMPARE(data.inverseBindMatrices().data(), inverseBindMatrixData); |
||||
CORRADE_COMPARE(data.importerState(), &state); |
||||
} |
||||
|
||||
void SkinDataTest::constructDifferentSize() { |
||||
#ifdef CORRADE_NO_ASSERT |
||||
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions"); |
||||
#endif |
||||
|
||||
std::ostringstream out; |
||||
Error redirectError{&out}; |
||||
SkinData3D data{{0, 2}, {{}, {}, {}}}; |
||||
CORRADE_COMPARE(out.str(), "Trade::SkinData: joint and inverse bind matrix arrays have different size, got 2 and 3\n"); |
||||
} |
||||
|
||||
void SkinDataTest::constructCopy() { |
||||
CORRADE_VERIFY(!(std::is_constructible<SkinData3D, const SkinData3D&>{})); |
||||
CORRADE_VERIFY(!(std::is_assignable<SkinData3D, const SkinData3D&>{})); |
||||
} |
||||
|
||||
void SkinDataTest::constructMove() { |
||||
int state; |
||||
SkinData3D a{{0, 2, 3}, { |
||||
Matrix4::translation(Vector3::zAxis(0.0f)), |
||||
Matrix4::translation(Vector3::zAxis(2.0f)), |
||||
Matrix4::translation(Vector3::zAxis(4.0f)), |
||||
}, &state}; |
||||
|
||||
SkinData3D b = std::move(a); |
||||
CORRADE_COMPARE(b.joints()[1], 2); |
||||
CORRADE_COMPARE(b.inverseBindMatrices()[1], Matrix4::translation(Vector3::zAxis(2.0f))); |
||||
CORRADE_COMPARE(b.importerState(), &state); |
||||
|
||||
SkinData3D c{{}, {}}; |
||||
c = std::move(b); |
||||
CORRADE_COMPARE(c.joints()[1], 2); |
||||
CORRADE_COMPARE(c.inverseBindMatrices()[1], Matrix4::translation(Vector3::zAxis(2.0f))); |
||||
CORRADE_COMPARE(c.importerState(), &state); |
||||
|
||||
CORRADE_VERIFY(std::is_nothrow_move_constructible<SkinData2D>::value); |
||||
CORRADE_VERIFY(std::is_nothrow_move_assignable<SkinData2D>::value); |
||||
} |
||||
|
||||
void SkinDataTest::release() { |
||||
Containers::Array<UnsignedInt> joints{Containers::InPlaceInit, {0, 2, 3}}; |
||||
Containers::Array<Matrix3> inverseBindMatrices{Containers::InPlaceInit, { |
||||
Matrix3::translation(Vector2::yAxis(0.0f)), |
||||
Matrix3::translation(Vector2::yAxis(2.0f)), |
||||
Matrix3::translation(Vector2::yAxis(4.0f)) |
||||
}}; |
||||
|
||||
const void* jointsPointer = joints; |
||||
const void* inverseBindMatricesPointer = inverseBindMatrices; |
||||
|
||||
SkinData2D data{std::move(joints), std::move(inverseBindMatrices)}; |
||||
|
||||
Containers::Array<UnsignedInt> releasedJoints = data.releaseJointData(); |
||||
CORRADE_COMPARE(data.joints().size(), 0); |
||||
CORRADE_COMPARE(data.inverseBindMatrices().size(), 3); |
||||
CORRADE_COMPARE(releasedJoints.size(), 3); |
||||
CORRADE_COMPARE(releasedJoints, jointsPointer); |
||||
|
||||
Containers::Array<Matrix3> releasedInverseBindMatrices = data.releaseInverseBindMatrixData(); |
||||
CORRADE_COMPARE(data.joints().size(), 0); |
||||
CORRADE_COMPARE(data.inverseBindMatrices().size(), 0); |
||||
CORRADE_COMPARE(releasedInverseBindMatrices.size(), 3); |
||||
CORRADE_COMPARE(releasedInverseBindMatrices, inverseBindMatricesPointer); |
||||
} |
||||
|
||||
}}}} |
||||
|
||||
CORRADE_TEST_MAIN(Magnum::Trade::Test::SkinDataTest) |
||||
Loading…
Reference in new issue