diff --git a/src/Engine/Graphics/VertexData.cpp b/src/Engine/Graphics/VertexData.cpp index 7a84b17..3468613 100644 --- a/src/Engine/Graphics/VertexData.cpp +++ b/src/Engine/Graphics/VertexData.cpp @@ -141,24 +141,27 @@ void VertexData::createDescriptors() { void VertexData::loadMesh(MeshId id, Array loadedIndices, Array loadedMeshlets) { std::unique_lock l(vertexDataLock); RegisteredMesh& mesh = registeredMeshes[id]; + assert(mesh.meshData.empty()); // TODO: update if not empty uint32 numChunks = (loadedMeshlets.size() + 2047) / 2048; for (uint32 chunkIdx = 0; chunkIdx < numChunks; ++chunkIdx) { - uint32 meshletOffset = (uint32)meshlets.size(); - AABB meshAABB; - uint32 numMeshlets = 0; uint32 chunkOffset = chunkIdx * 2048; uint32 numRemaining = loadedMeshlets.size() - chunkOffset; + + AABB meshAABB; + uint32 meshletOffset = meshlets.size(); for (uint32 chunk = 0; chunk < std::min(numRemaining, 2048u); chunk++) { Meshlet& m = loadedMeshlets[chunkOffset + chunk]; - numMeshlets++; //... meshAABB = meshAABB.combine(m.boundingBox); + uint32 vertexOffset = (uint32)vertexIndices.size(); vertexIndices.resize(vertexOffset + m.numVertices); std::memcpy(vertexIndices.data() + vertexOffset, m.uniqueVertices, m.numVertices * sizeof(uint32)); + uint32 primitiveOffset = (uint32)primitiveIndices.size(); primitiveIndices.resize(primitiveOffset + (m.numPrimitives * 3)); std::memcpy(primitiveIndices.data() + primitiveOffset, m.primitiveLayout, m.numPrimitives * 3 * sizeof(uint8)); + meshlets.add(MeshletDescription{ .bounding = m.boundingBox, //.toSphere(), .vertexIndices = @@ -172,7 +175,7 @@ void VertexData::loadMesh(MeshId id, Array loadedIndices, Array .size = m.numPrimitives, }, .color = Vector((float)rand() / RAND_MAX, (float)rand() / RAND_MAX, (float)rand() / RAND_MAX), - .indicesOffset = (uint32)registeredMeshes[id].indicesRange.offset, + .indicesOffset = (uint32)registeredMeshes[id].vertexOffset, }); } registeredMeshes[id].meshData.add(MeshData{ @@ -180,7 +183,7 @@ void VertexData::loadMesh(MeshId id, Array loadedIndices, Array .meshletRange = { .offset = meshletOffset, - .size = numMeshlets, + .size = std::min(numRemaining, 2048u), }, }); } @@ -190,11 +193,56 @@ void VertexData::loadMesh(MeshId id, Array loadedIndices, Array .size = (uint32)loadedIndices.size(), }; indices.resize(indices.size() + loadedIndices.size()); - std::memcpy(indices.data() + registeredMeshes[id].meshData[0].indicesRange.offset, loadedIndices.data(), loadedIndices.size() * sizeof(uint32)); + std::memcpy(indices.data() + registeredMeshes[id].meshData[0].indicesRange.offset, loadedIndices.data(), + loadedIndices.size() * sizeof(uint32)); } -void VertexData::updateMesh(MeshId id, Array indices, Array meshlets) { +void VertexData::removeMesh(MeshId id) { + RegisteredMesh& removing = registeredMeshes[id]; + uint32 meshletOffset = meshlets.size(); uint32 numMeshlets = 0; + uint32 vertexIndicesOffset = vertexIndices.size(); + uint32 numVertexIndices = 0; + uint32 primitiveIndicesOffset = primitiveIndices.size(); + uint32 numPrimitiveIndices = 0; + for (const auto& data : removing.meshData) { + meshletOffset = std::min(meshletOffset, data.meshletRange.offset); + numMeshlets += data.meshletRange.size; + for (uint32 m = data.meshletRange.offset; m < data.meshletRange.size; ++m) { + MeshletDescription& meshlet = meshlets[m]; + vertexIndicesOffset = std::min(vertexIndicesOffset, meshlet.vertexIndices.offset); + numVertexIndices += meshlet.vertexIndices.size; + primitiveIndicesOffset = std::min(primitiveIndicesOffset, meshlet.primitiveIndices.offset); + numPrimitiveIndices += meshlet.primitiveIndices.size; + } + } + for (auto& mesh : registeredMeshes) { + for (auto& data : mesh.meshData) { + if (data.meshletRange.offset > meshletOffset) { + for (uint32 i = 0; i < data.meshletRange.size; ++i) { + MeshletDescription& m = meshlets[data.meshletRange.offset]; + if (m.primitiveIndices.offset > primitiveIndicesOffset) { + m.primitiveIndices.offset -= numPrimitiveIndices; + } + if (m.vertexIndices.offset > vertexIndicesOffset) { + m.vertexIndices.offset -= numVertexIndices; + } + } + data.meshletRange.offset -= numMeshlets; + } + } + } + uint32 numMeshletsToMove = meshlets.size() - (meshletOffset + numMeshlets); + uint32 numVertexIndicesToMove = vertexIndices.size() - (vertexIndicesOffset + numVertexIndices); + uint32 numPrimitiveIndicesToMove = primitiveIndices.size() - (primitiveIndicesOffset + numPrimitiveIndices); + std::move(meshlets.begin() + meshletOffset + numMeshlets, meshlets.begin() + meshletOffset + numMeshlets + numMeshletsToMove, + meshlets.begin() + meshletOffset); + std::move(vertexIndices.begin() + vertexIndicesOffset + numVertexIndices, + vertexIndices.begin() + vertexIndicesOffset + numVertexIndices + numVertexIndicesToMove, + vertexIndices.begin() + vertexIndicesOffset); + std::move(primitiveIndices.begin() + primitiveIndicesOffset + numPrimitiveIndices, + primitiveIndices.begin() + primitiveIndicesOffset + numPrimitiveIndices + numPrimitiveIndices, + primitiveIndices.begin() + primitiveIndicesOffset); } void VertexData::commitMeshes() { @@ -273,7 +321,8 @@ void VertexData::serializeMesh(MeshId id, ArchiveBuffer& buffer) { } } Array ind(registeredMeshes[id].meshData[0].indicesRange.size); - std::memcpy(ind.data(), &indices[registeredMeshes[id].meshData[0].indicesRange.offset], registeredMeshes[id].meshData[0].indicesRange.size * sizeof(uint32)); + std::memcpy(ind.data(), &indices[registeredMeshes[id].meshData[0].indicesRange.offset], + registeredMeshes[id].meshData[0].indicesRange.size * sizeof(uint32)); Serialization::save(buffer, out); Serialization::save(buffer, ind); } diff --git a/src/Engine/Graphics/VertexData.h b/src/Engine/Graphics/VertexData.h index f7ef52c..d85c63d 100644 --- a/src/Engine/Graphics/VertexData.h +++ b/src/Engine/Graphics/VertexData.h @@ -58,7 +58,7 @@ class VertexData { void updateMesh(uint32 meshletOffset, PMesh mesh, Component::Transform& transform); virtual void createDescriptors(); void loadMesh(MeshId id, Array indices, Array meshlets); - void updateMesh(MeshId id, Array indices, Array meshlets); + virtual void removeMesh(MeshId id); void commitMeshes(); MeshId allocateVertexData(uint64 numVertices); uint64 getMeshOffset(MeshId id) const { return registeredMeshes[id].vertexOffset; } @@ -101,23 +101,20 @@ class VertexData { // range into primitiveIndices array PoolRange primitiveIndices; Vector color; - // gets added to vertex indices so that they reference the global mesh bool + // gets added to vertex indices so that they reference the global mesh pool uint32 indicesOffset = 0; }; std::mutex materialDataLock; - debug_resource vertexDataResource = {"VertexData"}; Array materialData; Array transparentData; std::mutex vertexDataLock; struct RegisteredMesh { - // each mesh id can have multiple meshdata, in case it needs to be split for having too many meshlets + // each mesh id can have multiple meshdata, in case it needs to be split for having too many meshlets Array meshData; uint64 vertexOffset; uint64 vertexCount; - PoolRange meshletRange; - PoolRange indicesRange; }; Array registeredMeshes;