diff options
| -rw-r--r-- | indra/newview/llmodelpreview.cpp | 61 | ||||
| -rw-r--r-- | indra/newview/llviewerparcelmgr.cpp | 2 | 
2 files changed, 45 insertions, 18 deletions
| diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 5d81d2c9b3..9e5a31d71e 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -1759,19 +1759,15 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d                  {                      genMeshOptimizerPerFace(base, target_model, face_idx, indices_decimator, lod_error_threshold, true);                  } - -                LL_INFOS() << "Model " << target_model->getName() -                    << " lod " << which_lod -                    << " simplified using per face method." << LL_ENDL;              }              if (model_meshopt_mode == MESH_OPTIMIZER_AUTO)              { -                // Switches between 'combine' method and 'per model sloppy' based on combine's result. +                // Switches between 'combine' method and 'sloppy' based on combine's result.                  F32 allowed_ratio_drift = 2.f; -                F32 res_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, false); - -                if (res_ratio < 0) +                F32 precise_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, false); +                 +                if (precise_ratio < 0)                  {                      // U16 vertices overflow, shouldn't happen, but just in case                      for (U32 face_idx = 0; face_idx < base->getNumVolumeFaces(); ++face_idx) @@ -1779,42 +1775,72 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d                          genMeshOptimizerPerFace(base, target_model, face_idx, indices_decimator, lod_error_threshold, false);                      }                  } -                else if (res_ratio * allowed_ratio_drift < indices_decimator) +                else if (precise_ratio * allowed_ratio_drift < indices_decimator)                  {                      // Try sloppy variant if normal one failed to simplify model enough. -                    res_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, true); +                    // Sloppy variant can fail entirely and has issues with precision, +                    // so code needs to do multiple attempts with different decimators. +                    // Todo: this is a bit of a mess, needs to be refined and improved +                    F32 last_working_decimator = 0.f; +                    F32 last_working_ratio = F32_MAX; + +                    F32 sloppy_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, true); + +                    if (sloppy_ratio > 0) +                    { +                        // Would be better to do a copy of target_model here, but if +                        // we need to use sloppy decimation, model should be cheap +                        // and fast to generate and it won't affect end result +                        last_working_decimator = indices_decimator; +                        last_working_ratio = sloppy_ratio; +                    }                      // Sloppy has a tendecy to error into lower side, so a request for 100                      // triangles turns into ~70, so check for significant difference from target decimation                      F32 sloppy_ratio_drift = 1.4f;                      if (lod_mode == LIMIT_TRIANGLES -                        && (res_ratio > indices_decimator * sloppy_ratio_drift || res_ratio < 0)) +                        && (sloppy_ratio > indices_decimator * sloppy_ratio_drift || sloppy_ratio < 0))                      {                          // Apply a correction to compensate.                          // (indices_decimator / res_ratio) by itself is likely to overshoot to a differend                          // side due to overal lack of precision, and we don't need an ideal result, which                          // likely does not exist, just a better one, so a partial correction is enough. -                        F32 sloppy_decimator = indices_decimator * (indices_decimator / res_ratio + 1) / 2; -                        res_ratio = genMeshOptimizerPerModel(base, target_model, sloppy_decimator, lod_error_threshold, true); +                        F32 sloppy_decimator = indices_decimator * (indices_decimator / sloppy_ratio + 1) / 2; +                        sloppy_ratio = genMeshOptimizerPerModel(base, target_model, sloppy_decimator, lod_error_threshold, true);                      } +                    if (last_working_decimator > 0 && sloppy_ratio < last_working_ratio) +                    { +                        // Compensation didn't work, return back to previous decimator +                        sloppy_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, true); +                    } + +                    if (sloppy_ratio < 0) +                    { +                        // sloppy method didn't work, final attempt with lower decimation +                        F32 sloppy_decimator = indices_decimator / decimation; +                        sloppy_ratio = genMeshOptimizerPerModel(base, target_model, sloppy_decimator, lod_error_threshold, true); +                    } -                    if (res_ratio < 0) +                    if (sloppy_ratio < 0 || sloppy_ratio < precise_ratio)                      { -                        // Sloppy variant failed to generate triangles. +                        // Sloppy variant failed to generate triangles or is worse.                          // Can happen with models that are too simple as is. -                        // Fallback to normal method or use lower decimator. -                        genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, false); +                        // Fallback to normal method + +                        precise_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, false);                          LL_INFOS() << "Model " << target_model->getName()                              << " lod " << which_lod +                            << " resulting ratio " << precise_ratio                              << " simplified using per model method." << LL_ENDL;                      }                      else                      {                          LL_INFOS() << "Model " << target_model->getName()                              << " lod " << which_lod +                            << " resulting ratio " << sloppy_ratio                              << " sloppily simplified using per model method." << LL_ENDL;                      }                  } @@ -1822,6 +1848,7 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d                  {                      LL_INFOS() << "Model " << target_model->getName()                          << " lod " << which_lod +                        << " resulting ratio " << precise_ratio                          << " simplified using per model method." << LL_ENDL;                  }              } diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 56370df751..e69b0347f8 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -878,7 +878,7 @@ LLParcel* LLViewerParcelMgr::getCollisionParcel() const  void LLViewerParcelMgr::render()  { -	if (mSelected && mRenderSelection && gSavedSettings.getBOOL("RenderParcelSelection")) +	if (mSelected && mRenderSelection && gSavedSettings.getBOOL("RenderParcelSelection") && !gDisconnected)  	{  		// Rendering is done in agent-coordinates, so need to supply  		// an appropriate offset to the render code. | 
