diff options
author | Andrey Lihatskiy <alihatskiy@productengine.com> | 2025-05-25 00:53:25 +0300 |
---|---|---|
committer | Andrey Lihatskiy <alihatskiy@productengine.com> | 2025-05-25 13:20:44 +0300 |
commit | 83fa366de9df385daec05c262f88eefd86af6adf (patch) | |
tree | 9afa6bb11e796f95db1827185ce4d2ebce407ab2 /indra | |
parent | e8eac13b7ba238172c7d5d677cff744bff8dff6d (diff) |
#4109 Fix inside-out geometry from negative scale transforms in GLTF loader
Diffstat (limited to 'indra')
-rw-r--r-- | indra/newview/gltf/llgltfloader.cpp | 20 |
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 |