mirror of
https://github.com/openharmony/third_party_meshoptimizer.git
synced 2026-07-19 20:03:59 -04:00
gltfpack: Record the fact that mesh geometry might be duplicate
Instead of computing a hash after mesh processing for every mesh, we now only do this when the mesh has been tagged as possibly-duplicate. This reduces the cost of hash update to cases when we are likely to benefit from them, and makes it easier to disable deduplication entirely for testing. While it is possible that two meshes did not have duplicate geometry before processing and are processed to have it (eg two identical meshes with a redundant vertex stream on one but not the other that gets removed), this is fairly unlikely in practice.
This commit is contained in:
+21
-9
@@ -411,14 +411,18 @@ static void process(cgltf_data* data, const char* input_path, const char* output
|
||||
#endif
|
||||
|
||||
for (size_t i = 0; i < meshes.size(); ++i)
|
||||
processMesh(meshes[i], settings);
|
||||
{
|
||||
Mesh& mesh = meshes[i];
|
||||
processMesh(mesh, settings);
|
||||
|
||||
if (mesh.geometry_duplicate)
|
||||
hashMesh(mesh);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
meshes.insert(meshes.end(), debug_meshes.begin(), debug_meshes.end());
|
||||
#endif
|
||||
|
||||
for (size_t i = 0; i < meshes.size(); ++i)
|
||||
hashMesh(meshes[i]);
|
||||
|
||||
filterEmptyMeshes(meshes); // some meshes may become empty after processing
|
||||
|
||||
@@ -585,19 +589,27 @@ static void process(cgltf_data* data, const char* input_path, const char* output
|
||||
|
||||
const QuantizationTexture& qt = qt_meshes[pi] == size_t(-1) ? qt_dummy : qt_materials[qt_meshes[pi]];
|
||||
|
||||
std::pair<size_t, size_t>& primitive_json = primitive_cache[std::make_pair(prim.geometry_hash[0], prim.geometry_hash[1])];
|
||||
|
||||
comma(json_meshes);
|
||||
|
||||
if (primitive_json.second > 0)
|
||||
if (prim.geometry_duplicate)
|
||||
{
|
||||
json_meshes.append(json_meshes, primitive_json.first, primitive_json.second);
|
||||
std::pair<size_t, size_t>& primitive_json = primitive_cache[std::make_pair(prim.geometry_hash[0], prim.geometry_hash[1])];
|
||||
|
||||
if (primitive_json.second)
|
||||
{
|
||||
// reuse previously written accessors
|
||||
json_meshes.append(json_meshes, primitive_json.first, primitive_json.second);
|
||||
}
|
||||
else
|
||||
{
|
||||
primitive_json.first = json_meshes.size();
|
||||
writeMeshGeometry(json_meshes, views, json_accessors, accr_offset, prim, qp, qt, settings);
|
||||
primitive_json.second = json_meshes.size() - primitive_json.first;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
primitive_json.first = json_meshes.size();
|
||||
writeMeshGeometry(json_meshes, views, json_accessors, accr_offset, prim, qp, qt, settings);
|
||||
primitive_json.second = json_meshes.size() - primitive_json.first;
|
||||
}
|
||||
|
||||
if (prim.material)
|
||||
|
||||
@@ -56,6 +56,8 @@ struct Mesh
|
||||
|
||||
std::vector<Stream> streams;
|
||||
std::vector<unsigned int> indices;
|
||||
|
||||
bool geometry_duplicate;
|
||||
uint64_t geometry_hash[2];
|
||||
|
||||
size_t targets;
|
||||
|
||||
@@ -376,7 +376,12 @@ void dedupMeshes(std::vector<Mesh>& meshes)
|
||||
continue;
|
||||
|
||||
if (mesh.scene != target.scene || mesh.material != target.material || mesh.skin != target.skin)
|
||||
{
|
||||
// mark both meshes as having duplicate geometry; we don't use this in dedupMeshes but it's useful later in the pipeline
|
||||
target.geometry_duplicate = true;
|
||||
mesh.geometry_duplicate = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// basic sanity test; these should be included in geometry hash
|
||||
assert(mesh.streams.size() == target.streams.size());
|
||||
|
||||
Reference in New Issue
Block a user