summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Lihatskiy <alihatskiy@productengine.com>2025-05-22 19:53:35 +0300
committerAndrey Lihatskiy <alihatskiy@productengine.com>2025-05-22 19:56:45 +0300
commitf5d4d3f86224df61bacabf219b6d053bcdebc3ef (patch)
treee4155249d584cb3cb8fee801b133e40194564143
parent9d3a03e6da9604dc3d76ed0649c06c58beb22771 (diff)
#4109 Improve handling of GLTF transform hierarchy
-rw-r--r--indra/newview/gltf/llgltfloader.cpp44
-rw-r--r--indra/newview/gltf/llgltfloader.h1
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);