diff --git a/src/Magnum/MeshTools/Test/CombineTest.cpp b/src/Magnum/MeshTools/Test/CombineTest.cpp index bb1bb2645..9d31ac641 100644 --- a/src/Magnum/MeshTools/Test/CombineTest.cpp +++ b/src/Magnum/MeshTools/Test/CombineTest.cpp @@ -88,7 +88,7 @@ void CombineTest::combineIndexedAttributes() { const UnsignedInt indicesA[]{2, 1, 2, 0}; const Int dataA[]{2, 1, 0}; const UnsignedByte indicesB[]{3, 4, 3, 2}; - const Short dataB[]{4, 3, 2, 1, 0}; + const Byte dataB[][2]{{4, 1}, {3, 2}, {2, 3}, {1, 4}, {0, 5}}; const UnsignedShort indicesC[]{7, 6, 7, 5}; const Float dataC[]{0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f}; Trade::MeshData a{MeshPrimitive::LineLoop, @@ -98,7 +98,9 @@ void CombineTest::combineIndexedAttributes() { Trade::MeshData b{MeshPrimitive::LineLoop, {}, indicesB, Trade::MeshIndexData{indicesB}, {}, dataB, {Trade::MeshAttributeData{ - Trade::meshAttributeCustom(17), Containers::arrayView(dataB)}}}; + /* Array attribute to verify it's correctly propagated */ + Trade::meshAttributeCustom(17), VertexFormat::Byte, 2, + Containers::arrayView(dataB)}}}; Trade::MeshData c{MeshPrimitive::LineLoop, {}, indicesC, Trade::MeshIndexData{indicesC}, {}, dataC, {Trade::MeshAttributeData{ @@ -119,9 +121,10 @@ void CombineTest::combineIndexedAttributes() { Containers::arrayView({0, 1, 2}), TestSuite::Compare::Container); CORRADE_COMPARE(result.attributeName(1), Trade::meshAttributeCustom(17)); - CORRADE_COMPARE(result.attributeFormat(1), VertexFormat::Short); - CORRADE_COMPARE_AS(result.attribute(1), - Containers::arrayView({1, 0, 2}), + CORRADE_COMPARE(result.attributeFormat(1), VertexFormat::Byte); + CORRADE_COMPARE(result.attributeArraySize(1), 2); + CORRADE_COMPARE_AS((Containers::arrayCast<1, const Vector2b>(result.attribute(1))), + Containers::arrayView({{1, 4}, {0, 5}, {2, 3}}), TestSuite::Compare::Container); CORRADE_COMPARE(result.attributeName(2), Trade::meshAttributeCustom(22)); CORRADE_COMPARE(result.attributeFormat(2), VertexFormat::Float); diff --git a/src/Magnum/MeshTools/Test/CompressIndicesTest.cpp b/src/Magnum/MeshTools/Test/CompressIndicesTest.cpp index 39d9263ac..c94a9c5f9 100644 --- a/src/Magnum/MeshTools/Test/CompressIndicesTest.cpp +++ b/src/Magnum/MeshTools/Test/CompressIndicesTest.cpp @@ -255,12 +255,15 @@ template void CompressIndicesTest::compressMeshData() { setTestCaseTemplateName(Math::TypeTraits::name()); struct { - Vector2 positions[103]; + Float data[103][2]; Vector3 normals[103]; } vertexData{}; - vertexData.positions[100] = {1.3f, 0.3f}; - vertexData.positions[101] = {0.87f, 1.1f}; - vertexData.positions[102] = {1.0f, -0.5f}; + vertexData.data[100][0] = 1.3f; + vertexData.data[100][1] = 0.3f; + vertexData.data[101][0] = 0.87f; + vertexData.data[101][1] = 1.1f; + vertexData.data[102][0] = 1.0f; + vertexData.data[102][1] = -0.5f; vertexData.normals[100] = Vector3::xAxis(); vertexData.normals[101] = Vector3::yAxis(); vertexData.normals[102] = Vector3::zAxis(); @@ -269,7 +272,9 @@ template void CompressIndicesTest::compressMeshData() { Trade::MeshData data{MeshPrimitive::TriangleFan, {}, indices, Trade::MeshIndexData{indices}, {}, Containers::arrayView(&vertexData, 1), { - Trade::MeshAttributeData{Trade::MeshAttribute::Position, Containers::arrayView(vertexData.positions)}, + Trade::MeshAttributeData{Trade::meshAttributeCustom(42), + /* Array attribute to verify it's correctly propagated */ + VertexFormat::Float, 2, Containers::arrayView(vertexData.data)}, Trade::MeshAttributeData{Trade::MeshAttribute::Normal, Containers::arrayView(vertexData.normals)} }}; CORRADE_COMPARE(data.vertexCount(), 103); @@ -283,12 +288,19 @@ template void CompressIndicesTest::compressMeshData() { Containers::arrayView({2, 1, 0, 1, 2}), TestSuite::Compare::Container); CORRADE_COMPARE(compressed.vertexCount(), 3); + + CORRADE_COMPARE(compressed.attributeName(0), Trade::meshAttributeCustom(42)); + CORRADE_COMPARE(compressed.attributeFormat(0), VertexFormat::Float); + CORRADE_COMPARE(compressed.attributeArraySize(0), 2); CORRADE_COMPARE(compressed.attributeOffset(0), 100*sizeof(Vector2)); - CORRADE_COMPARE(compressed.attributeOffset(1), 103*sizeof(Vector2) + 100*sizeof(Vector3)); - CORRADE_COMPARE_AS(compressed.attribute(Trade::MeshAttribute::Position), + CORRADE_COMPARE_AS((Containers::arrayCast<1, const Vector2>(compressed.attribute(0))), Containers::arrayView({{1.3f, 0.3f}, {0.87f, 1.1f}, {1.0f, -0.5f}}), TestSuite::Compare::Container); - CORRADE_COMPARE_AS(compressed.attribute(Trade::MeshAttribute::Normal), + + CORRADE_COMPARE(compressed.attributeName(1), Trade::MeshAttribute::Normal); + CORRADE_COMPARE(compressed.attributeFormat(1), VertexFormat::Vector3); + CORRADE_COMPARE(compressed.attributeOffset(1), 103*sizeof(Vector2) + 100*sizeof(Vector3)); + CORRADE_COMPARE_AS(compressed.attribute(1), Containers::arrayView({Vector3::xAxis(), Vector3::yAxis(), Vector3::zAxis()}), TestSuite::Compare::Container); } diff --git a/src/Magnum/MeshTools/Test/ConcatenateTest.cpp b/src/Magnum/MeshTools/Test/ConcatenateTest.cpp index 287877d3e..0c12794d2 100644 --- a/src/Magnum/MeshTools/Test/ConcatenateTest.cpp +++ b/src/Magnum/MeshTools/Test/ConcatenateTest.cpp @@ -49,6 +49,7 @@ struct ConcatenateTest: TestSuite::Tester { void concatenateUnsupportedPrimitive(); void concatenateInconsistentPrimitive(); void concatenateInconsistentAttributeType(); + void concatenateInconsistentAttributeArraySize(); void concatenateIntoNoMeshes(); }; @@ -66,6 +67,7 @@ ConcatenateTest::ConcatenateTest() { &ConcatenateTest::concatenateUnsupportedPrimitive, &ConcatenateTest::concatenateInconsistentPrimitive, &ConcatenateTest::concatenateInconsistentAttributeType, + &ConcatenateTest::concatenateInconsistentAttributeArraySize, &ConcatenateTest::concatenateIntoNoMeshes}); } @@ -76,6 +78,7 @@ struct VertexDataA { Vector2 texcoords2; Int:32; Vector3 position; + Short data[2]; }; void ConcatenateTest::concatenate() { @@ -84,8 +87,8 @@ void ConcatenateTest::concatenate() { /* First is non-indexed, this layout (including the gap) will be preserved */ const VertexDataA vertexDataA[]{ - {{0.1f, 0.2f}, {0.5f, 0.6f}, {1.0f, 2.0f, 3.0f}}, - {{0.3f, 0.4f}, {0.7f, 0.8f}, {4.0f, 5.0f, 6.0f}} + {{0.1f, 0.2f}, {0.5f, 0.6f}, {1.0f, 2.0f, 3.0f}, {15, 3}}, + {{0.3f, 0.4f}, {0.7f, 0.8f}, {4.0f, 5.0f, 6.0f}, {14, 2}} }; Trade::MeshData a{MeshPrimitive::Points, {}, vertexDataA, { Trade::MeshAttributeData{Trade::MeshAttribute::TextureCoordinates, @@ -97,6 +100,11 @@ void ConcatenateTest::concatenate() { Trade::MeshAttributeData{Trade::MeshAttribute::Position, Containers::stridedArrayView(vertexDataA, &vertexDataA[0].position, 2, sizeof(VertexDataA))}, + /* Array attribute to verify it's correctly propagated */ + Trade::MeshAttributeData{Trade::meshAttributeCustom(42), + VertexFormat::Short, 2, + Containers::stridedArrayView(vertexDataA, + &vertexDataA[0].data, 2, sizeof(VertexDataA))} }}; /* Second is indexed, has only one texture coordinate of the two, an extra @@ -104,12 +112,13 @@ void ConcatenateTest::concatenate() { zero-filled) */ const struct VertexDataB { Color4 color; + Short data[2]; Vector2 texcoords1; } vertexDataB[]{ - {0x112233_rgbf, {0.15f, 0.25f}}, - {0x445566_rgbf, {0.35f, 0.45f}}, - {0x778899_rgbf, {0.55f, 0.65f}}, - {0xaabbcc_rgbf, {0.75f, 0.85f}} + {0x112233_rgbf, {28, -15}, {0.15f, 0.25f}}, + {0x445566_rgbf, {29, -16}, {0.35f, 0.45f}}, + {0x778899_rgbf, {30, -17}, {0.55f, 0.65f}}, + {0xaabbcc_rgbf, {40, -18}, {0.75f, 0.85f}} }; const UnsignedShort indicesB[]{0, 2, 1, 0, 3, 2}; Trade::MeshData b{MeshPrimitive::Points, @@ -117,9 +126,14 @@ void ConcatenateTest::concatenate() { Trade::MeshAttributeData{Trade::MeshAttribute::Color, Containers::stridedArrayView(vertexDataB, &vertexDataB[0].color, 4, sizeof(VertexDataB))}, + /* Array attribute to verify it's correctly propagated */ + Trade::MeshAttributeData{Trade::meshAttributeCustom(42), + VertexFormat::Short, 2, + Containers::stridedArrayView(vertexDataB, + &vertexDataB[0].data, 4, sizeof(VertexDataB))}, Trade::MeshAttributeData{Trade::MeshAttribute::TextureCoordinates, Containers::stridedArrayView(vertexDataB, - &vertexDataB[0].texcoords1, 4, sizeof(VertexDataB))}, + &vertexDataB[0].texcoords1, 4, sizeof(VertexDataB))} }}; /* Third is again non-indexed, has one texcoord attribute more (which will @@ -153,7 +167,7 @@ void ConcatenateTest::concatenate() { Trade::MeshData dst = MeshTools::concatenate(a, {b, c}); CORRADE_COMPARE(dst.primitive(), MeshPrimitive::Points); - CORRADE_COMPARE(dst.attributeCount(), 3); + CORRADE_COMPARE(dst.attributeCount(), 4); CORRADE_COMPARE_AS(dst.attribute(Trade::MeshAttribute::Position), Containers::arrayView({ {1.0f, 2.0f, 3.0f}, @@ -184,6 +198,15 @@ void ConcatenateTest::concatenate() { {0.525f, 0.575f}, {0.625f, 0.675f} }), TestSuite::Compare::Container); + CORRADE_COMPARE(dst.attributeName(3), Trade::meshAttributeCustom(42)); + CORRADE_COMPARE(dst.attributeFormat(3), VertexFormat::Short); + CORRADE_COMPARE(dst.attributeArraySize(3), 2); + CORRADE_COMPARE_AS((Containers::arrayCast<1, const Vector2s>(dst.attribute(3))), + Containers::arrayView({ + {15, 3}, {14, 2}, + {28, -15}, {29, -16}, {30, -17}, {40, -18}, + {}, {}, {}, /* Missing in the third mesh */ + }), TestSuite::Compare::Container); CORRADE_VERIFY(dst.isIndexed()); CORRADE_COMPARE(dst.indexType(), MeshIndexType::UnsignedInt); CORRADE_COMPARE_AS(dst.indices(), @@ -593,6 +616,36 @@ void ConcatenateTest::concatenateInconsistentAttributeType() { "MeshTools::concatenateInto(): expected VertexFormat::Vector3ubNormalized for attribute 2 (Trade::MeshAttribute::Color) but got VertexFormat::Vector3usNormalized in mesh 3 attribute 1\n"); } +void ConcatenateTest::concatenateInconsistentAttributeArraySize() { + #ifdef CORRADE_NO_ASSERT + CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions"); + #endif + + /* Things are a bit duplicated to test correct numbering */ + Trade::MeshData a{MeshPrimitive::Lines, nullptr, { + Trade::MeshAttributeData{Trade::MeshAttribute::Position, + VertexFormat::Vector3, nullptr}, + Trade::MeshAttributeData{Trade::MeshAttribute::Position, + VertexFormat::Vector3, nullptr}, + Trade::MeshAttributeData{Trade::meshAttributeCustom(42), + VertexFormat::ByteNormalized, 5, nullptr} + }}; + Trade::MeshData b{MeshPrimitive::Lines, nullptr, { + Trade::MeshAttributeData{Trade::MeshAttribute::Position, + VertexFormat::Vector3, nullptr}, + Trade::MeshAttributeData{Trade::meshAttributeCustom(42), + VertexFormat::ByteNormalized, 4, nullptr} + }}; + + std::ostringstream out; + Error redirectError{&out}; + MeshTools::concatenate(a, {a, a, a, b}); + MeshTools::concatenateInto(a, {a, a, a, b}); + CORRADE_COMPARE(out.str(), + "MeshTools::concatenate(): expected array size 5 for attribute 2 (Trade::MeshAttribute::Custom(42)) but got 4 in mesh 3 attribute 1\n" + "MeshTools::concatenateInto(): expected array size 5 for attribute 2 (Trade::MeshAttribute::Custom(42)) but got 4 in mesh 3 attribute 1\n"); +} + void ConcatenateTest::concatenateIntoNoMeshes() { #ifdef CORRADE_NO_ASSERT CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions"); diff --git a/src/Magnum/MeshTools/Test/DuplicateTest.cpp b/src/Magnum/MeshTools/Test/DuplicateTest.cpp index 5a06bf0a5..1112f3d40 100644 --- a/src/Magnum/MeshTools/Test/DuplicateTest.cpp +++ b/src/Magnum/MeshTools/Test/DuplicateTest.cpp @@ -279,16 +279,19 @@ template void DuplicateTest::duplicateMeshData() { T indices[]{0, 1, 2, 2, 1, 0}; struct { Vector2 positions[3]; - Vector3 normals[3]; + Float extra[3][3]; } vertexData{ {{1.3f, 0.3f}, {0.87f, 1.1f}, {1.0f, -0.5f}}, - {Vector3::xAxis(), Vector3::yAxis(), Vector3::zAxis()} + {{1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}} }; Trade::MeshData data{MeshPrimitive::TriangleFan, {}, indices, Trade::MeshIndexData{indices}, {}, Containers::arrayView(&vertexData, 1), { - Trade::MeshAttributeData{Trade::MeshAttribute::Position, Containers::arrayView(vertexData.positions)}, - Trade::MeshAttributeData{Trade::MeshAttribute::Normal, Containers::arrayView(vertexData.normals)} + Trade::MeshAttributeData{Trade::MeshAttribute::Position, + Containers::arrayView(vertexData.positions)}, + /* Array attribute to verify it's correctly propagated */ + Trade::MeshAttributeData{Trade::meshAttributeCustom(42), + VertexFormat::Float, 3, Containers::arrayView(vertexData.extra)} }}; Trade::MeshData duplicated = MeshTools::duplicate(data); @@ -302,7 +305,10 @@ template void DuplicateTest::duplicateMeshData() { {1.3f, 0.3f}, {0.87f, 1.1f}, {1.0f, -0.5f}, {1.0f, -0.5f}, {0.87f, 1.1f}, {1.3f, 0.3f} }), TestSuite::Compare::Container); - CORRADE_COMPARE_AS(duplicated.attribute(Trade::MeshAttribute::Normal), + CORRADE_COMPARE(duplicated.attributeName(1), Trade::meshAttributeCustom(42)); + CORRADE_COMPARE(duplicated.attributeFormat(1), VertexFormat::Float); + CORRADE_COMPARE(duplicated.attributeArraySize(1), 3); + CORRADE_COMPARE_AS((Containers::arrayCast<1, const Vector3>(duplicated.attribute(1))), Containers::arrayView({ Vector3::xAxis(), Vector3::yAxis(), Vector3::zAxis(), Vector3::zAxis(), Vector3::yAxis(), Vector3::xAxis() @@ -326,13 +332,16 @@ void DuplicateTest::duplicateMeshDataExtra() { Trade::MeshData data{MeshPrimitive::Lines, {}, indices, Trade::MeshIndexData{indices}, {}, positions, { - Trade::MeshAttributeData{Trade::MeshAttribute::Position, Containers::arrayView(positions)} + Trade::MeshAttributeData{Trade::MeshAttribute::Position, + Containers::arrayView(positions)} }}; - const Vector3 normals[]{Vector3::xAxis(), Vector3::yAxis(), Vector3::zAxis()}; + const Float extra[][3]{{1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}}; Trade::MeshData duplicated = MeshTools::duplicate(data, { Trade::MeshAttributeData{4}, - Trade::MeshAttributeData{Trade::MeshAttribute::Normal, Containers::arrayView(normals)} + /* Array attribute to verify it's correctly propagated */ + Trade::MeshAttributeData{Trade::meshAttributeCustom(42), + VertexFormat::Float, 3, Containers::arrayView(extra)} }); CORRADE_VERIFY(MeshTools::isInterleaved(duplicated)); CORRADE_COMPARE(duplicated.primitive(), MeshPrimitive::Lines); @@ -344,7 +353,10 @@ void DuplicateTest::duplicateMeshDataExtra() { {1.3f, 0.3f}, {0.87f, 1.1f}, {1.0f, -0.5f}, {1.0f, -0.5f}, {0.87f, 1.1f}, {1.3f, 0.3f} }), TestSuite::Compare::Container); - CORRADE_COMPARE_AS(duplicated.attribute(Trade::MeshAttribute::Normal), + CORRADE_COMPARE(duplicated.attributeName(1), Trade::meshAttributeCustom(42)); + CORRADE_COMPARE(duplicated.attributeFormat(1), VertexFormat::Float); + CORRADE_COMPARE(duplicated.attributeArraySize(1), 3); + CORRADE_COMPARE_AS((Containers::arrayCast<1, const Vector3>(duplicated.attribute(1))), Containers::arrayView({ Vector3::xAxis(), Vector3::yAxis(), Vector3::zAxis(), Vector3::zAxis(), Vector3::yAxis(), Vector3::xAxis() diff --git a/src/Magnum/MeshTools/Test/GenerateIndicesTest.cpp b/src/Magnum/MeshTools/Test/GenerateIndicesTest.cpp index d7a4c6734..304887379 100644 --- a/src/Magnum/MeshTools/Test/GenerateIndicesTest.cpp +++ b/src/Magnum/MeshTools/Test/GenerateIndicesTest.cpp @@ -389,13 +389,14 @@ void GenerateIndicesTest::generateIndicesMeshData() { const struct Vertex { Vector2 position; + Short data[2]; Vector2 textureCoordinates; } vertexData[] { - {{1.5f, 0.3f}, {0.2f, 0.8f}}, - {{2.5f, 1.3f}, {0.3f, 0.7f}}, - {{3.5f, 2.3f}, {0.4f, 0.6f}}, - {{4.5f, 3.3f}, {0.5f, 0.5f}}, - {{5.5f, 4.3f}, {0.6f, 0.4f}} + {{1.5f, 0.3f}, {28, -15}, {0.2f, 0.8f}}, + {{2.5f, 1.3f}, {29, -16}, {0.3f, 0.7f}}, + {{3.5f, 2.3f}, {30, -17}, {0.4f, 0.6f}}, + {{4.5f, 3.3f}, {40, -18}, {0.5f, 0.5f}}, + {{5.5f, 4.3f}, {41, -19}, {0.6f, 0.4f}} }; Trade::MeshData mesh{data.primitive, @@ -403,6 +404,11 @@ void GenerateIndicesTest::generateIndicesMeshData() { Trade::MeshAttributeData{Trade::MeshAttribute::Position, Containers::stridedArrayView(vertexData, &vertexData[0].position, 5, sizeof(Vertex))}, + /* Array attribute to verify it's correctly propagated */ + Trade::MeshAttributeData{Trade::meshAttributeCustom(42), + VertexFormat::Short, 2, + Containers::stridedArrayView(vertexData, + &vertexData[0].data, 5, sizeof(Vertex))}, Trade::MeshAttributeData{Trade::MeshAttribute::TextureCoordinates, Containers::stridedArrayView(vertexData, &vertexData[0].textureCoordinates, 5, sizeof(Vertex))} @@ -414,11 +420,20 @@ void GenerateIndicesTest::generateIndicesMeshData() { CORRADE_COMPARE_AS(out.indices(), data.indices, TestSuite::Compare::Container); - CORRADE_COMPARE(out.attributeCount(), 2); + CORRADE_COMPARE(out.attributeCount(), 3); CORRADE_COMPARE_AS(out.attribute(Trade::MeshAttribute::Position), Containers::arrayView({ {1.5f, 0.3f}, {2.5f, 1.3f}, {3.5f, 2.3f}, {4.5f, 3.3f}, {5.5f, 4.3f} }), TestSuite::Compare::Container); + + CORRADE_COMPARE(out.attributeName(1), Trade::meshAttributeCustom(42)); + CORRADE_COMPARE(out.attributeFormat(1), VertexFormat::Short); + CORRADE_COMPARE(out.attributeArraySize(1), 2); + CORRADE_COMPARE_AS((Containers::arrayCast<1, const Vector2s>(out.attribute(1))), + Containers::arrayView({ + {28, -15}, {29, -16}, {30, -17}, {40, -18}, {41, -19} + }), TestSuite::Compare::Container); + CORRADE_COMPARE_AS(out.attribute(Trade::MeshAttribute::TextureCoordinates), Containers::arrayView({ {0.2f, 0.8f}, {0.3f, 0.7f}, {0.4f, 0.6f}, {0.5f, 0.5f}, {0.6f, 0.4f} diff --git a/src/Magnum/MeshTools/Test/InterleaveTest.cpp b/src/Magnum/MeshTools/Test/InterleaveTest.cpp index 7c058c8ba..45f6bc685 100644 --- a/src/Magnum/MeshTools/Test/InterleaveTest.cpp +++ b/src/Magnum/MeshTools/Test/InterleaveTest.cpp @@ -62,6 +62,7 @@ struct InterleaveTest: Corrade::TestSuite::Tester { void isInterleavedVertexDataWholeMemory(); void interleavedData(); + void interleavedDataArrayAttributes(); void interleavedDataNoAttributes(); void interleavedDataNoVertices(); void interleavedDataNotInterleaved(); @@ -113,6 +114,7 @@ InterleaveTest::InterleaveTest() { &InterleaveTest::isInterleavedVertexDataWholeMemory, &InterleaveTest::interleavedData, + &InterleaveTest::interleavedDataArrayAttributes, &InterleaveTest::interleavedDataNoAttributes, &InterleaveTest::interleavedDataNoVertices, &InterleaveTest::interleavedDataNotInterleaved, @@ -409,6 +411,39 @@ void InterleaveTest::interleavedData() { CORRADE_COMPARE(interleavedMutable.stride()[1], 1); } +void InterleaveTest::interleavedDataArrayAttributes() { + /* Same as above, except that the MeshData get those as custom Float array + attribs of size 3 and 2 instead of Vector3 and Vector2. Output should be + the same for both. */ + Containers::Array vertexData{100 + 3*40}; + Containers::StridedArrayView1D normals{vertexData, + reinterpret_cast(vertexData.data() + 100 + 24), 3, 40}; + Containers::StridedArrayView1D positions{vertexData, + reinterpret_cast(vertexData.data() + 100 + 5), 3, 40}; + + Trade::MeshData data{MeshPrimitive::Triangles, std::move(vertexData), { + Trade::MeshAttributeData{Trade::meshAttributeCustom(42), + VertexFormat::Float, 3, normals}, + Trade::MeshAttributeData{Trade::meshAttributeCustom(43), + VertexFormat::Float, 2, positions} + }}; + + CORRADE_VERIFY(MeshTools::isInterleaved(data)); + Containers::StridedArrayView2D interleaved = MeshTools::interleavedData(data); + CORRADE_COMPARE(interleaved.data(), positions.data()); + CORRADE_COMPARE(interleaved.size()[0], 3); + CORRADE_COMPARE(interleaved.size()[1], 31); + CORRADE_COMPARE(interleaved.stride()[0], 40); + CORRADE_COMPARE(interleaved.stride()[1], 1); + + Containers::StridedArrayView2D interleavedMutable = MeshTools::interleavedMutableData(data); + CORRADE_COMPARE(interleavedMutable.data(), positions.data()); + CORRADE_COMPARE(interleavedMutable.size()[0], 3); + CORRADE_COMPARE(interleavedMutable.size()[1], 31); + CORRADE_COMPARE(interleavedMutable.stride()[0], 40); + CORRADE_COMPARE(interleavedMutable.stride()[1], 1); +} + void InterleaveTest::interleavedDataNoAttributes() { char a[1]; Trade::MeshData data{MeshPrimitive::Lines, {}, a, {}, 15}; @@ -510,13 +545,16 @@ void InterleaveTest::interleavedMutableDataNotMutable() { void InterleaveTest::interleavedLayout() { Containers::Array indexData{6}; - Containers::Array vertexData{3*20}; + Containers::Array vertexData{3*24}; const Trade::MeshAttributeData attributeData[]{ Trade::MeshAttributeData{Trade::MeshAttribute::Position, Containers::arrayCast(vertexData.prefix(3*8))}, Trade::MeshAttributeData{Trade::MeshAttribute::Normal, - Containers::arrayCast(vertexData.suffix(3*8))} + Containers::arrayCast(vertexData.slice(3*8, 3*20))}, + /* Array attribute to verify it's correctly propagated */ + Trade::MeshAttributeData{Trade::meshAttributeCustom(42), + VertexFormat::Short, 2, Containers::StridedArrayView2D{vertexData.suffix(3*20), {3, 4}}} }; Trade::MeshIndexData indices{Containers::arrayCast(indexData)}; @@ -531,20 +569,24 @@ void InterleaveTest::interleavedLayout() { CORRADE_VERIFY(MeshTools::isInterleaved(layout)); CORRADE_COMPARE(layout.primitive(), MeshPrimitive::TriangleFan); CORRADE_VERIFY(!layout.isIndexed()); /* Indices are not preserved */ - CORRADE_COMPARE(layout.attributeCount(), 2); + CORRADE_COMPARE(layout.attributeCount(), 3); CORRADE_COMPARE(layout.attributeName(0), Trade::MeshAttribute::Position); CORRADE_COMPARE(layout.attributeName(1), Trade::MeshAttribute::Normal); + CORRADE_COMPARE(layout.attributeName(2), Trade::meshAttributeCustom(42)); CORRADE_COMPARE(layout.attributeFormat(0), VertexFormat::Vector2); CORRADE_COMPARE(layout.attributeFormat(1), VertexFormat::Vector3); - CORRADE_COMPARE(layout.attributeStride(0), 20); - CORRADE_COMPARE(layout.attributeStride(1), 20); + CORRADE_COMPARE(layout.attributeFormat(2), VertexFormat::Short); + CORRADE_COMPARE(layout.attributeStride(0), 24); + CORRADE_COMPARE(layout.attributeStride(1), 24); + CORRADE_COMPARE(layout.attributeStride(2), 24); CORRADE_COMPARE(layout.attributeOffset(0), 0); CORRADE_COMPARE(layout.attributeOffset(1), 8); + CORRADE_COMPARE(layout.attributeOffset(2), 20); CORRADE_COMPARE(layout.vertexCount(), 10); /* Needs to be like this so we can modify the data */ CORRADE_COMPARE(layout.vertexDataFlags(), Trade::DataFlag::Mutable|Trade::DataFlag::Owned); CORRADE_VERIFY(layout.vertexData()); - CORRADE_COMPARE(layout.vertexData().size(), 10*20); + CORRADE_COMPARE(layout.vertexData().size(), 10*24); } void InterleaveTest::interleavedLayoutExtra() { @@ -560,8 +602,9 @@ void InterleaveTest::interleavedLayoutExtra() { Trade::MeshData layout = MeshTools::interleavedLayout(data, 7, { Trade::MeshAttributeData{1}, + /* Array attribute to verify it's correctly propagated */ Trade::MeshAttributeData{Trade::meshAttributeCustom(15), - VertexFormat::UnsignedShort, nullptr}, + VertexFormat::UnsignedByte, 6, nullptr}, Trade::MeshAttributeData{1}, Trade::MeshAttributeData{Trade::MeshAttribute::Color, VertexFormat::Vector3, nullptr}, @@ -575,18 +618,22 @@ void InterleaveTest::interleavedLayoutExtra() { CORRADE_COMPARE(layout.attributeName(3), Trade::MeshAttribute::Color); CORRADE_COMPARE(layout.attributeFormat(0), VertexFormat::Vector2); CORRADE_COMPARE(layout.attributeFormat(1), VertexFormat::Vector3); - CORRADE_COMPARE(layout.attributeFormat(2), VertexFormat::UnsignedShort); + CORRADE_COMPARE(layout.attributeFormat(2), VertexFormat::UnsignedByte); CORRADE_COMPARE(layout.attributeFormat(3), VertexFormat::Vector3); - CORRADE_COMPARE(layout.attributeStride(0), 40); - CORRADE_COMPARE(layout.attributeStride(1), 40); - CORRADE_COMPARE(layout.attributeStride(2), 40); - CORRADE_COMPARE(layout.attributeStride(3), 40); + CORRADE_COMPARE(layout.attributeStride(0), 44); + CORRADE_COMPARE(layout.attributeStride(1), 44); + CORRADE_COMPARE(layout.attributeStride(2), 44); + CORRADE_COMPARE(layout.attributeStride(3), 44); CORRADE_COMPARE(layout.attributeOffset(0), 0); CORRADE_COMPARE(layout.attributeOffset(1), 8); CORRADE_COMPARE(layout.attributeOffset(2), 21); - CORRADE_COMPARE(layout.attributeOffset(3), 24); + CORRADE_COMPARE(layout.attributeOffset(3), 28); + CORRADE_COMPARE(layout.attributeArraySize(0), 0); + CORRADE_COMPARE(layout.attributeArraySize(1), 0); + CORRADE_COMPARE(layout.attributeArraySize(2), 6); + CORRADE_COMPARE(layout.attributeArraySize(3), 0); CORRADE_COMPARE(layout.vertexCount(), 7); - CORRADE_COMPARE(layout.vertexData().size(), 7*40); + CORRADE_COMPARE(layout.vertexData().size(), 7*44); } void InterleaveTest::interleavedLayoutExtraAliased() {