diff options
Diffstat (limited to 'indra')
-rw-r--r-- | indra/newview/gltf/llgltfloader.cpp | 48 | ||||
-rw-r--r-- | indra/newview/gltf/llgltfloader.h | 2 |
2 files changed, 17 insertions, 33 deletions
diff --git a/indra/newview/gltf/llgltfloader.cpp b/indra/newview/gltf/llgltfloader.cpp index edcc716298..17de6eb829 100644 --- a/indra/newview/gltf/llgltfloader.cpp +++ b/indra/newview/gltf/llgltfloader.cpp @@ -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 @@ -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); } } diff --git a/indra/newview/gltf/llgltfloader.h b/indra/newview/gltf/llgltfloader.h index 4802c8e093..19337c24aa 100644 --- a/indra/newview/gltf/llgltfloader.h +++ b/indra/newview/gltf/llgltfloader.h @@ -175,7 +175,7 @@ private: 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); |