Browse Source

WIP

Signed-off-by: Squareys <squareys@googlemail.com>
pull/444/head
Squareys 6 years ago
parent
commit
0ffa866bda
  1. 13
      src/Magnum/Shaders/Generic.h
  2. 18
      src/Magnum/Trade/MeshData.cpp
  3. 20
      src/Magnum/Trade/MeshData.h
  4. 106
      src/Magnum/Trade/Test/MeshDataTest.cpp

13
src/Magnum/Shaders/Generic.h

@ -132,7 +132,7 @@ both bitangents and object ID for instancing, \n
<tr> <tr>
<td>7</td> <td>7</td>
<td colspan="3"> <td colspan="3">
@ref JointIndices @ref JointIds
</td> </td>
</tr> </tr>
<tr> <tr>
@ -150,13 +150,13 @@ both bitangents and object ID for instancing, \n
<tr> <tr>
<td>10</td> <td>10</td>
<td colspan="2"> <td colspan="2">
@ref Weights @ref SecondaryWeights
</td> </td>
</tr> </tr>
<tr> <tr>
<td>11</td> <td>11</td>
<td colspan="2"> <td colspan="2">
@ref JointIndices @ref SecondaryJointIds
</td> </td>
</tr> </tr>
<tr> <tr>
@ -469,6 +469,11 @@ struct BaseGeneric {
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
typedef GL::Attribute<4, UnsignedInt> ObjectId; typedef GL::Attribute<4, UnsignedInt> ObjectId;
#endif #endif
typedef GL::Attribute<6, Vector4> Weights;
typedef GL::Attribute<7, Vector4> JointIds;
typedef GL::Attribute<10, Vector4> SecondaryWeights;
typedef GL::Attribute<11, Vector4> SecondaryJointIds;
typedef GL::Attribute<15, Vector2> TextureOffset; typedef GL::Attribute<15, Vector2> TextureOffset;
@ -497,8 +502,6 @@ template<> struct Generic<3>: BaseGeneric {
typedef GL::Attribute<3, Vector4> Tangent4; typedef GL::Attribute<3, Vector4> Tangent4;
typedef GL::Attribute<4, Vector3> Bitangent; /* also ObjectId */ typedef GL::Attribute<4, Vector3> Bitangent; /* also ObjectId */
typedef GL::Attribute<5, Vector3> Normal; typedef GL::Attribute<5, Vector3> Normal;
typedef GL::Attribute<6, Vector4> Weights;
typedef GL::Attribute<7, Vector4> JointIds;
typedef GL::Attribute<8, Matrix4> TransformationMatrix; typedef GL::Attribute<8, Matrix4> TransformationMatrix;
/* 9, 10, 11 occupied by TransformationMatrix */ /* 9, 10, 11 occupied by TransformationMatrix */

18
src/Magnum/Trade/MeshData.cpp

@ -791,26 +791,13 @@ void MeshData::weightsInto(const Containers::StridedArrayView1D<Vector4> destina
Utility::copy(Containers::arrayCast<const Vector4>(attributeData), destination); Utility::copy(Containers::arrayCast<const Vector4>(attributeData), destination);
else if(attribute._format == VertexFormat::Vector4h) else if(attribute._format == VertexFormat::Vector4h)
Math::unpackHalfInto(Containers::arrayCast<2, const UnsignedShort>(attributeData, 4), destination4f); 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) else if(attribute._format == VertexFormat::Vector4ubNormalized)
Math::unpackInto(Containers::arrayCast<2, const UnsignedByte>(attributeData, 4), destination4f); 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) else if(attribute._format == VertexFormat::Vector4usNormalized)
Math::unpackInto(Containers::arrayCast<2, const UnsignedShort>(attributeData, 4), destination4f); 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 */ else CORRADE_INTERNAL_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */
} }
Containers::Array<Vector4> MeshData::weightsAsArray(const UnsignedInt id) const { Containers::Array<Vector4> MeshData::weightsAsArray(const UnsignedInt id) const {
Containers::Array<Vector4> out{_vertexCount}; Containers::Array<Vector4> out{_vertexCount};
weightsInto(out, id); weightsInto(out, id);
@ -825,13 +812,14 @@ void MeshData::jointIdsInto(const Containers::StridedArrayView1D<Vector4ui> dest
CORRADE_ASSERT(!isVertexFormatImplementationSpecific(attribute._format), CORRADE_ASSERT(!isVertexFormatImplementationSpecific(attribute._format),
"Trade::MeshData::jointIdsInto(): can't extract data out of an implementation-specific vertex format" << reinterpret_cast<void*>(vertexFormatUnwrap(attribute._format)), ); "Trade::MeshData::jointIdsInto(): can't extract data out of an implementation-specific vertex format" << reinterpret_cast<void*>(vertexFormatUnwrap(attribute._format)), );
const Containers::StridedArrayView1D<const void> attributeData = attributeDataViewInternal(attribute); const Containers::StridedArrayView1D<const void> attributeData = attributeDataViewInternal(attribute);
const Containers::StridedArrayView2D<UnsignedInt> destination4ui = Containers::arrayCast<2, UnsignedInt>(destination);
if(attribute._format == VertexFormat::Vector4ui) if(attribute._format == VertexFormat::Vector4ui)
Utility::copy(Containers::arrayCast<const Vector4ui>(attributeData), destination); Utility::copy(Containers::arrayCast<const Vector4ui>(attributeData), destination);
else if(attribute._format == VertexFormat::Vector4ub) else if(attribute._format == VertexFormat::Vector4ub)
Utility::copy(Containers::arrayCast<const Vector4ub>(attributeData), destination); Math::castInto(Containers::arrayCast<2, const UnsignedByte>(attributeData, 4), destination4ui);
else if(attribute._format == VertexFormat::Vector4us) else if(attribute._format == VertexFormat::Vector4us)
Utility::copy(Containers::arrayCast<const Vector4us>(attributeData), destination); Math::castInto(Containers::arrayCast<2, const UnsignedShort>(attributeData, 4), destination4ui);
else CORRADE_INTERNAL_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */ else CORRADE_INTERNAL_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */
} }

20
src/Magnum/Trade/MeshData.h

@ -149,12 +149,9 @@ enum class MeshAttribute: UnsignedShort {
/** /**
* Weights. Type is usually @ref VertexFormat::Vector4, but can be also * Weights. Type is usually @ref VertexFormat::Vector4, but can be also
* @ref VertexFormat::Vector4h, @ref VertexFormat::Vector4ub, * @ref VertexFormat::Vector4h, @ref VertexFormat::Vector4ubNormalized
* @ref VertexFormat::Vector4b, @ref VertexFormat::Vector4us, * or @ref VertexFormat::Vector4usNormalized.
* @ref VertexFormat::Vector4s, @ref VertexFormat::Vector4ubNormalized, * Corresponds to @ref Shaders::Generic::Weights.
* @ref VertexFormat::Vector4bNormalized, @ref VertexFormat::Vector4usNormalized
* or @ref VertexFormat::Vector4sNormalized.
* Corresponds to * @ref Shaders::Generic::Weights.
* @see @ref MeshData::weightsAsArray() * @see @ref MeshData::weightsAsArray()
*/ */
Weights, Weights,
@ -162,7 +159,7 @@ enum class MeshAttribute: UnsignedShort {
/** /**
* Joint IDs. Type is usually @ref VertexFormat::Vector4ui, but can be also * Joint IDs. Type is usually @ref VertexFormat::Vector4ui, but can be also
* @ref VertexFormat::Vector4us or @ref VertexFormat::Vector4ub. * @ref VertexFormat::Vector4us or @ref VertexFormat::Vector4ub.
* @ref Shaders::Generic::JointIds. * Corresponds to @ref Shaders::Generic::JointIds.
* @see @ref MeshData::jointIdsAsArray() * @see @ref MeshData::jointIdsAsArray()
*/ */
JointIds, JointIds,
@ -2132,6 +2129,15 @@ namespace Implementation {
(format == VertexFormat::UnsignedInt || (format == VertexFormat::UnsignedInt ||
format == VertexFormat::UnsignedShort || format == VertexFormat::UnsignedShort ||
format == VertexFormat::UnsignedByte)) || format == VertexFormat::UnsignedByte)) ||
(name == MeshAttribute::Weights &&
(format == VertexFormat::Vector4 ||
format == VertexFormat::Vector4h ||
format == VertexFormat::Vector4ubNormalized ||
format == VertexFormat::Vector4usNormalized)) ||
(name == MeshAttribute::JointIds &&
(format == VertexFormat::Vector4ui ||
format == VertexFormat::Vector4ub ||
format == VertexFormat::Vector4us)) ||
/* Custom attributes can be anything */ /* Custom attributes can be anything */
isMeshAttributeCustom(name); isMeshAttributeCustom(name);
} }

106
src/Magnum/Trade/Test/MeshDataTest.cpp

@ -146,6 +146,14 @@ struct MeshDataTest: TestSuite::Tester {
template<class T> void objectIdsAsArray(); template<class T> void objectIdsAsArray();
void objectIdsIntoArrayInvalidSize(); void objectIdsIntoArrayInvalidSize();
template<class T> void weightsAsArray();
template<class T> void weightsAsArrayPackedUnsignedNormalized();
template<class T> void weightsAsArrayPackedSignedNormalized();
void weightsIntoArrayInvalidSize();
template<class T> void jointIdsAsArray();
void jointIdsIntoArrayInvalidSize();
void implementationSpecificVertexFormat(); void implementationSpecificVertexFormat();
void implementationSpecificVertexFormatWrongAccess(); void implementationSpecificVertexFormatWrongAccess();
void implementationSpecificVertexFormatNotContained(); void implementationSpecificVertexFormatNotContained();
@ -364,6 +372,17 @@ MeshDataTest::MeshDataTest() {
&MeshDataTest::objectIdsAsArray<UnsignedInt>, &MeshDataTest::objectIdsAsArray<UnsignedInt>,
&MeshDataTest::objectIdsIntoArrayInvalidSize, &MeshDataTest::objectIdsIntoArrayInvalidSize,
&MeshDataTest::weightsAsArray<Vector4>,
&MeshDataTest::weightsAsArray<Vector4h>,
&MeshDataTest::weightsAsArrayPackedUnsignedNormalized<Vector4ub>,
&MeshDataTest::weightsAsArrayPackedUnsignedNormalized<Vector4us>,
&MeshDataTest::weightsIntoArrayInvalidSize,
&MeshDataTest::jointIdsAsArray<Vector4ui>,
&MeshDataTest::jointIdsAsArray<Vector4us>,
&MeshDataTest::jointIdsAsArray<Vector4ub>,
&MeshDataTest::jointIdsIntoArrayInvalidSize,
&MeshDataTest::implementationSpecificVertexFormat, &MeshDataTest::implementationSpecificVertexFormat,
&MeshDataTest::implementationSpecificVertexFormatWrongAccess, &MeshDataTest::implementationSpecificVertexFormatWrongAccess,
&MeshDataTest::implementationSpecificVertexFormatNotContained, &MeshDataTest::implementationSpecificVertexFormatNotContained,
@ -1856,8 +1875,11 @@ _c(Vector3b)
_c(Vector3us) _c(Vector3us)
_c(Vector3s) _c(Vector3s)
_c(Vector4) _c(Vector4)
_c(Vector4ui)
_c(Vector4h) _c(Vector4h)
_c(Vector4ub)
_c(Vector4b) _c(Vector4b)
_c(Vector4us)
_c(Vector4s) _c(Vector4s)
_c(Color3) _c(Color3)
_c(Color3h) _c(Color3h)
@ -2500,6 +2522,90 @@ void MeshDataTest::objectIdsIntoArrayInvalidSize() {
"Trade::MeshData::objectIdsInto(): expected a view with 3 elements but got 2\n"); "Trade::MeshData::objectIdsInto(): expected a view with 3 elements but got 2\n");
} }
template<class T> void MeshDataTest::weightsAsArray() {
setTestCaseTemplateName(NameTraits<T>::name());
typedef typename T::Type U;
Containers::Array<char> vertexData{3*sizeof(T)};
auto weightsView = Containers::arrayCast<T>(vertexData);
/* Needs to be sufficiently representable to have the test work also for
half floats */
weightsView[0] = T::pad(Math::Vector4<U>{U(2.0f), U(1.0f), U(0.75f), U(3.0f)});
weightsView[1] = T::pad(Math::Vector4<U>{U(0.0f), U(-1.0f), U(1.25f), U(1.0f)});
weightsView[2] = T::pad(Math::Vector4<U>{U(-2.0f), U(3.0f), U(2.5f), U(2.5f)});
MeshData data{MeshPrimitive::Points, std::move(vertexData), {MeshAttributeData{MeshAttribute::Weights, weightsView}}};
CORRADE_COMPARE_AS(data.weightsAsArray(), Containers::arrayView<Vector4>({
{2.0f, 1.0f, 0.75f, 3.0f}, {0.0f, -1.0f, 1.25f, 1.0f}, {-2.0f, 3.0f, 2.5f, 2.5f},
}), TestSuite::Compare::Container);
}
template<class T> void MeshDataTest::weightsAsArrayPackedUnsignedNormalized() {
setTestCaseTemplateName(NameTraits<T>::name());
Containers::Array<char> vertexData{2*sizeof(T)};
auto weightsView = Containers::arrayCast<T>(vertexData);
weightsView[0] = T::pad(Math::Vector4<typename T::Type>{Math::pack<typename T::Type>(1.0f), 0, Math::pack<typename T::Type>(1.0f), Math::pack<typename T::Type>(0.8)});
weightsView[1] = T::pad(Math::Vector4<typename T::Type>{0, Math::pack<typename T::Type>(1.0f), 0, Math::pack<typename T::Type>(0.4f)});
MeshData data{MeshPrimitive::Points, std::move(vertexData), {MeshAttributeData{MeshAttribute::Weights,
/* Assuming the normalized enum is always after the non-normalized */
VertexFormat(UnsignedInt(Implementation::vertexFormatFor<T>()) + 1),
weightsView}}};
CORRADE_COMPARE_AS(data.weightsAsArray(), Containers::arrayView<Vector4>({
Vector4::pad(Math::Vector<T::Size, Float>::pad(Vector4{1.0f, 0.0f, 1.0f, 0.8})),
Vector4::pad(Math::Vector<T::Size, Float>::pad(Vector4{0.0f, 1.0f, 0.0f, 0.4f}))
}), TestSuite::Compare::Container);
}
void MeshDataTest::weightsIntoArrayInvalidSize() {
#ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");
#endif
Containers::Array<char> vertexData{3*sizeof(Vector4)};
MeshData data{MeshPrimitive::Points, std::move(vertexData), {MeshAttributeData{MeshAttribute::Weights, Containers::arrayCast<Vector4>(vertexData)}}};
std::ostringstream out;
Error redirectError{&out};
Vector4 destination[2];
data.weightsInto(destination);
CORRADE_COMPARE(out.str(),
"Trade::MeshData::weightsInto(): expected a view with 3 elements but got 2\n");
}
template<class T> void MeshDataTest::jointIdsAsArray() {
setTestCaseTemplateName(NameTraits<T>::name());
typedef typename T::Type U;
Containers::Array<char> vertexData{3*sizeof(T)};
auto joinIdsView = Containers::arrayCast<T>(vertexData);
joinIdsView[0] = {U(0), U(1), U(2), U(3)};
joinIdsView[1] = {U(4), U(5), U(6), U(7)};
joinIdsView[2] = {U(8), U(9), U(10), U(11)};
MeshData data{MeshPrimitive::Points, std::move(vertexData), {MeshAttributeData{MeshAttribute::JointIds, joinIdsView}}};
CORRADE_COMPARE_AS(data.jointIdsAsArray(), Containers::arrayView<Vector4ui>({
{0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11},
}), TestSuite::Compare::Container);
}
void MeshDataTest::jointIdsIntoArrayInvalidSize() {
#ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");
#endif
Containers::Array<char> vertexData{3*sizeof(Vector4ui)};
MeshData data{MeshPrimitive::Points, std::move(vertexData), {MeshAttributeData{MeshAttribute::JointIds, Containers::arrayCast<Vector4ui>(vertexData)}}};
std::ostringstream out;
Error redirectError{&out};
Vector4ui destination[2];
data.jointIdsInto(destination);
CORRADE_COMPARE(out.str(),
"Trade::MeshData::jointIdsInto(): expected a view with 3 elements but got 2\n");
}
/* MSVC 2015 doesn't like anonymous bitfields in inline structs, so putting the /* MSVC 2015 doesn't like anonymous bitfields in inline structs, so putting the
declaration outside */ declaration outside */
struct VertexWithImplementationSpecificData { struct VertexWithImplementationSpecificData {

Loading…
Cancel
Save