diff --git a/gltf/gltfpack.cpp b/gltf/gltfpack.cpp index a61f057c98..015ec0e0fa 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); @@ -661,6 +661,9 @@ static void process(cgltf_data* data, const char* input_path, const char* output append(json_meshes, "]}}"); } + if (settings.keep_extras) + writeExtras(json_meshes, prim.extras); + append(json_meshes, "}"); } @@ -893,7 +896,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 9644d3862b..86ffdcc482 100644 --- a/gltf/gltfpack.h +++ b/gltf/gltfpack.h @@ -52,6 +52,8 @@ struct Mesh cgltf_material* material; cgltf_skin* skin; + cgltf_extras extras; + cgltf_primitive_type type; std::vector streams; @@ -319,12 +321,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); @@ -397,7 +400,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 68d5610c85..23343dec81 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 c691b48b7b..d5c744a591 100644 --- a/gltf/mesh.cpp +++ b/gltf/mesh.cpp @@ -238,6 +238,9 @@ static bool canMergeMeshes(const Mesh& lhs, const Mesh& rhs, const Settings& set if (lhs.streams.size() != rhs.streams.size()) return false; + if (settings.keep_extras && !areExtrasEqual(lhs.extras, rhs.extras)) + return false; + for (size_t i = 0; i < lhs.streams.size(); ++i) if (lhs.streams[i].type != rhs.streams[i].type || lhs.streams[i].index != rhs.streams[i].index || lhs.streams[i].target != rhs.streams[i].target) return false; @@ -337,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()) @@ -347,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; @@ -354,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; @@ -370,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) @@ -383,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 7d14be33f2..fe9826dbd5 100644 --- a/gltf/parsegltf.cpp +++ b/gltf/parsegltf.cpp @@ -180,6 +180,8 @@ static void parseMeshesGltf(cgltf_data* data, std::vector& meshes, std::ve result.material = primitive.material; + result.extras = primitive.extras; + result.type = primitive.type; result.streams.reserve(primitive.attributes_count); diff --git a/gltf/write.cpp b/gltf/write.cpp index e76591ebfa..51845d3242 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, "}"); }