From d5857b376f1da9ad4fe25ced1a4785a40a82a709 Mon Sep 17 00:00:00 2001
From: Andrey Kleshchev <andreykproductengine@lindenlab.com>
Date: Tue, 20 Jul 2021 21:51:43 +0300
Subject: [PATCH] DRTVWR-542 Generate placehodler triangles when face got
 optimized away like glod does

---
 indra/newview/llmodelpreview.cpp | 55 +++++++++++++++++++++-----------
 1 file changed, 36 insertions(+), 19 deletions(-)

diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp
index 93186657ced..f21b05f9dc4 100644
--- a/indra/newview/llmodelpreview.cpp
+++ b/indra/newview/llmodelpreview.cpp
@@ -1860,12 +1860,13 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, U32 decimation, bool en
                     face.mNumVertices);
                 */
 
-                S32 target_indices = llmax(3, llfloor(num_indices * indices_ratio)); // leave at least one triangle
+                S32 target_indices = 0;
                 F32 result_code = 0; // how far from original the model is, 1 == 100%
                 S32 new_indices = 0;
 
                 if (sloppy)
                 {
+                    target_indices = llfloor(num_indices * indices_ratio);
                     new_indices = LLMeshOptimizer::simplifySloppy(
                         output,
                         face.mIndices,
@@ -1877,11 +1878,9 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, U32 decimation, bool en
                         lod_error_threshold,
                         &result_code);
                 }
-
-                // todo: instead of checking (new_indices <= 0)
-                // create a dummy triangle if simplifySloppy returns nothing
-                if (new_indices <= 0)
+                else
                 {
+                    target_indices = llmax(3, llfloor(num_indices * indices_ratio)); // leave at least one triangle
                     new_indices = LLMeshOptimizer::simplify(
                         output,
                         face.mIndices,
@@ -1903,28 +1902,46 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, U32 decimation, bool en
                         << " new Indices: " << new_indices
                         << " original count: " << num_indices << LL_ENDL;
                 }
-                if (new_indices == 0)
-                {
-                    LL_WARNS() << "No indices generated by meshoptimizer for face " << face_idx
-                        << " of model " << target_model->mLabel
-                        << " target Indices: " << target_indices
-                        << " original count: " << num_indices << LL_ENDL;
-                }
 
                 LLVolumeFace &new_face = target_model->getVolumeFace(face_idx);
 
                 // Copy old values
                 new_face = face;
 
-                // Assign new values
-                new_face.resizeIndices(new_indices); // will wipe out mIndices, so new_face can't substitute output
-                S32 idx_size = (new_indices * sizeof(U16) + 0xF) & ~0xF;
-                LLVector4a::memcpyNonAliased16((F32*)new_face.mIndices, (F32*)output, idx_size);
 
-                ll_aligned_free_16(output);
+                if (new_indices == 0)
+                {
+                    if (!sloppy)
+                    {
+                        // optimizeSloppy() can optimize triangles away even if target_indices is > 2,
+                        // but optimize() isn't supposed to
+                        LL_INFOS() << "No indices generated by meshoptimizer for face " << face_idx
+                            << " of model " << target_model->mLabel
+                            << " target Indices: " << target_indices
+                            << " original count: " << num_indices << LL_ENDL;
+                    }
+
+                    // Face got optimized away
+                    // Generate empty triangle
+                    new_face.resizeIndices(3);
+                    new_face.resizeVertices(1);
+                    memset(new_face.mIndices, 0, sizeof(U16) * 3);
+                    new_face.mPositions[0].clear(); // set first vertice to 0
+                    new_face.mNormals[0].clear();
+                    new_face.mTexCoords[0].setZero();
+                }
+                else
+                {
+                    // Assign new values
+                    new_face.resizeIndices(new_indices); // will wipe out mIndices, so new_face can't substitute output
+                    S32 idx_size = (new_indices * sizeof(U16) + 0xF) & ~0xF;
+                    LLVector4a::memcpyNonAliased16((F32*)new_face.mIndices, (F32*)output, idx_size);
 
-                // clear unused values
-                new_face.optimize();
+                    // clear unused values
+                    new_face.optimize();
+                }
+
+                ll_aligned_free_16(output);
             }
 
             //blind copy skin weights and just take closest skin weight to point on
-- 
GitLab