summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorAndrey Lihatskiy <alihatskiy@productengine.com>2025-05-25 00:53:25 +0300
committerAndrey Lihatskiy <alihatskiy@productengine.com>2025-05-25 13:20:44 +0300
commit83fa366de9df385daec05c262f88eefd86af6adf (patch)
tree9afa6bb11e796f95db1827185ce4d2ebce407ab2 /indra
parente8eac13b7ba238172c7d5d677cff744bff8dff6d (diff)
#4109 Fix inside-out geometry from negative scale transforms in GLTF loader
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/gltf/llgltfloader.cpp20
1 files changed, 18 insertions, 2 deletions
diff --git a/indra/newview/gltf/llgltfloader.cpp b/indra/newview/gltf/llgltfloader.cpp
index 2e8521b597..a64df86770 100644
--- a/indra/newview/gltf/llgltfloader.cpp
+++ b/indra/newview/gltf/llgltfloader.cpp
@@ -262,6 +262,9 @@ bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh&
// Combine transforms: coordinate rotation applied to hierarchy transform
const glm::mat4 final_transform = coord_system_rotation * hierarchy_transform;
+ // Check if we have a negative scale (flipped coordinate system)
+ bool hasNegativeScale = glm::determinant(final_transform) < 0.0f;
+
// Pre-compute normal transform matrix (transpose of inverse of upper-left 3x3)
const glm::mat3 normal_transform = glm::transpose(glm::inverse(glm::mat3(final_transform)));
@@ -429,9 +432,22 @@ bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh&
vertices.push_back(vert);
}
- for (U32 i = 0; i < prim.getIndexCount(); i++)
+ // When processing indices, flip winding order if needed
+ for (U32 i = 0; i < prim.getIndexCount(); i += 3)
{
- indices.push_back(prim.mIndexArray[i]);
+ if (hasNegativeScale)
+ {
+ // Flip winding order for negative scale
+ indices.push_back(prim.mIndexArray[i]);
+ indices.push_back(prim.mIndexArray[i + 2]); // Swap these two
+ indices.push_back(prim.mIndexArray[i + 1]);
+ }
+ else
+ {
+ indices.push_back(prim.mIndexArray[i]);
+ indices.push_back(prim.mIndexArray[i + 1]);
+ indices.push_back(prim.mIndexArray[i + 2]);
+ }
}
// Check for empty vertex array before processing