diff options
| author | Andrey Lihatskiy <alihatskiy@productengine.com> | 2025-05-22 19:53:35 +0300 | 
|---|---|---|
| committer | Andrey Lihatskiy <alihatskiy@productengine.com> | 2025-05-22 19:56:45 +0300 | 
| commit | f5d4d3f86224df61bacabf219b6d053bcdebc3ef (patch) | |
| tree | e4155249d584cb3cb8fee801b133e40194564143 /indra/newview | |
| parent | 9d3a03e6da9604dc3d76ed0649c06c58beb22771 (diff) | |
#4109 Improve handling of GLTF transform hierarchy
Diffstat (limited to 'indra/newview')
| -rw-r--r-- | indra/newview/gltf/llgltfloader.cpp | 44 | ||||
| -rw-r--r-- | indra/newview/gltf/llgltfloader.h | 1 | 
2 files changed, 42 insertions, 3 deletions
| diff --git a/indra/newview/gltf/llgltfloader.cpp b/indra/newview/gltf/llgltfloader.cpp index 22c7c5d13e..871936db95 100644 --- a/indra/newview/gltf/llgltfloader.cpp +++ b/indra/newview/gltf/llgltfloader.cpp @@ -307,6 +307,34 @@ bool LLGLTFLoader::parseMeshes()      return true;  } +void LLGLTFLoader::computeCombinedNodeTransform(const LL::GLTF::Asset& asset, S32 node_index, glm::mat4& combined_transform) +{ +    auto& node = asset.mNodes[node_index]; + +    // Start with this node's transform +    glm::mat4 node_transform = node.mMatrix; + +    // Find parent node and apply its transform if it exists +    for (auto& other_node : asset.mNodes) +    { +        for (auto& child_index : other_node.mChildren) +        { +            if (child_index == node_index) +            { +                // Found a parent, recursively get its combined transform +                glm::mat4 parent_transform; +                computeCombinedNodeTransform(asset, static_cast<S32>(&other_node - &asset.mNodes[0]), parent_transform); + +                // Apply parent transform to current node transform +                node_transform = parent_transform * node_transform; +                break; +            } +        } +    } + +    combined_transform = node_transform; +} +  bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh& mesh, const LL::GLTF::Node& nodeno, material_map& mats,                                                            const F32 scale_factor, const LLVector3& center_offset)  { @@ -438,14 +466,24 @@ bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh&                  }              } +            // Compute combined transform for this node considering parent hierarchy +            S32 node_index = static_cast<S32>(&nodeno - &mGLTFAsset.mNodes[0]); +            glm::mat4 combined_transform; +            computeCombinedNodeTransform(mGLTFAsset, node_index, combined_transform); +              // Apply the global scale and center offset to all vertices              for (U32 i = 0; i < prim.getVertexCount(); i++)              { +                // Transform vertex position with combined hierarchy transform +                glm::vec4 pos(prim.mPositions[i][0], prim.mPositions[i][1], prim.mPositions[i][2], 1.0f); +                glm::vec4 transformed_pos = combined_transform * pos; + +                // Apply scaling and centering after hierarchy transform                  GLTFVertex vert;                  vert.position = glm::vec3( -                    (prim.mPositions[i][0] + center_offset.mV[VX]) * scale_factor, -                    (prim.mPositions[i][1] + center_offset.mV[VY]) * scale_factor, -                    (prim.mPositions[i][2] + center_offset.mV[VZ]) * scale_factor +                    (transformed_pos.x + center_offset.mV[VX]) * scale_factor, +                    (transformed_pos.y + center_offset.mV[VY]) * scale_factor, +                    (transformed_pos.z + center_offset.mV[VZ]) * scale_factor                  );                  vert.normal = glm::vec3(prim.mNormals[i][0], prim.mNormals[i][1], prim.mNormals[i][2]); diff --git a/indra/newview/gltf/llgltfloader.h b/indra/newview/gltf/llgltfloader.h index bfcdccac00..4d02909f72 100644 --- a/indra/newview/gltf/llgltfloader.h +++ b/indra/newview/gltf/llgltfloader.h @@ -167,6 +167,7 @@ private:      void uploadMeshes();      bool parseMaterials();      void uploadMaterials(); +    void computeCombinedNodeTransform(const LL::GLTF::Asset& asset, S32 node_index, glm::mat4& combined_transform);      bool populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &mesh, const LL::GLTF::Node &node, material_map& mats,                                                  const F32 scale_factor = 1.0f, const LLVector3& center_offset = LLVector3());      void populateJointFromSkin(const LL::GLTF::Skin& skin); | 
