Browse Source

Trade: new SkinData class.

pull/470/head
Vladimír Vondruš 6 years ago
parent
commit
e8b64544df
  1. 1
      doc/changelog.dox
  2. 4
      src/Magnum/Trade/CMakeLists.txt
  3. 60
      src/Magnum/Trade/SkinData.cpp
  4. 154
      src/Magnum/Trade/SkinData.h
  5. 1
      src/Magnum/Trade/Test/CMakeLists.txt
  6. 155
      src/Magnum/Trade/Test/SkinDataTest.cpp
  7. 4
      src/Magnum/Trade/Trade.h

1
doc/changelog.dox

@ -91,6 +91,7 @@ See also:
@ref Trade::PhongMaterialData::normalTextureScale() and
@ref Trade::PhongMaterialData::normalTextureSwizzle() to make new features
added for PBR materials recognizable also in classic Phong workflows.
- New @ref Trade::SkinData class for skin import
@subsection changelog-latest-changes Changes and improvements

4
src/Magnum/Trade/CMakeLists.txt

@ -49,7 +49,8 @@ set(MagnumTrade_GracefulAssert_SRCS
PbrClearCoatMaterialData.cpp
PbrMetallicRoughnessMaterialData.cpp
PbrSpecularGlossinessMaterialData.cpp
PhongMaterialData.cpp)
PhongMaterialData.cpp
SkinData.cpp)
set(MagnumTrade_HEADERS
AbstractImporter.h
@ -74,6 +75,7 @@ set(MagnumTrade_HEADERS
PbrSpecularGlossinessMaterialData.h
PhongMaterialData.h
SceneData.h
SkinData.h
TextureData.h
Trade.h

60
src/Magnum/Trade/SkinData.cpp

@ -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
}}

154
src/Magnum/Trade/SkinData.h

@ -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

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

@ -56,6 +56,7 @@ corrade_add_test(TradeMeshDataTest MeshDataTest.cpp LIBRARIES MagnumTradeTestLib
corrade_add_test(TradeObjectData2DTest ObjectData2DTest.cpp LIBRARIES MagnumTradeTestLib)
corrade_add_test(TradeObjectData3DTest ObjectData3DTest.cpp LIBRARIES MagnumTradeTestLib)
corrade_add_test(TradeSceneDataTest SceneDataTest.cpp LIBRARIES MagnumTrade)
corrade_add_test(TradeSkinDataTest SkinDataTest.cpp LIBRARIES MagnumTradeTestLib)
corrade_add_test(TradeTextureDataTest TextureDataTest.cpp LIBRARIES MagnumTrade)
set_property(TARGET

155
src/Magnum/Trade/Test/SkinDataTest.cpp

@ -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)

4
src/Magnum/Trade/Trade.h

@ -99,6 +99,10 @@ class PbrSpecularGlossinessMaterialData;
class PhongMaterialData;
class TextureData;
class SceneData;
template<UnsignedInt> class SkinData;
typedef SkinData<2> SkinData2D;
typedef SkinData<3> SkinData3D;
#endif
}}

Loading…
Cancel
Save