From ca2e3c5cb0d985cef090fe0d33564c7f395eeffc Mon Sep 17 00:00:00 2001 From: Julien Dupuy Date: Thu, 21 Nov 2024 14:47:19 +0100 Subject: [PATCH] gltfpack: Take account of PR comments and also write the scene extras and the mesh name --- gltf/gltfpack.cpp | 14 +++++++++++--- gltf/gltfpack.h | 7 +++++-- gltf/material.cpp | 16 ++++++++-------- gltf/mesh.cpp | 14 +++++++++----- gltf/parsegltf.cpp | 1 + gltf/write.cpp | 4 +++- 6 files changed, 37 insertions(+), 19 deletions(-) diff --git a/gltf/gltfpack.cpp b/gltf/gltfpack.cpp index 41195aa40..3d3ca0f7c 100644 --- a/gltf/gltfpack.cpp +++ b/gltf/gltfpack.cpp @@ -360,7 +360,7 @@ static void process(cgltf_data* data, const char* input_path, const char* output mergeMeshMaterials(data, meshes, settings); if (settings.mesh_dedup) - dedupMeshes(meshes); + dedupMeshes(meshes, settings); for (size_t i = 0; i < meshes.size(); ++i) detachMesh(meshes[i], data, nodes, settings); @@ -587,7 +587,15 @@ static void process(cgltf_data* data, const char* input_path, const char* output const Mesh& mesh = meshes[i]; comma(json_meshes); - append(json_meshes, "{\"primitives\":["); + append(json_meshes, "{"); + if (mesh.name && *mesh.name) + { + append(json_meshes, "\"name\":\""); + append(json_meshes, mesh.name); + append(json_meshes, "\""); + comma(json_meshes); + } + append(json_meshes, "\"primitives\":["); size_t pi = i; for (; pi < meshes.size(); ++pi) @@ -896,7 +904,7 @@ static void process(cgltf_data* data, const char* input_path, const char* output append(json, ",\"scenes\":["); for (size_t i = 0; i < data->scenes_count; ++i) - writeScene(json, data->scenes[i], json_roots[i]); + writeScene(json, data->scenes[i], json_roots[i], settings); append(json, "]"); } diff --git a/gltf/gltfpack.h b/gltf/gltfpack.h index 8f3f594b9..60a691a13 100644 --- a/gltf/gltfpack.h +++ b/gltf/gltfpack.h @@ -62,6 +62,8 @@ struct Mesh bool geometry_duplicate; uint64_t geometry_hash[2]; + const char* name; + size_t targets; std::vector target_weights; std::vector target_names; @@ -321,12 +323,13 @@ bool compareMeshVariants(const Mesh& lhs, const Mesh& rhs); bool compareMeshNodes(const Mesh& lhs, const Mesh& rhs); void hashMesh(Mesh& mesh); -void dedupMeshes(std::vector& meshes); +void dedupMeshes(std::vector& meshes, const Settings& settings); void mergeMeshInstances(Mesh& mesh); void mergeMeshes(std::vector& meshes, const Settings& settings); void filterEmptyMeshes(std::vector& meshes); void filterStreams(Mesh& mesh, const MaterialInfo& mi); +bool areExtrasEqual(const cgltf_extras& lhs, const cgltf_extras& rhs); void mergeMeshMaterials(cgltf_data* data, std::vector& meshes, const Settings& settings); void markNeededMaterials(cgltf_data* data, std::vector& materials, const std::vector& meshes, const Settings& settings); @@ -399,7 +402,7 @@ void writeLight(std::string& json, const cgltf_light& light); void writeArray(std::string& json, const char* name, const std::string& contents); void writeExtensions(std::string& json, const ExtensionInfo* extensions, size_t count); void writeExtras(std::string& json, const cgltf_extras& extras); -void writeScene(std::string& json, const cgltf_scene& scene, const std::string& roots); +void writeScene(std::string& json, const cgltf_scene& scene, const std::string& roots, const Settings& settings); /** * Copyright (c) 2016-2024 Arseny Kapoulkine diff --git a/gltf/material.cpp b/gltf/material.cpp index 68d5610c8..23343dec8 100644 --- a/gltf/material.cpp +++ b/gltf/material.cpp @@ -55,14 +55,6 @@ static bool areTextureViewsEqual(const cgltf_texture_view& lhs, const cgltf_text return true; } -static bool areExtrasEqual(const cgltf_extras& lhs, const cgltf_extras& rhs) -{ - if (lhs.data && rhs.data) - return strcmp(lhs.data, rhs.data) == 0; - else - return lhs.data == rhs.data; -} - static bool areMaterialComponentsEqual(const cgltf_pbr_metallic_roughness& lhs, const cgltf_pbr_metallic_roughness& rhs) { if (!areTextureViewsEqual(lhs.base_color_texture, rhs.base_color_texture)) @@ -576,6 +568,14 @@ static bool shouldKeepAlpha(const cgltf_texture_view& color, float alpha, cgltf_ return image && getChannels(*image, images[image - data->images], input_path) == 4; } +bool areExtrasEqual(const cgltf_extras& lhs, const cgltf_extras& rhs) +{ + if (lhs.data && rhs.data) + return strcmp(lhs.data, rhs.data) == 0; + else + return lhs.data == rhs.data; +} + void optimizeMaterials(cgltf_data* data, const char* input_path, std::vector& images) { for (size_t i = 0; i < data->materials_count; ++i) diff --git a/gltf/mesh.cpp b/gltf/mesh.cpp index a3828a299..d5c744a59 100644 --- a/gltf/mesh.cpp +++ b/gltf/mesh.cpp @@ -238,7 +238,7 @@ static bool canMergeMeshes(const Mesh& lhs, const Mesh& rhs, const Settings& set if (lhs.streams.size() != rhs.streams.size()) return false; - if (lhs.extras.data && rhs.extras.data && strcmp(lhs.extras.data, rhs.extras.data)) + if (settings.keep_extras && !areExtrasEqual(lhs.extras, rhs.extras)) return false; for (size_t i = 0; i < lhs.streams.size(); ++i) @@ -340,7 +340,7 @@ void hashMesh(Mesh& mesh) hashUpdate(mesh.geometry_hash, meta, sizeof(meta)); } -static bool canDedupMesh(const Mesh& mesh) +static bool canDedupMesh(const Mesh& mesh, const Settings& settings) { // empty mesh if (mesh.streams.empty()) @@ -350,6 +350,10 @@ static bool canDedupMesh(const Mesh& mesh) if (mesh.nodes.empty() && mesh.instances.empty()) return false; + // has extras + if (settings.keep_extras && mesh.extras.data) + return false; + // to simplify dedup we ignore complex target setups for now if (!mesh.target_weights.empty() || !mesh.target_names.empty() || !mesh.variants.empty()) return false; @@ -357,7 +361,7 @@ static bool canDedupMesh(const Mesh& mesh) return true; } -void dedupMeshes(std::vector& meshes) +void dedupMeshes(std::vector& meshes, const Settings& settings) { std::unordered_map hashes; @@ -373,7 +377,7 @@ void dedupMeshes(std::vector& meshes) { Mesh& target = meshes[i]; - if (!canDedupMesh(target)) + if (!canDedupMesh(target, settings)) continue; if (hashes[target.geometry_hash[0] ^ target.geometry_hash[1]] <= 1) @@ -386,7 +390,7 @@ void dedupMeshes(std::vector& meshes) if (mesh.geometry_hash[0] != target.geometry_hash[0] || mesh.geometry_hash[1] != target.geometry_hash[1]) continue; - if (!canDedupMesh(mesh)) + if (!canDedupMesh(mesh, settings)) continue; if (mesh.scene != target.scene || mesh.material != target.material || mesh.skin != target.skin) diff --git a/gltf/parsegltf.cpp b/gltf/parsegltf.cpp index fe9826dbd..61fb6ad23 100644 --- a/gltf/parsegltf.cpp +++ b/gltf/parsegltf.cpp @@ -269,6 +269,7 @@ static void parseMeshesGltf(cgltf_data* data, std::vector& meshes, std::ve result.targets = primitive.targets_count; result.target_weights.assign(mesh.weights, mesh.weights + mesh.weights_count); result.target_names.assign(mesh.target_names, mesh.target_names + mesh.target_names_count); + result.name = mesh.name; result.variants.assign(primitive.mappings, primitive.mappings + primitive.mappings_count); } diff --git a/gltf/write.cpp b/gltf/write.cpp index e76591ebf..51845d324 100644 --- a/gltf/write.cpp +++ b/gltf/write.cpp @@ -1610,7 +1610,7 @@ void writeExtras(std::string& json, const cgltf_extras& extras) appendJson(json, extras.data); } -void writeScene(std::string& json, const cgltf_scene& scene, const std::string& roots) +void writeScene(std::string& json, const cgltf_scene& scene, const std::string& roots, const Settings& settings) { comma(json); append(json, "{"); @@ -1627,5 +1627,7 @@ void writeScene(std::string& json, const cgltf_scene& scene, const std::string& append(json, roots); append(json, "]"); } + if (settings.keep_extras) + writeExtras(json, scene.extras); append(json, "}"); }