From 140eb7b7a4e1ae01e1d6c5b16ae5435ae0670572 Mon Sep 17 00:00:00 2001 From: Jan Date: Thu, 23 Jan 2025 17:46:33 +0000 Subject: [PATCH] feat: dump objects into gltf meshes instead of primitives --- src/ObjWriting/XModel/Gltf/GltfWriter.cpp | 67 +++++++++++++---------- 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/src/ObjWriting/XModel/Gltf/GltfWriter.cpp b/src/ObjWriting/XModel/Gltf/GltfWriter.cpp index b0a569c1..18eaf323 100644 --- a/src/ObjWriting/XModel/Gltf/GltfWriter.cpp +++ b/src/ObjWriting/XModel/Gltf/GltfWriter.cpp @@ -42,13 +42,13 @@ namespace CreateJsonAsset(gltf.asset); CreateSkeletonNodes(gltf, xmodel); - CreateMeshNode(gltf, xmodel); + CreateMeshNodes(gltf, xmodel); CreateRootNode(gltf, xmodel); CreateMaterials(gltf, xmodel); CreateBufferViews(gltf, xmodel); CreateAccessors(gltf, xmodel); CreateSkin(gltf, xmodel); - CreateMesh(gltf, xmodel); + CreateMeshes(gltf, xmodel); CreateScene(gltf, xmodel); FillBufferData(gltf, xmodel, bufferData); CreateBuffer(gltf, xmodel, bufferData); @@ -69,39 +69,44 @@ namespace asset.generator = GLTF_GENERATOR; } - void CreateMeshNode(JsonRoot& gltf, const XModelCommon& xmodel) + void CreateMeshNodes(JsonRoot& gltf, const XModelCommon& xmodel) { - JsonNode meshNode; - - if (!xmodel.m_name.empty()) - meshNode.name = xmodel.m_name; - - // We only have one mesh - meshNode.mesh = 0u; - - // Only add skin if the model has bones - if (!xmodel.m_bones.empty()) - { - // We only have one skin - meshNode.skin = 0u; - } - if (!gltf.nodes.has_value()) gltf.nodes.emplace(); - m_mesh_node = gltf.nodes->size(); + m_first_mesh_node = gltf.nodes->size(); - if (xmodel.m_bones.empty()) - m_root_node = m_mesh_node; + auto meshIndex = 0u; + for (const auto& object : xmodel.m_objects) + { + JsonNode meshNode; - gltf.nodes->emplace_back(std::move(meshNode)); + if (!object.name.empty()) + meshNode.name = object.name; + + meshNode.mesh = meshIndex++; + + // Only add skin if the model has bones + if (!xmodel.m_bones.empty()) + { + // We only have one skin + meshNode.skin = 0u; + } + + gltf.nodes->emplace_back(std::move(meshNode)); + } + + // If we only have one mesh and no bones we don't need a dedicated root node + if (xmodel.m_bones.empty() && xmodel.m_objects.size() == 1) + m_root_node = m_first_mesh_node; } void CreateRootNode(JsonRoot& gltf, const XModelCommon& xmodel) { JsonNode rootNode; - if (xmodel.m_bones.empty()) + // If we have at most one mesh and no bones we don't need a dedicated root node + if (xmodel.m_bones.empty() && xmodel.m_objects.size() <= 1) return; if (!xmodel.m_name.empty()) @@ -111,25 +116,28 @@ namespace gltf.nodes.emplace(); rootNode.children.emplace(); - rootNode.children->push_back(m_mesh_node); + + const auto meshCount = xmodel.m_objects.size(); + for (auto meshIndex = 0u; meshIndex < meshCount; meshIndex++) + rootNode.children->push_back(m_first_mesh_node + meshIndex); + rootNode.children->push_back(m_first_bone_node); m_root_node = gltf.nodes->size(); gltf.nodes->emplace_back(std::move(rootNode)); } - void CreateMesh(JsonRoot& gltf, const XModelCommon& xmodel) + void CreateMeshes(JsonRoot& gltf, const XModelCommon& xmodel) { if (!gltf.meshes.has_value()) gltf.meshes.emplace(); - JsonMesh mesh; - const auto hasBoneWeightData = !xmodel.m_bone_weight_data.weights.empty(); auto objectIndex = 0u; for (const auto& object : xmodel.m_objects) { + JsonMesh mesh; JsonMeshPrimitives primitives; primitives.material = object.materialIndex; @@ -149,9 +157,8 @@ namespace mesh.primitives.emplace_back(primitives); objectIndex++; + gltf.meshes->emplace_back(std::move(mesh)); } - - gltf.meshes->emplace_back(std::move(mesh)); } static void CreateMaterials(JsonRoot& gltf, const XModelCommon& xmodel) @@ -604,7 +611,7 @@ namespace gltf.buffers->emplace_back(std::move(jsonBuffer)); } - unsigned m_mesh_node = 0u; + unsigned m_first_mesh_node = 0u; unsigned m_root_node = 0u; unsigned m_first_bone_node = 0u; unsigned m_position_accessor = 0u;