Merge branch 'DRTVWR-546' of ssh://bitbucket.org/lindenlab/viewer into DRTVWR-546
commit
ba6ca8d45f
|
|
@ -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 (res_ratio < 0)
|
||||
if (last_working_decimator > 0 && sloppy_ratio < last_working_ratio)
|
||||
{
|
||||
// Sloppy variant failed to generate triangles.
|
||||
// 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 (sloppy_ratio < 0 || sloppy_ratio < precise_ratio)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Reference in New Issue