Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 16 additions & 32 deletions indra/newview/gltf/llgltfloader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,57 +263,41 @@ bool LLGLTFLoader::parseMeshes()
std::map<std::string, S32> mesh_name_counts;
U32 submodel_limit = mGLTFAsset.mNodes.size() > 0 ? mGeneratedModelLimit / (U32)mGLTFAsset.mNodes.size() : 0;

// Mark which nodes have been processed to avoid duplicates
std::vector<bool> node_processed(mGLTFAsset.mNodes.size(), false);
// Build parent mapping for efficient traversal
std::vector<S32> node_parents(mGLTFAsset.mNodes.size(), -1);
std::vector<bool> is_root(mGLTFAsset.mNodes.size(), true);

// First, find root nodes (nodes without parents) and process their hierarchies
for (size_t node_idx = 0; node_idx < mGLTFAsset.mNodes.size(); node_idx++)
// Build parent relationships
for (size_t parent_idx = 0; parent_idx < mGLTFAsset.mNodes.size(); parent_idx++)
{
if (!node_processed[node_idx])
const auto& parent_node = mGLTFAsset.mNodes[parent_idx];
for (S32 child_idx : parent_node.mChildren)
{
// Check if this node has a parent
bool has_parent = false;
for (const auto& potential_parent : mGLTFAsset.mNodes)
{
if (std::find(potential_parent.mChildren.begin(),
potential_parent.mChildren.end(),
static_cast<S32>(node_idx)) != potential_parent.mChildren.end())
{
has_parent = true;
break;
}
}

// If no parent, this is a root node - process its hierarchy
if (!has_parent)
if (child_idx >= 0 && child_idx < static_cast<S32>(mGLTFAsset.mNodes.size()))
{
processNodeHierarchy(static_cast<S32>(node_idx), mesh_name_counts, submodel_limit, volume_params, node_processed);
node_parents[child_idx] = static_cast<S32>(parent_idx);
is_root[child_idx] = false;
}
}
}

// Process any remaining unprocessed nodes (disconnected nodes)
// Process all root nodes and their hierarchies
for (size_t node_idx = 0; node_idx < mGLTFAsset.mNodes.size(); node_idx++)
{
if (!node_processed[node_idx])
if (is_root[node_idx])
{
processNodeHierarchy(static_cast<S32>(node_idx), mesh_name_counts, submodel_limit, volume_params, node_processed);
processNodeHierarchy(static_cast<S32>(node_idx), mesh_name_counts, submodel_limit, volume_params);
}
}

return true;
}

void LLGLTFLoader::processNodeHierarchy(S32 node_idx, std::map<std::string, S32>& mesh_name_counts, U32 submodel_limit, const LLVolumeParams& volume_params, std::vector<bool>& node_processed)
void LLGLTFLoader::processNodeHierarchy(S32 node_idx, std::map<std::string, S32>& mesh_name_counts, U32 submodel_limit, const LLVolumeParams& volume_params)
{
if (node_idx < 0 || node_idx >= static_cast<S32>(mGLTFAsset.mNodes.size()))
return;

if (node_processed[node_idx])
return;

node_processed[node_idx] = true;

auto& node = mGLTFAsset.mNodes[node_idx];

// Process this node's mesh if it has one
Expand Down Expand Up @@ -393,10 +377,10 @@ void LLGLTFLoader::processNodeHierarchy(S32 node_idx, std::map<std::string, S32>
}
}

// Process all children
// Process all children recursively
for (S32 child_idx : node.mChildren)
{
processNodeHierarchy(child_idx, mesh_name_counts, submodel_limit, volume_params, node_processed);
processNodeHierarchy(child_idx, mesh_name_counts, submodel_limit, volume_params);
}
}

Expand Down
2 changes: 1 addition & 1 deletion indra/newview/gltf/llgltfloader.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ class LLGLTFLoader : public LLModelLoader
bool parseMaterials();
void uploadMaterials();
void computeCombinedNodeTransform(const LL::GLTF::Asset& asset, S32 node_index, glm::mat4& combined_transform) const;
void processNodeHierarchy(S32 node_idx, std::map<std::string, S32>& mesh_name_counts, U32 submodel_limit, const LLVolumeParams& volume_params, std::vector<bool>& node_processed);
void processNodeHierarchy(S32 node_idx, std::map<std::string, S32>& mesh_name_counts, U32 submodel_limit, const LLVolumeParams& volume_params);
bool populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &mesh, const LL::GLTF::Node &node, material_map& mats, S32 instance_count);
void populateJointFromSkin(S32 skin_idx);
void addModelToScene(LLModel* pModel, U32 submodel_limit, const LLMatrix4& transformation, const LLVolumeParams& volume_params, const material_map& mats);
Expand Down