Browse Source

MeshTools: merge isInterleaved() and interleavedData() tests together.

Because it tested the exact same thing for the most part.
pull/547/head
Vladimír Vondruš 4 years ago
parent
commit
fce0756fc7
  1. 484
      src/Magnum/MeshTools/Test/InterleaveTest.cpp

484
src/Magnum/MeshTools/Test/InterleaveTest.cpp

@ -53,21 +53,17 @@ struct InterleaveTest: Corrade::TestSuite::Tester {
void interleaveInto(); void interleaveInto();
void isInterleaved();
void isInterleavedEmpty();
void isInterleavedSingleAttribute();
void isInterleavedGaps();
void isInterleavedAliased();
void isInterleavedUnordered();
void isInterleavedAttributeAcrossStride();
void isInterleavedVertexDataWholeMemory();
void isInterleavedImplementationSpecificVertexFormat();
void interleavedData(); void interleavedData();
void interleavedDataUnordered();
void interleavedDataGaps();
void interleavedDataAliased();
void interleavedDataSingleAttribute();
void interleavedDataArrayAttributes(); void interleavedDataArrayAttributes();
void interleavedDataEmpty();
void interleavedDataNoAttributes(); void interleavedDataNoAttributes();
void interleavedDataNoVertices(); void interleavedDataNoVertices();
void interleavedDataNotInterleaved(); void interleavedDataNotInterleaved();
void interleavedDataAttributeAcrossStride();
void interleavedDataVertexDataWholeMemory(); void interleavedDataVertexDataWholeMemory();
void interleavedMutableDataNotMutable(); void interleavedMutableDataNotMutable();
void interleavedDataImplementationSpecificVertexFormat(); void interleavedDataImplementationSpecificVertexFormat();
@ -122,21 +118,17 @@ InterleaveTest::InterleaveTest() {
&InterleaveTest::interleaveInto, &InterleaveTest::interleaveInto,
&InterleaveTest::isInterleaved,
&InterleaveTest::isInterleavedEmpty,
&InterleaveTest::isInterleavedSingleAttribute,
&InterleaveTest::isInterleavedGaps,
&InterleaveTest::isInterleavedAliased,
&InterleaveTest::isInterleavedUnordered,
&InterleaveTest::isInterleavedAttributeAcrossStride,
&InterleaveTest::isInterleavedVertexDataWholeMemory,
&InterleaveTest::isInterleavedImplementationSpecificVertexFormat,
&InterleaveTest::interleavedData, &InterleaveTest::interleavedData,
&InterleaveTest::interleavedDataUnordered,
&InterleaveTest::interleavedDataGaps,
&InterleaveTest::interleavedDataAliased,
&InterleaveTest::interleavedDataSingleAttribute,
&InterleaveTest::interleavedDataArrayAttributes, &InterleaveTest::interleavedDataArrayAttributes,
&InterleaveTest::interleavedDataEmpty,
&InterleaveTest::interleavedDataNoAttributes, &InterleaveTest::interleavedDataNoAttributes,
&InterleaveTest::interleavedDataNoVertices, &InterleaveTest::interleavedDataNoVertices,
&InterleaveTest::interleavedDataNotInterleaved, &InterleaveTest::interleavedDataNotInterleaved,
&InterleaveTest::interleavedDataAttributeAcrossStride,
&InterleaveTest::interleavedDataVertexDataWholeMemory, &InterleaveTest::interleavedDataVertexDataWholeMemory,
&InterleaveTest::interleavedMutableDataNotMutable, &InterleaveTest::interleavedMutableDataNotMutable,
&InterleaveTest::interleavedDataImplementationSpecificVertexFormat, &InterleaveTest::interleavedDataImplementationSpecificVertexFormat,
@ -286,216 +278,122 @@ void InterleaveTest::interleaveInto() {
} }
} }
void InterleaveTest::isInterleaved() { void InterleaveTest::interleavedData() {
/* Interleaved; testing also initial offset */ Containers::Array<char> vertexData{100 + 3*20};
{ Containers::StridedArrayView1D<Vector2> positions{vertexData,
Containers::Array<char> vertexData{100 + 3*20}; reinterpret_cast<Vector2*>(vertexData.data() + 100), 3, 20};
Trade::MeshAttributeData positions{Trade::MeshAttribute::Position, Containers::StridedArrayView1D<Vector3> normals{vertexData,
Containers::StridedArrayView1D<Vector2>{vertexData, reinterpret_cast<Vector3*>(vertexData.data() + 100 + 8), 3, 20};
reinterpret_cast<Vector2*>(vertexData.data() + 100), 3, 20}};
Trade::MeshAttributeData normals{Trade::MeshAttribute::Normal,
Containers::StridedArrayView1D<Vector3>{vertexData,
reinterpret_cast<Vector3*>(vertexData.data() + 100 + 8), 3, 20}};
Trade::MeshData data{MeshPrimitive::Triangles, std::move(vertexData), {positions, normals}};
CORRADE_VERIFY(MeshTools::isInterleaved(data));
}
/* One after another */
{
Containers::Array<char> vertexData{100 + 3*20};
Trade::MeshAttributeData positions{Trade::MeshAttribute::Position,
Containers::arrayCast<Vector2>(vertexData.suffix(100).prefix(3*8))};
Trade::MeshAttributeData normals{Trade::MeshAttribute::Normal,
Containers::arrayCast<Vector3>(vertexData.suffix(100).suffix(3*8))};
Trade::MeshData data{MeshPrimitive::Triangles, std::move(vertexData), {positions, normals}};
CORRADE_VERIFY(!MeshTools::isInterleaved(data));
}
}
void InterleaveTest::isInterleavedEmpty() {
Trade::MeshData data{MeshPrimitive::Triangles, 5};
CORRADE_VERIFY(MeshTools::isInterleaved(data));
}
void InterleaveTest::isInterleavedSingleAttribute() {
Containers::Array<char> vertexData{3*8};
Trade::MeshAttributeData positions{Trade::MeshAttribute::Position,
Containers::arrayCast<Vector2>(vertexData.prefix(3*8))};
Trade::MeshData data{MeshPrimitive::Triangles, std::move(vertexData), {positions}}; Trade::MeshData data{MeshPrimitive::Triangles, std::move(vertexData), {
Trade::MeshAttributeData{Trade::MeshAttribute::Position, positions},
Trade::MeshAttributeData{Trade::MeshAttribute::Normal, normals}
}};
CORRADE_VERIFY(MeshTools::isInterleaved(data)); CORRADE_VERIFY(MeshTools::isInterleaved(data));
}
void InterleaveTest::isInterleavedGaps() { Containers::StridedArrayView2D<const char> interleaved = MeshTools::interleavedData(data);
Containers::Array<char> vertexData{3*40}; CORRADE_COMPARE(interleaved.data(), positions.data());
Trade::MeshAttributeData positions{Trade::MeshAttribute::Position, CORRADE_COMPARE(interleaved.size()[0], 3);
Containers::StridedArrayView1D<Vector2>{vertexData, CORRADE_COMPARE(interleaved.size()[1], 20);
reinterpret_cast<Vector2*>(vertexData.data() + 5), 3, 40}}; CORRADE_COMPARE(interleaved.stride()[0], 20);
Trade::MeshAttributeData normals{Trade::MeshAttribute::Normal, CORRADE_COMPARE(interleaved.stride()[1], 1);
Containers::StridedArrayView1D<Vector3>{vertexData,
reinterpret_cast<Vector3*>(vertexData.data() + 24), 3, 40}};
Trade::MeshData data{MeshPrimitive::Triangles, std::move(vertexData), {positions, normals}}; /* It just takes the output of interleavedData() and casts, nothing else
CORRADE_VERIFY(MeshTools::isInterleaved(data)); to test there */
Containers::StridedArrayView2D<char> interleavedMutable = MeshTools::interleavedMutableData(data);
CORRADE_COMPARE(interleavedMutable.data(), positions.data());
CORRADE_COMPARE(interleavedMutable.size()[0], 3);
CORRADE_COMPARE(interleavedMutable.size()[1], 20);
CORRADE_COMPARE(interleavedMutable.stride()[0], 20);
CORRADE_COMPARE(interleavedMutable.stride()[1], 1);
} }
void InterleaveTest::isInterleavedAliased() { void InterleaveTest::interleavedDataUnordered() {
/* Normals share first two components with positions */ /* Compared to interleavedData() the attribute order in MeshData is
Containers::Array<char> vertexData{3*12}; flipped, but the result should be the same */
Trade::MeshAttributeData positions{Trade::MeshAttribute::Position, Containers::Array<char> vertexData{100 + 3*20};
Containers::StridedArrayView1D<Vector2>{vertexData, Containers::StridedArrayView1D<Vector2> positions{vertexData,
reinterpret_cast<Vector2*>(vertexData.data()), 3, 12}}; reinterpret_cast<Vector2*>(vertexData.data() + 100), 3, 20};
Trade::MeshAttributeData normals{Trade::MeshAttribute::Normal, Containers::StridedArrayView1D<Vector3> normals{vertexData,
Containers::StridedArrayView1D<Vector3>{vertexData, reinterpret_cast<Vector3*>(vertexData.data() + 100 + 8), 3, 20};
reinterpret_cast<Vector3*>(vertexData.data()), 3, 12}};
Trade::MeshData data{MeshPrimitive::Triangles, std::move(vertexData), {positions, normals}}; Trade::MeshData data{MeshPrimitive::Triangles, std::move(vertexData), {
Trade::MeshAttributeData{Trade::MeshAttribute::Normal, normals},
Trade::MeshAttributeData{Trade::MeshAttribute::Position, positions}
}};
CORRADE_VERIFY(MeshTools::isInterleaved(data)); CORRADE_VERIFY(MeshTools::isInterleaved(data));
}
void InterleaveTest::isInterleavedUnordered() {
Containers::Array<char> vertexData{3*12};
Trade::MeshAttributeData positions{Trade::MeshAttribute::Position,
Containers::StridedArrayView1D<Vector2>{vertexData,
reinterpret_cast<Vector2*>(vertexData.data()), 3, 12}};
Trade::MeshAttributeData normals{Trade::MeshAttribute::Normal,
Containers::StridedArrayView1D<Vector3>{vertexData,
reinterpret_cast<Vector3*>(vertexData.data()), 3, 12}};
/* Normals specified first even though they're ordered after positions */ Containers::StridedArrayView2D<const char> interleaved = MeshTools::interleavedData(data);
Trade::MeshData data{MeshPrimitive::Triangles, std::move(vertexData), {normals, positions}}; CORRADE_COMPARE(interleaved.data(), positions.data());
CORRADE_VERIFY(MeshTools::isInterleaved(data)); CORRADE_COMPARE(interleaved.size()[0], 3);
CORRADE_COMPARE(interleaved.size()[1], 20);
CORRADE_COMPARE(interleaved.stride()[0], 20);
CORRADE_COMPARE(interleaved.stride()[1], 1);
} }
void InterleaveTest::isInterleavedAttributeAcrossStride() { void InterleaveTest::interleavedDataGaps() {
/* Data slightly larger */ /* Compared to interleavedData() there's a few padding bytes in between and
Containers::Array<char> vertexData{5 + 3*30 + 3}; at the end, the size should tightly wrap the data though */
Trade::MeshAttributeData positions{Trade::MeshAttribute::Position, Containers::Array<char> vertexData{100 + 3*40};
Containers::StridedArrayView1D<Vector2>{vertexData, Containers::StridedArrayView1D<Vector2> positions{vertexData,
reinterpret_cast<Vector2*>(vertexData.data() + 5), 3, 30}}; reinterpret_cast<Vector2*>(vertexData.data() + 100 + 5), 3, 40};
Trade::MeshAttributeData normals{Trade::MeshAttribute::Normal, Containers::StridedArrayView1D<Vector3> normals{vertexData,
Containers::StridedArrayView1D<Vector3>{vertexData, reinterpret_cast<Vector3*>(vertexData.data() + 100 + 24), 3, 40};
/* 23 + 12 is 35, which still fits into the stride after
subtracting the initial offset; 24 not */
reinterpret_cast<Vector3*>(vertexData.data() + 23), 3, 30}};
Trade::MeshData data{MeshPrimitive::Triangles, std::move(vertexData), Trade::MeshData data{MeshPrimitive::Triangles, std::move(vertexData), {
{positions, normals}}; Trade::MeshAttributeData{Trade::MeshAttribute::Position, positions},
Trade::MeshAttributeData{Trade::MeshAttribute::Normal, normals}
}};
CORRADE_VERIFY(MeshTools::isInterleaved(data)); CORRADE_VERIFY(MeshTools::isInterleaved(data));
vertexData = data.releaseVertexData(); Containers::StridedArrayView2D<const char> interleaved = MeshTools::interleavedData(data);
Trade::MeshAttributeData normals2{Trade::MeshAttribute::Normal, CORRADE_COMPARE(interleaved.data(), positions.data());
Containers::StridedArrayView1D<Vector3>{vertexData, CORRADE_COMPARE(interleaved.size()[0], 3);
reinterpret_cast<Vector3*>(vertexData.data() + 24), 3, 30}}; CORRADE_COMPARE(interleaved.size()[1], 31);
Trade::MeshData data2{MeshPrimitive::Triangles, CORRADE_COMPARE(interleaved.stride()[0], 40);
std::move(vertexData), {positions, normals2}}; CORRADE_COMPARE(interleaved.stride()[1], 1);
CORRADE_VERIFY(!MeshTools::isInterleaved(data2));
} }
void InterleaveTest::isInterleavedVertexDataWholeMemory() { void InterleaveTest::interleavedDataAliased() {
struct Vertex { /* Compared to interleavedData() the normals share first two components
Vector2 position; with positions */
Vector3 normal; Containers::Array<char> vertexData{100 + 3*12};
} vertexData[3]; Containers::StridedArrayView1D<Vector2> positions{vertexData,
Trade::MeshAttributeData positions{Trade::MeshAttribute::Position, reinterpret_cast<Vector2*>(vertexData.data() + 100), 3, 12};
Containers::StridedArrayView1D<Vector2>{vertexData, Containers::StridedArrayView1D<Vector3> normals{vertexData,
&vertexData[0].position, 3, sizeof(Vertex)}}; reinterpret_cast<Vector3*>(vertexData.data() + 100), 3, 12};
Trade::MeshAttributeData normals{Trade::MeshAttribute::Normal,
Containers::StridedArrayView1D<Vector3>{vertexData,
&vertexData[0].normal, 3, sizeof(Vertex)}};
/* This is used internally by combineFaceAttributes(), as long as the Trade::MeshData data{MeshPrimitive::Triangles, std::move(vertexData), {
vertex data array isn't accessed directly it's okay */ Trade::MeshAttributeData{Trade::MeshAttribute::Position, positions},
Trade::MeshData data{MeshPrimitive::Triangles, Trade::MeshAttributeData{Trade::MeshAttribute::Normal, normals}
{}, {nullptr, ~std::size_t{}}, {positions, normals}}; }};
CORRADE_VERIFY(MeshTools::isInterleaved(data)); CORRADE_VERIFY(MeshTools::isInterleaved(data));
}
void InterleaveTest::isInterleavedImplementationSpecificVertexFormat() {
/* Interleaved; fits into one byte at the end of stride */
{
Containers::Array<char> vertexData{100 + 3*9};
Trade::MeshAttributeData positions{Trade::MeshAttribute::Position,
Containers::StridedArrayView1D<Vector2>{vertexData,
reinterpret_cast<Vector2*>(vertexData.data() + 100), 3, 9}};
Trade::MeshAttributeData normals{Trade::MeshAttribute::Normal,
vertexFormatWrap(0x1234),
Containers::StridedArrayView1D<char>{vertexData,
vertexData.data() + 100 + 8, 3, 9}};
/* The result should be independent on the order of calculations */
Trade::MeshData data{MeshPrimitive::Triangles, {}, vertexData,
{positions, normals}};
Trade::MeshData dataDifferentOrder{MeshPrimitive::Triangles, {}, vertexData,
{normals, positions}};
CORRADE_VERIFY(MeshTools::isInterleaved(data));
CORRADE_VERIFY(MeshTools::isInterleaved(dataDifferentOrder));
}
/* Doesn't have even one byte of space in the stride, invalid */
{
Containers::Array<char> vertexData{100 + 3*8};
Trade::MeshAttributeData positions{Trade::MeshAttribute::Position,
Containers::StridedArrayView1D<Vector2>{vertexData,
reinterpret_cast<Vector2*>(vertexData.data() + 100), 3, 8}};
Trade::MeshAttributeData normals{Trade::MeshAttribute::Normal,
vertexFormatWrap(0x1234),
Containers::StridedArrayView1D<char>{vertexData,
vertexData.data() + 100 + 8, 3, 8}};
Trade::MeshData data{MeshPrimitive::Triangles, std::move(vertexData), {positions, normals}}; Containers::StridedArrayView2D<const char> interleaved = MeshTools::interleavedData(data);
CORRADE_VERIFY(!MeshTools::isInterleaved(data)); CORRADE_COMPARE(interleaved.data(), positions.data());
} CORRADE_COMPARE(interleaved.size()[0], 3);
CORRADE_COMPARE(interleaved.size()[1], 12);
/* A non-interleaved (or not?) attribute with a implementation-specific CORRADE_COMPARE(interleaved.stride()[0], 12);
format after interleaved ones is also invalid */ CORRADE_COMPARE(interleaved.stride()[1], 1);
{
Containers::Array<char> vertexData{100 + 3*20 + 3};
Trade::MeshAttributeData positions{Trade::MeshAttribute::Position,
Containers::StridedArrayView1D<Vector2>{vertexData,
reinterpret_cast<Vector2*>(vertexData.data() + 100), 3, 20}};
Trade::MeshAttributeData normals{Trade::MeshAttribute::Normal,
Containers::StridedArrayView1D<Vector3>{vertexData,
reinterpret_cast<Vector3*>(vertexData.data() + 100 + 8), 3, 20}};
Trade::MeshAttributeData extra{Trade::meshAttributeCustom(1234),
vertexFormatWrap(0x1234),
Containers::StridedArrayView1D<char>{vertexData,
vertexData.data() + 100 + 3*20, 3, 1}};
Trade::MeshData data{MeshPrimitive::Triangles, {}, vertexData,
{positions, normals, extra}};
CORRADE_VERIFY(!MeshTools::isInterleaved(data));
}
} }
void InterleaveTest::interleavedData() { void InterleaveTest::interleavedDataSingleAttribute() {
Containers::Array<char> vertexData{100 + 3*40}; /* Just to ensure it passes also when there's just one tightly-packed
Containers::StridedArrayView1D<Vector3> normals{vertexData, attribute, which is the same as if it would be interleaved */
reinterpret_cast<Vector3*>(vertexData.data() + 100 + 24), 3, 40}; Containers::Array<char> vertexData{3*8};
Containers::StridedArrayView1D<Vector2> positions{vertexData, auto positions = Containers::arrayCast<Vector2>(vertexData);
reinterpret_cast<Vector2*>(vertexData.data() + 100 + 5), 3, 40};
Trade::MeshData data{MeshPrimitive::Triangles, std::move(vertexData), { Trade::MeshData data{MeshPrimitive::Triangles, std::move(vertexData), {
Trade::MeshAttributeData{Trade::MeshAttribute::Normal, normals},
Trade::MeshAttributeData{Trade::MeshAttribute::Position, positions} Trade::MeshAttributeData{Trade::MeshAttribute::Position, positions}
}}; }};
CORRADE_VERIFY(MeshTools::isInterleaved(data)); CORRADE_VERIFY(MeshTools::isInterleaved(data));
Containers::StridedArrayView2D<const char> interleaved = MeshTools::interleavedData(data); Containers::StridedArrayView2D<const char> interleaved = MeshTools::interleavedData(data);
CORRADE_COMPARE(interleaved.data(), positions.data()); CORRADE_COMPARE(interleaved.data(), positions.data());
CORRADE_COMPARE(interleaved.size()[0], 3); CORRADE_COMPARE(interleaved.size()[0], 3);
CORRADE_COMPARE(interleaved.size()[1], 31); CORRADE_COMPARE(interleaved.size()[1], sizeof(Vector2));
CORRADE_COMPARE(interleaved.stride()[0], 40); CORRADE_COMPARE(interleaved.stride()[0], sizeof(Vector2));
CORRADE_COMPARE(interleaved.stride()[1], 1); CORRADE_COMPARE(interleaved.stride()[1], 1);
Containers::StridedArrayView2D<char> 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::interleavedDataArrayAttributes() { void InterleaveTest::interleavedDataArrayAttributes() {
@ -514,27 +412,33 @@ void InterleaveTest::interleavedDataArrayAttributes() {
Trade::MeshAttributeData{Trade::meshAttributeCustom(43), Trade::MeshAttributeData{Trade::meshAttributeCustom(43),
VertexFormat::Float, positions, 2} VertexFormat::Float, positions, 2}
}}; }};
CORRADE_VERIFY(MeshTools::isInterleaved(data)); CORRADE_VERIFY(MeshTools::isInterleaved(data));
Containers::StridedArrayView2D<const char> interleaved = MeshTools::interleavedData(data); Containers::StridedArrayView2D<const char> interleaved = MeshTools::interleavedData(data);
CORRADE_COMPARE(interleaved.data(), positions.data()); CORRADE_COMPARE(interleaved.data(), positions.data());
CORRADE_COMPARE(interleaved.size()[0], 3); CORRADE_COMPARE(interleaved.size()[0], 3);
CORRADE_COMPARE(interleaved.size()[1], 31); CORRADE_COMPARE(interleaved.size()[1], 31);
CORRADE_COMPARE(interleaved.stride()[0], 40); CORRADE_COMPARE(interleaved.stride()[0], 40);
CORRADE_COMPARE(interleaved.stride()[1], 1); CORRADE_COMPARE(interleaved.stride()[1], 1);
}
Containers::StridedArrayView2D<char> interleavedMutable = MeshTools::interleavedMutableData(data); void InterleaveTest::interleavedDataEmpty() {
CORRADE_COMPARE(interleavedMutable.data(), positions.data()); Trade::MeshData data{MeshPrimitive::Triangles, 5};
CORRADE_COMPARE(interleavedMutable.size()[0], 3); CORRADE_VERIFY(MeshTools::isInterleaved(data));
CORRADE_COMPARE(interleavedMutable.size()[1], 31);
CORRADE_COMPARE(interleavedMutable.stride()[0], 40); Containers::StridedArrayView2D<const char> interleaved = MeshTools::interleavedData(data);
CORRADE_COMPARE(interleavedMutable.stride()[1], 1); CORRADE_COMPARE(interleaved.data(), nullptr);
CORRADE_COMPARE(interleaved.size()[0], 5);
CORRADE_COMPARE(interleaved.size()[1], 0);
CORRADE_COMPARE(interleaved.stride()[0], 0);
CORRADE_COMPARE(interleaved.stride()[1], 1);
} }
void InterleaveTest::interleavedDataNoAttributes() { void InterleaveTest::interleavedDataNoAttributes() {
char a[1]; char a[1];
Trade::MeshData data{MeshPrimitive::Lines, {}, a, {}, 15}; Trade::MeshData data{MeshPrimitive::Lines, {}, a, {}, 15};
CORRADE_VERIFY(MeshTools::isInterleaved(data)); CORRADE_VERIFY(MeshTools::isInterleaved(data));
Containers::StridedArrayView2D<const char> interleaved = MeshTools::interleavedData(data); Containers::StridedArrayView2D<const char> interleaved = MeshTools::interleavedData(data);
CORRADE_COMPARE(interleaved.data(), static_cast<void*>(a)); CORRADE_COMPARE(interleaved.data(), static_cast<void*>(a));
CORRADE_COMPARE(interleaved.size()[0], 15); CORRADE_COMPARE(interleaved.size()[0], 15);
@ -555,8 +459,8 @@ void InterleaveTest::interleavedDataNoVertices() {
Trade::MeshAttributeData{Trade::MeshAttribute::Position, Trade::MeshAttributeData{Trade::MeshAttribute::Position,
Containers::stridedArrayView(a, &a[0].position, 0, sizeof(Vertex))} Containers::stridedArrayView(a, &a[0].position, 0, sizeof(Vertex))}
}}; }};
CORRADE_VERIFY(MeshTools::isInterleaved(data)); CORRADE_VERIFY(MeshTools::isInterleaved(data));
Containers::StridedArrayView2D<const char> interleaved = MeshTools::interleavedData(data); Containers::StridedArrayView2D<const char> interleaved = MeshTools::interleavedData(data);
CORRADE_COMPARE(interleaved.data(), static_cast<void*>(a)); CORRADE_COMPARE(interleaved.data(), static_cast<void*>(a));
CORRADE_COMPARE(interleaved.size()[0], 0); CORRADE_COMPARE(interleaved.size()[0], 0);
@ -571,12 +475,14 @@ void InterleaveTest::interleavedDataNotInterleaved() {
#endif #endif
Containers::Array<char> vertexData{100 + 3*20}; Containers::Array<char> vertexData{100 + 3*20};
Trade::MeshAttributeData positions{Trade::MeshAttribute::Position, auto positions = Containers::arrayCast<Vector2>(vertexData.suffix(100).prefix(3*8));
Containers::arrayCast<Vector2>(vertexData.suffix(100).prefix(3*8))}; auto normals = Containers::arrayCast<Vector3>(vertexData.suffix(100).suffix(3*8));
Trade::MeshAttributeData normals{Trade::MeshAttribute::Normal,
Containers::arrayCast<Vector3>(vertexData.suffix(100).suffix(3*8))};
Trade::MeshData data{MeshPrimitive::Triangles, std::move(vertexData), {positions, normals}}; Trade::MeshData data{MeshPrimitive::Triangles, std::move(vertexData), {
Trade::MeshAttributeData{Trade::MeshAttribute::Normal, normals},
Trade::MeshAttributeData{Trade::MeshAttribute::Position, positions}
}};
CORRADE_VERIFY(!MeshTools::isInterleaved(data));
std::ostringstream out; std::ostringstream out;
Error redirectError{&out}; Error redirectError{&out};
@ -584,6 +490,45 @@ void InterleaveTest::interleavedDataNotInterleaved() {
CORRADE_COMPARE(out.str(), "MeshTools::interleavedData(): the mesh is not interleaved\n"); CORRADE_COMPARE(out.str(), "MeshTools::interleavedData(): the mesh is not interleaved\n");
} }
void InterleaveTest::interleavedDataAttributeAcrossStride() {
/* Data slightly larger */
char vertexData[5 + 3*30 + 3]{};
Containers::StridedArrayView1D<Vector2> positions{vertexData,
reinterpret_cast<Vector2*>(vertexData + 5), 3, 30};
/* 23 + 12 is 35, which still fits into the stride after subtracting the
initial offset */
{
Containers::StridedArrayView1D<Vector3> normals{vertexData,
reinterpret_cast<Vector3*>(vertexData + 23), 3, 30};
Trade::MeshData data{MeshPrimitive::Triangles, {}, vertexData, {
Trade::MeshAttributeData{Trade::MeshAttribute::Position, positions},
Trade::MeshAttributeData{Trade::MeshAttribute::Normal, normals}
}};
CORRADE_VERIFY(MeshTools::isInterleaved(data));
Containers::StridedArrayView2D<const char> interleaved = MeshTools::interleavedData(data);
CORRADE_COMPARE(interleaved.data(), positions.data());
CORRADE_COMPARE(interleaved.size()[0], 3);
CORRADE_COMPARE(interleaved.size()[1], 30);
CORRADE_COMPARE(interleaved.stride()[0], 30);
CORRADE_COMPARE(interleaved.stride()[1], 1);
/* 24 not */
} {
Containers::StridedArrayView1D<Vector3> normals{vertexData,
reinterpret_cast<Vector3*>(vertexData + 24), 3, 30};
Trade::MeshData data{MeshPrimitive::Triangles, {}, vertexData, {
Trade::MeshAttributeData{Trade::MeshAttribute::Position, positions},
Trade::MeshAttributeData{Trade::MeshAttribute::Normal, normals}
}};
CORRADE_VERIFY(!MeshTools::isInterleaved(data));
/* Not testing interleavedData() for an assertion, done above already
and since both use the same helper checking just the isInterleaved()
is enough */
}
}
void InterleaveTest::interleavedDataVertexDataWholeMemory() { void InterleaveTest::interleavedDataVertexDataWholeMemory() {
struct Vertex { struct Vertex {
int:32; int:32;
@ -631,39 +576,100 @@ void InterleaveTest::interleavedMutableDataNotMutable() {
} }
void InterleaveTest::interleavedDataImplementationSpecificVertexFormat() { void InterleaveTest::interleavedDataImplementationSpecificVertexFormat() {
Containers::Array<char> vertexData{100 + 3*50}; /* The implementation-specific format is conservatively assumed to occupy
Trade::MeshAttributeData positions{Trade::MeshAttribute::Position, the whole stride (even if it may be excessive) */
Containers::StridedArrayView1D<Vector2>{vertexData, {
reinterpret_cast<Vector2*>(vertexData.data() + 100), 3, 50}}; Containers::Array<char> vertexData{100 + 3*50};
Trade::MeshAttributeData normals{Trade::MeshAttribute::Normal, Trade::MeshAttributeData positions{Trade::MeshAttribute::Position,
vertexFormatWrap(0x1234), Containers::StridedArrayView1D<Vector2>{vertexData,
Containers::StridedArrayView1D<char>{vertexData, reinterpret_cast<Vector2*>(vertexData.data() + 100), 3, 50}};
vertexData.data() + 100 + 8, 3, 50}}; Trade::MeshAttributeData normals{Trade::MeshAttribute::Normal,
vertexFormatWrap(0x1234),
Containers::StridedArrayView1D<char>{vertexData,
vertexData.data() + 100 + 8, 3, 50}};
{
Trade::MeshData data{MeshPrimitive::Triangles, {}, vertexData,
{positions, normals}};
CORRADE_VERIFY(MeshTools::isInterleaved(data));
Containers::StridedArrayView2D<const char> interleaved = MeshTools::interleavedData(data);
CORRADE_COMPARE(interleaved.data(), positions.data().data());
CORRADE_COMPARE(interleaved.size()[0], 3);
CORRADE_COMPARE(interleaved.size()[1], 50);
CORRADE_COMPARE(interleaved.stride()[0], 50);
CORRADE_COMPARE(interleaved.stride()[1], 1);
/* The result should be the same independent on the order of
attributes */
} {
Trade::MeshData data{MeshPrimitive::Triangles, {}, vertexData,
{normals, positions}};
CORRADE_VERIFY(MeshTools::isInterleaved(data));
Containers::StridedArrayView2D<const char> interleaved = MeshTools::interleavedData(data);
CORRADE_COMPARE(interleaved.data(), positions.data().data());
CORRADE_COMPARE(interleaved.size()[0], 3);
CORRADE_COMPARE(interleaved.size()[1], 50);
CORRADE_COMPARE(interleaved.stride()[0], 50);
CORRADE_COMPARE(interleaved.stride()[1], 1);
}
}
/* Fits just into one byte at the end of stride */
{ {
Containers::Array<char> vertexData{100 + 3*9};
Trade::MeshAttributeData positions{Trade::MeshAttribute::Position,
Containers::StridedArrayView1D<Vector2>{vertexData,
reinterpret_cast<Vector2*>(vertexData.data() + 100), 3, 9}};
Trade::MeshAttributeData normals{Trade::MeshAttribute::Normal,
vertexFormatWrap(0x1234),
Containers::StridedArrayView1D<char>{vertexData,
vertexData.data() + 100 + 8, 3, 9}};
/* The result should be independent on the order of calculations */
Trade::MeshData data{MeshPrimitive::Triangles, {}, vertexData, Trade::MeshData data{MeshPrimitive::Triangles, {}, vertexData,
{positions, normals}}; {positions, normals}};
Trade::MeshData dataDifferentOrder{MeshPrimitive::Triangles, {}, vertexData,
{normals, positions}};
CORRADE_VERIFY(MeshTools::isInterleaved(data)); CORRADE_VERIFY(MeshTools::isInterleaved(data));
Containers::StridedArrayView2D<const char> interleaved = MeshTools::interleavedData(data); CORRADE_VERIFY(MeshTools::isInterleaved(dataDifferentOrder));
CORRADE_COMPARE(interleaved.data(), positions.data().data()); }
CORRADE_COMPARE(interleaved.size()[0], 3);
/* The implementation-specific format is conservatively assumed to /* Doesn't have even one byte of space in the stride, invalid */
occupy the whole stride (even if may be is excessive) */ {
CORRADE_COMPARE(interleaved.size()[1], 50); Containers::Array<char> vertexData{100 + 3*8};
CORRADE_COMPARE(interleaved.stride()[0], 50); Trade::MeshAttributeData positions{Trade::MeshAttribute::Position,
CORRADE_COMPARE(interleaved.stride()[1], 1); Containers::StridedArrayView1D<Vector2>{vertexData,
reinterpret_cast<Vector2*>(vertexData.data() + 100), 3, 8}};
Trade::MeshAttributeData normals{Trade::MeshAttribute::Normal,
vertexFormatWrap(0x1234),
Containers::StridedArrayView1D<char>{vertexData,
vertexData.data() + 100 + 8, 3, 8}};
Trade::MeshData data{MeshPrimitive::Triangles, std::move(vertexData), {positions, normals}};
CORRADE_VERIFY(!MeshTools::isInterleaved(data));
}
/* A non-interleaved (or not?) attribute with a implementation-specific
format after interleaved ones is also invalid */
{
Containers::Array<char> vertexData{100 + 3*20 + 3};
Trade::MeshAttributeData positions{Trade::MeshAttribute::Position,
Containers::StridedArrayView1D<Vector2>{vertexData,
reinterpret_cast<Vector2*>(vertexData.data() + 100), 3, 20}};
Trade::MeshAttributeData normals{Trade::MeshAttribute::Normal,
Containers::StridedArrayView1D<Vector3>{vertexData,
reinterpret_cast<Vector3*>(vertexData.data() + 100 + 8), 3, 20}};
Trade::MeshAttributeData extra{Trade::meshAttributeCustom(1234),
vertexFormatWrap(0x1234),
Containers::StridedArrayView1D<char>{vertexData,
vertexData.data() + 100 + 3*20, 3, 1}};
/* The result should be the same independent on the order of attributes */
} {
Trade::MeshData data{MeshPrimitive::Triangles, {}, vertexData, Trade::MeshData data{MeshPrimitive::Triangles, {}, vertexData,
{normals, positions}}; {positions, normals, extra}};
CORRADE_VERIFY(MeshTools::isInterleaved(data)); CORRADE_VERIFY(!MeshTools::isInterleaved(data));
Containers::StridedArrayView2D<const char> interleaved = MeshTools::interleavedData(data);
CORRADE_COMPARE(interleaved.data(), positions.data().data());
CORRADE_COMPARE(interleaved.size()[0], 3);
CORRADE_COMPARE(interleaved.size()[1], 50);
CORRADE_COMPARE(interleaved.stride()[0], 50);
CORRADE_COMPARE(interleaved.stride()[1], 1);
} }
} }

Loading…
Cancel
Save