Browse Source

MeshTools: implement combine*() using interleavedLayout().

So the same logic isn't duplicated in two places, plus future-proofing
for when interleavedLayout() gains alignment-aware attribute reordering.
pull/623/head
Vladimír Vondruš 3 years ago
parent
commit
62b954e258
  1. 71
      src/Magnum/MeshTools/Combine.cpp

71
src/Magnum/MeshTools/Combine.cpp

@ -52,29 +52,40 @@ Trade::MeshData combineIndexedImplementation(
combinedIndices, combinedIndices,
indexDataI); indexDataI);
/* Calculate attribute count and vertex stride */ /* Gather attributes of all input meshes together */
UnsignedInt attributeCount = 0; Containers::Array<Trade::MeshAttributeData> attributes;
UnsignedInt vertexStride = 0; {
for(std::size_t i = 0; i != meshes.size(); ++i) { UnsignedInt attributeCount = 0;
attributeCount += meshes[i].attributeCount(); for(const Trade::MeshData& mesh: meshes)
for(UnsignedInt j = 0; j != meshes[i].attributeCount(); ++j) { attributeCount += mesh.attributeCount();
const VertexFormat format = meshes[i].attributeFormat(j); attributes = Containers::Array<Trade::MeshAttributeData>{ValueInit, attributeCount};
CORRADE_ASSERT(!isVertexFormatImplementationSpecific(format), UnsignedInt attributeOffset = 0;
assertPrefix << "attribute" << j << "of mesh" << i << "has an implementation-specific format" << reinterpret_cast<void*>(vertexFormatUnwrap(format)), for(std::size_t i = 0; i != meshes.size(); ++i) {
(Trade::MeshData{MeshPrimitive::Points, 0})); const Trade::MeshData& mesh = meshes[i];
for(std::size_t j = 0; j != mesh.attributeCount(); ++j) {
vertexStride += vertexFormatSize(format)*Math::max(meshes[i].attributeArraySize(j), UnsignedShort{1}); const VertexFormat format = mesh.attributeFormat(j);
/* While interleavedLayout() has the same assert, we'd have no
way to detect if we should bail early if it triggers, so
this is easier; plus the user gets a less confusing function
name in the message */
CORRADE_ASSERT(!isVertexFormatImplementationSpecific(format),
assertPrefix << "attribute" << j << "of mesh" << i << "has an implementation-specific format" << reinterpret_cast<void*>(vertexFormatUnwrap(format)),
(Trade::MeshData{MeshPrimitive::Points, 0}));
attributes[attributeOffset++] = mesh.attributeData(j);
}
} }
} }
/* Allocate resulting attribute and vertex data and duplicate the /* Allocate an interleaved layout */
attributes there according to the combined index buffer */ /** @todo support InterleaveFlag::PreserveInterleavedAttributes here, for
Containers::Array<char> vertexData{NoInit, vertexStride*vertexCount}; example by putting all the attributes into the MeshData instance and
Containers::Array<Trade::MeshAttributeData> attributeData{attributeCount}; not as extras? */
Trade::MeshData out = interleavedLayout(Trade::MeshData{primitive, 0}, vertexCount, attributes, InterleaveFlags{});
/* Duplicate the attributes there according to the combined index buffer */
{ {
std::size_t indexOffset = 0; UnsignedInt indexOffset = 0;
std::size_t attributeOffset = 0; UnsignedInt attributeOffset = 0;
std::size_t vertexOffset = 0;
for(const Trade::MeshData& mesh: meshes) { for(const Trade::MeshData& mesh: meshes) {
const UnsignedInt indexSize = mesh.isIndexed() ? const UnsignedInt indexSize = mesh.isIndexed() ?
meshIndexTypeSize(mesh.indexType()) : 4; meshIndexTypeSize(mesh.indexType()) : 4;
@ -82,29 +93,19 @@ Trade::MeshData combineIndexedImplementation(
{0, indexOffset}, {0, indexOffset},
{vertexCount, indexSize}); {vertexCount, indexSize});
for(UnsignedInt i = 0; i != mesh.attributeCount(); ++i) { for(UnsignedInt i = 0; i != mesh.attributeCount(); ++i)
Containers::StridedArrayView2D<const char> src = mesh.attribute(i); duplicateInto(indices,
Containers::StridedArrayView2D<char> dst{vertexData, mesh.attribute(i),
vertexData.data() + vertexOffset, out.mutableAttribute(attributeOffset++));
{vertexCount, src.size()[1]},
{std::ptrdiff_t(vertexStride), 1}};
duplicateInto(indices, src, dst);
vertexOffset += src.size()[1];
attributeData[attributeOffset++] = Trade::MeshAttributeData{
mesh.attributeName(i), mesh.attributeFormat(i), dst,
mesh.attributeArraySize(i)};
}
indexOffset += indexSize; indexOffset += indexSize;
} }
/* Check we pre-calculated correctly */
CORRADE_INTERNAL_ASSERT(attributeOffset == attributeCount && vertexOffset == vertexStride);
} }
/* Combine the index buffer in */
return Trade::MeshData{primitive, return Trade::MeshData{primitive,
std::move(indexData), Trade::MeshIndexData{indexDataI}, std::move(indexData), Trade::MeshIndexData{indexDataI},
std::move(vertexData), std::move(attributeData), vertexCount}; out.releaseVertexData(), out.releaseAttributeData(), vertexCount};
} }
} }

Loading…
Cancel
Save