-
I have the following code that uses meshoptimizer: std::vector<uint32_t> remap(mesh.vertices.size()); // allocate temporary memory for the remap table
size_t vertex_count = meshopt_generateVertexRemap(remap.data(), mesh.indices.data(), mesh.indices.size(), mesh.vertices.data(), mesh.vertices.size(), sizeof(vertex_t));
meshopt_remapIndexBuffer(mesh.indices.data(),mesh.indices.data(),mesh.indices.size(),remap.data());
meshopt_remapVertexBuffer(mesh.vertices.data(),mesh.vertices.data(), mesh.vertices.size(), sizeof(vertex_t), remap.data());
meshopt_optimizeVertexCache(mesh.indices.data(), mesh.indices.data(), mesh.indices.size(), mesh.vertices.size());
meshopt_optimizeOverdraw(mesh.indices.data(), mesh.indices.data(), mesh.indices.size(), &mesh.vertices[0].position.x, mesh.vertices.size(), sizeof(vertex_t), 1.05f);
meshopt_optimizeVertexFetch(mesh.vertices.data(), mesh.indices.data(), mesh.indices.size(), mesh.vertices.data(), mesh.vertices.size(), sizeof(vertex_t)); This works great for static meshes. However, my skin weights table is based on the locations in-memory of the vertices before optimization, so my skinned meshes break when rendering. I tried using the remap table like this: remap[weightval.mVertexId] to move the weight cells to match the new locations of the vertices, but this did not fix the issue. Is there a way to get a mapping of new vertex offsets to old vertex offsets so that I can properly handle optimized skinned meshes? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
When using an external skin weights table, you indeed will need to remap the indices. Note that there are two functions you are using that both change the vertex indexing: generateVertexRemap/remapVertexBuffer, and optimizeVertexFetch. If you disable the call to meshopt_optimizeVertexFetch, remap[mVertexId] should work. This would be good to verify. Once it does, you'd need to change from meshopt_optimizeVertexFetch to meshopt_optimizeVertexFetchRemap (which returns the remap table) plus manually call remapIndexBuffer/remapVertexBuffer and remap the vertex ids in skinning data again. (normally meshoptimizer expects skin data to be part of the vertex definitions so it "just works" but with external references you need to go through this process every time you change the vertex ordering, which happens twice here) |
Beta Was this translation helpful? Give feedback.
-
For anyone else who encounters this issue, here is the fixed code: std::vector<uint32_t> remap(mesh.indices.size()); // allocate temporary memory for the remap table
size_t vertex_count = meshopt_generateVertexRemap(remap.data(), mesh.indices.data(), mesh.indices.size(), mesh.vertices.data(), mesh.vertices.size(), sizeof(vertex_t));
meshopt_remapIndexBuffer(mesh.indices.data(),mesh.indices.data(),mesh.indices.size(),remap.data());
meshopt_remapVertexBuffer(mesh.vertices.data(),mesh.vertices.data(), mesh.vertices.size(), sizeof(vertex_t), remap.data());
meshopt_optimizeVertexCache(mesh.indices.data(), mesh.indices.data(), mesh.indices.size(), mesh.vertices.size());
meshopt_optimizeOverdraw(mesh.indices.data(), mesh.indices.data(), mesh.indices.size(), &mesh.vertices[0].position.x, mesh.vertices.size(), sizeof(vertex_t), 1.05f);
auto indcpy = mesh.indices;
meshopt_optimizeVertexFetchRemap(remap.data(), mesh.indices.data(), mesh.indices.size(), mesh.vertices.size());
meshopt_remapIndexBuffer(mesh.indices.data(), indcpy.data(), mesh.indices.size(), remap.data());
meshopt_remapVertexBuffer(mesh.vertices.data(), mesh.vertices.data(), mesh.vertices.size(), sizeof(vertex_t), remap.data()); |
Beta Was this translation helpful? Give feedback.
When using an external skin weights table, you indeed will need to remap the indices. Note that there are two functions you are using that both change the vertex indexing: generateVertexRemap/remapVertexBuffer, and optimizeVertexFetch.
If you disable the call to meshopt_optimizeVertexFetch, remap[mVertexId] should work. This would be good to verify.
Once it does, you'd need to change from meshopt_optimizeVertexFetch to meshopt_optimizeVertexFetchRemap (which returns the remap table) plus manually call remapIndexBuffer/remapVertexBuffer and remap the vertex ids in skinning data again.
(normally meshoptimizer expects skin data to be part of the vertex definitions so it "just works" but with…