From 90462159236c89f08f8b48fd9e913e0aafaaa961 Mon Sep 17 00:00:00 2001 From: Squareys Date: Thu, 7 May 2020 15:42:21 +0200 Subject: [PATCH] fixup! MeshAttribute Signed-off-by: Squareys --- src/Magnum/Trade/MeshData.cpp | 60 +++++++++++++++++++++++++++++++++-- src/Magnum/Trade/MeshData.h | 36 +++++++++++---------- 2 files changed, 76 insertions(+), 20 deletions(-) diff --git a/src/Magnum/Trade/MeshData.cpp b/src/Magnum/Trade/MeshData.cpp index 658438945..94ac37036 100644 --- a/src/Magnum/Trade/MeshData.cpp +++ b/src/Magnum/Trade/MeshData.cpp @@ -777,15 +777,67 @@ Containers::Array MeshData::objectIdsAsArray(const UnsignedInt id) return out; } +void MeshData::weightsInto(const Containers::StridedArrayView1D destination, const UnsignedInt id) const { + const UnsignedInt attributeId = attributeFor(MeshAttribute::Weights, id); + CORRADE_ASSERT(attributeId != ~UnsignedInt{}, "Trade::MeshData::weightsInto(): index" << id << "out of range for" << attributeCount(MeshAttribute::Weights) << "weights attributes", ); + CORRADE_ASSERT(destination.size() == _vertexCount, "Trade::MeshData::weightsInto(): expected a view with" << _vertexCount << "elements but got" << destination.size(), ); + const MeshAttributeData& attribute = _attributes[attributeId]; + CORRADE_ASSERT(!isVertexFormatImplementationSpecific(attribute._format), + "Trade::MeshData::weightsInto(): can't extract data out of an implementation-specific vertex format" << reinterpret_cast(vertexFormatUnwrap(attribute._format)), ); + const Containers::StridedArrayView1D attributeData = attributeDataViewInternal(attribute); + const Containers::StridedArrayView2D destination4f = Containers::arrayCast<2, Float>(destination); + + if(attribute._format == VertexFormat::Vector4) + Utility::copy(Containers::arrayCast(attributeData), destination); + else if(attribute._format == VertexFormat::Vector4h) + Math::unpackHalfInto(Containers::arrayCast<2, const UnsignedShort>(attributeData, 4), destination4f); + else if(attribute._format == VertexFormat::Vector4ub) + Math::castInto(Containers::arrayCast<2, const UnsignedByte>(attributeData, 4), destination4f); + else if(attribute._format == VertexFormat::Vector4b) + Math::castInto(Containers::arrayCast<2, const Byte>(attributeData, 4), destination4f); + else if(attribute._format == VertexFormat::Vector4us) + Math::castInto(Containers::arrayCast<2, const UnsignedShort>(attributeData, 4), destination4f); + else if(attribute._format == VertexFormat::Vector4s) + Math::castInto(Containers::arrayCast<2, const Short>(attributeData, 4), destination4f); + else if(attribute._format == VertexFormat::Vector4ubNormalized) + Math::unpackInto(Containers::arrayCast<2, const UnsignedByte>(attributeData, 4), destination4f); + else if(attribute._format == VertexFormat::Vector4bNormalized) + Math::unpackInto(Containers::arrayCast<2, const Byte>(attributeData, 4), destination4f); + else if(attribute._format == VertexFormat::Vector4usNormalized) + Math::unpackInto(Containers::arrayCast<2, const UnsignedShort>(attributeData, 4), destination4f); + else if(attribute._format == VertexFormat::Vector4sNormalized) + Math::unpackInto(Containers::arrayCast<2, const Short>(attributeData, 4), destination4f); + else CORRADE_INTERNAL_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */ +} + + Containers::Array MeshData::weightsAsArray(const UnsignedInt id) const { Containers::Array out{_vertexCount}; weightsInto(out, id); return out; } -Containers::Array MeshData::jointIndicesAsArray(const UnsignedInt id) const { - Containers::Array out{_vertexCount}; - jointIndicesInto(out, id); +void MeshData::jointIdsInto(const Containers::StridedArrayView1D destination, const UnsignedInt id) const { + const UnsignedInt attributeId = attributeFor(MeshAttribute::JointIds, id); + CORRADE_ASSERT(attributeId != ~UnsignedInt{}, "Trade::MeshData::jointIdsInto(): index" << id << "out of range for" << attributeCount(MeshAttribute::JointIds) << "joint IDs attributes", ); + CORRADE_ASSERT(destination.size() == _vertexCount, "Trade::MeshData::jointIdsInto(): expected a view with" << _vertexCount << "elements but got" << destination.size(), ); + const MeshAttributeData& attribute = _attributes[attributeId]; + CORRADE_ASSERT(!isVertexFormatImplementationSpecific(attribute._format), + "Trade::MeshData::jointIdsInto(): can't extract data out of an implementation-specific vertex format" << reinterpret_cast(vertexFormatUnwrap(attribute._format)), ); + const Containers::StridedArrayView1D attributeData = attributeDataViewInternal(attribute); + + if(attribute._format == VertexFormat::Vector4ui) + Utility::copy(Containers::arrayCast(attributeData), destination); + else if(attribute._format == VertexFormat::Vector4ub) + Utility::copy(Containers::arrayCast(attributeData), destination); + else if(attribute._format == VertexFormat::Vector4us) + Utility::copy(Containers::arrayCast(attributeData), destination); + else CORRADE_INTERNAL_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */ +} + +Containers::Array MeshData::jointIdsAsArray(const UnsignedInt id) const { + Containers::Array out{_vertexCount}; + jointIdsInto(out, id); return out; } @@ -823,6 +875,8 @@ Debug& operator<<(Debug& debug, const MeshAttribute value) { _c(TextureCoordinates) _c(Color) _c(ObjectId) + _c(Weights) + _c(JointIds) #undef _c /* LCOV_EXCL_STOP */ diff --git a/src/Magnum/Trade/MeshData.h b/src/Magnum/Trade/MeshData.h index 632133952..221713b22 100644 --- a/src/Magnum/Trade/MeshData.h +++ b/src/Magnum/Trade/MeshData.h @@ -149,21 +149,23 @@ enum class MeshAttribute: UnsignedShort { /** * Weights. Type is usually @ref VertexFormat::Vector4, but can be also - * @ref VertexFormat::Vector4h, @ref VertexFormat::Vector4bNormalized or - * @ref VertexFormat::Vector4sNormalized. Corresponds to - * @ref Shaders::Generic::Weights. + * @ref VertexFormat::Vector4h, @ref VertexFormat::Vector4ub, + * @ref VertexFormat::Vector4b, @ref VertexFormat::Vector4us, + * @ref VertexFormat::Vector4s, @ref VertexFormat::Vector4ubNormalized, + * @ref VertexFormat::Vector4bNormalized, @ref VertexFormat::Vector4usNormalized + * or @ref VertexFormat::Vector4sNormalized. + * Corresponds to * @ref Shaders::Generic::Weights. * @see @ref MeshData::weightsAsArray() */ Weights, /** - * JointIndices. Type is usually @ref VertexFormat::Vector4ui, but can be also - * @ref VertexFormat::Vector4i, @ref VertexFormat::Vector4s, @ref VertexFormat::Vector4us, - * @ref VertexFormat::Vector4ub or @ref VertexFormat::Vector4b. Corresponds to - * @ref Shaders::Generic::JointIndices. - * @see @ref MeshData::jointIndicesAsArray() + * Joint IDs. Type is usually @ref VertexFormat::Vector4ui, but can be also + * @ref VertexFormat::Vector4us or @ref VertexFormat::Vector4ub. + * @ref Shaders::Generic::JointIds. + * @see @ref MeshData::jointIdsAsArray() */ - JointIndices, + JointIds, /** * This and all higher values are for importer-specific attributes. Can be @@ -632,7 +634,7 @@ The simplest usage is through the convenience functions @ref positions2DAsArray( @ref positions3DAsArray(), @ref tangentsAsArray(), @ref bitangentsAsArray(), @ref normalsAsArray(), @ref tangentsAsArray(), @ref textureCoordinates2DAsArray(), @ref colorsAsArray(), @ref objectIdsAsArray(), @ref weightsAsArray() and -@ref jointIndicesAsArray(). Each of these takes an index (as there can be multiple +@ref jointIdsAsArray(). Each of these takes an index (as there can be multiple sets of texture coordinates, for example) and you're expected to check for attribute presence first with either @ref hasAttribute() or @ref attributeCount(MeshAttribute) const: @@ -1761,28 +1763,28 @@ class MAGNUM_TRADE_EXPORT MeshData { void weightsInto(Containers::StridedArrayView1D destination, UnsignedInt id = 0) const; /** - * @brief Weights as 4D unsigned short vectors + * @brief Joint IDs as 4D unsigned int vectors * * Convenience alternative to @ref attribute(MeshAttribute, UnsignedInt) const - * with @ref MeshAttribute::JointIndices as the first argument. Converts + * with @ref MeshAttribute::JointIds as the first argument. Converts * the joint indices array from an arbitrary underlying type and returns it * in a newly-allocated array. Expects that the vertex format is *not* * implementation-specific, in that case you can only access the * attribute via the typeless @ref attribute(MeshAttribute, UnsignedInt) const. - * @see @ref jointIndicesInto(), @ref attributeFormat(), + * @see @ref jointIdsInto(), @ref attributeFormat(), * @ref isVertexFormatImplementationSpecific() */ - Containers::Array jointIndicesAsArray(UnsignedInt id = 0) const; + Containers::Array jointIdsAsArray(UnsignedInt id = 0) const; /** - * @brief Weights as 4D unsigned short vectors into a pre-allocated view + * @brief Joint IDs as 4D unsigned int vectors into a pre-allocated view * - * Like @ref jointIndicesAsArray(), but puts the result into + * Like @ref jointIdsAsArray(), but puts the result into * @p destination instead of allocating a new array. Expects that * @p destination is sized to contain exactly all data. * @see @ref vertexCount() */ - void jointIndicesInto(Containers::StridedArrayView1D destination, UnsignedInt id = 0) const; + void jointIdsInto(Containers::StridedArrayView1D destination, UnsignedInt id = 0) const; /** * @brief Release index data storage