feat: dump objects into gltf meshes instead of primitives

This commit is contained in:
Jan 2025-01-23 17:46:33 +00:00
parent 708e759f8c
commit 140eb7b7a4
No known key found for this signature in database
GPG Key ID: 44B581F78FF5C57C

View File

@ -42,13 +42,13 @@ namespace
CreateJsonAsset(gltf.asset); CreateJsonAsset(gltf.asset);
CreateSkeletonNodes(gltf, xmodel); CreateSkeletonNodes(gltf, xmodel);
CreateMeshNode(gltf, xmodel); CreateMeshNodes(gltf, xmodel);
CreateRootNode(gltf, xmodel); CreateRootNode(gltf, xmodel);
CreateMaterials(gltf, xmodel); CreateMaterials(gltf, xmodel);
CreateBufferViews(gltf, xmodel); CreateBufferViews(gltf, xmodel);
CreateAccessors(gltf, xmodel); CreateAccessors(gltf, xmodel);
CreateSkin(gltf, xmodel); CreateSkin(gltf, xmodel);
CreateMesh(gltf, xmodel); CreateMeshes(gltf, xmodel);
CreateScene(gltf, xmodel); CreateScene(gltf, xmodel);
FillBufferData(gltf, xmodel, bufferData); FillBufferData(gltf, xmodel, bufferData);
CreateBuffer(gltf, xmodel, bufferData); CreateBuffer(gltf, xmodel, bufferData);
@ -69,39 +69,44 @@ namespace
asset.generator = GLTF_GENERATOR; 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()) if (!gltf.nodes.has_value())
gltf.nodes.emplace(); gltf.nodes.emplace();
m_mesh_node = gltf.nodes->size(); m_first_mesh_node = gltf.nodes->size();
if (xmodel.m_bones.empty()) auto meshIndex = 0u;
m_root_node = m_mesh_node; 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) void CreateRootNode(JsonRoot& gltf, const XModelCommon& xmodel)
{ {
JsonNode rootNode; 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; return;
if (!xmodel.m_name.empty()) if (!xmodel.m_name.empty())
@ -111,25 +116,28 @@ namespace
gltf.nodes.emplace(); gltf.nodes.emplace();
rootNode.children.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); rootNode.children->push_back(m_first_bone_node);
m_root_node = gltf.nodes->size(); m_root_node = gltf.nodes->size();
gltf.nodes->emplace_back(std::move(rootNode)); 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()) if (!gltf.meshes.has_value())
gltf.meshes.emplace(); gltf.meshes.emplace();
JsonMesh mesh;
const auto hasBoneWeightData = !xmodel.m_bone_weight_data.weights.empty(); const auto hasBoneWeightData = !xmodel.m_bone_weight_data.weights.empty();
auto objectIndex = 0u; auto objectIndex = 0u;
for (const auto& object : xmodel.m_objects) for (const auto& object : xmodel.m_objects)
{ {
JsonMesh mesh;
JsonMeshPrimitives primitives; JsonMeshPrimitives primitives;
primitives.material = object.materialIndex; primitives.material = object.materialIndex;
@ -149,9 +157,8 @@ namespace
mesh.primitives.emplace_back(primitives); mesh.primitives.emplace_back(primitives);
objectIndex++; objectIndex++;
gltf.meshes->emplace_back(std::move(mesh));
} }
gltf.meshes->emplace_back(std::move(mesh));
} }
static void CreateMaterials(JsonRoot& gltf, const XModelCommon& xmodel) static void CreateMaterials(JsonRoot& gltf, const XModelCommon& xmodel)
@ -604,7 +611,7 @@ namespace
gltf.buffers->emplace_back(std::move(jsonBuffer)); 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_root_node = 0u;
unsigned m_first_bone_node = 0u; unsigned m_first_bone_node = 0u;
unsigned m_position_accessor = 0u; unsigned m_position_accessor = 0u;