summaryrefslogtreecommitdiff
path: root/indra/newview/llmodelpreview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llmodelpreview.cpp')
-rw-r--r--indra/newview/llmodelpreview.cpp113
1 files changed, 58 insertions, 55 deletions
diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp
index 5a8c1b474a..5d81d2c9b3 100644
--- a/indra/newview/llmodelpreview.cpp
+++ b/indra/newview/llmodelpreview.cpp
@@ -559,7 +559,7 @@ void LLModelPreview::rebuildUploadData()
bool upload_skinweights = fmp && fmp->childGetValue("upload_skin").asBoolean();
if (upload_skinweights && high_lod_model->mSkinInfo.mJointNames.size() > 0)
{
- LLQuaternion bind_rot = LLSkinningUtil::getUnscaledQuaternion(high_lod_model->mSkinInfo.mBindShapeMatrix);
+ LLQuaternion bind_rot = LLSkinningUtil::getUnscaledQuaternion(LLMatrix4(high_lod_model->mSkinInfo.mBindShapeMatrix));
LLQuaternion identity;
if (!bind_rot.isEqualEps(identity, 0.01))
{
@@ -1380,6 +1380,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
S32 buf_positions_copied = 0;
S32 buf_indices_copied = 0;
indices_idx_shift = 0;
+ S32 valid_faces = 0;
// Crude method to copy indices back into face
for (U32 face_idx = 0; face_idx < base_model->getNumVolumeFaces(); ++face_idx)
@@ -1478,6 +1479,8 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
U32 tex_size = (buf_positions_copied * sizeof(LLVector2) + 0xF)&~0xF;
LLVector4a::memcpyNonAliased16((F32*)new_face.mTexCoords, (F32*)buffer_tex_coords, tex_size);
+
+ valid_faces++;
}
indices_idx_shift += face.mNumVertices;
@@ -1490,7 +1493,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
ll_aligned_free_16(buffer_indices);
ll_aligned_free_32(combined_indices);
- if (new_indices < 3)
+ if (new_indices < 3 || valid_faces == 0)
{
// Model should have at least one visible triangle
@@ -1691,12 +1694,6 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
end = which_lod;
}
- LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
- if (shader)
- {
- shader->unbind();
- }
-
for (S32 lod = start; lod >= end; --lod)
{
if (which_lod == -1)
@@ -1740,7 +1737,7 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
// but combine all submodels with origin model as well
if (model_meshopt_mode == MESH_OPTIMIZER_COMBINE)
{
- // Run meshoptimizer for each model/object, up to 8 faces in one model
+ // Run meshoptimizer for each model/object, up to 8 faces in one model.
// Ideally this should run not per model,
// but combine all submodels with origin model as well
@@ -1762,10 +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.
F32 allowed_ratio_drift = 2.f;
F32 res_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, false);
@@ -1776,25 +1778,44 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
{
genMeshOptimizerPerFace(base, target_model, face_idx, indices_decimator, lod_error_threshold, false);
}
- LL_INFOS() << "Model " << target_model->getName()
- << " lod " << which_lod
- << " per model method overflow, defaulting to per face." << LL_ENDL;
}
else if (res_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);
- LL_INFOS() << "Model " << target_model->getName()
- << " lod " << which_lod
- << " sloppily simplified using per model method." << LL_ENDL;
+
+ // 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))
+ {
+ // 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);
+ }
if (res_ratio < 0)
{
// Sloppy variant failed to generate triangles.
// Can happen with models that are too simple as is.
- // Fallback to normal method.
+ // Fallback to normal method or use lower decimator.
genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, false);
+
+ LL_INFOS() << "Model " << target_model->getName()
+ << " lod " << which_lod
+ << " simplified using per model method." << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS() << "Model " << target_model->getName()
+ << " lod " << which_lod
+ << " sloppily simplified using per model method." << LL_ENDL;
}
}
else
@@ -1846,12 +1867,6 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
}
mResourceCost = calcResourceCost();
-
- LLVertexBuffer::unbind();
- if (shader)
- {
- shader->bind();
- }
}
void LLModelPreview::updateStatusMessages()
@@ -2652,6 +2667,8 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
*(index_strider++) = vf.mIndices[i];
}
+ vb->flush();
+
mVertexBuffer[lod][mdl].push_back(vb);
vertex_count += num_vertices;
@@ -2877,8 +2894,6 @@ BOOL LLModelPreview::render()
LLMutexLock lock(this);
mNeedsUpdate = FALSE;
- bool use_shaders = LLGLSLShader::sNoFixedFunction;
-
bool edges = mViewOption["show_edges"];
bool joint_overrides = mViewOption["show_joint_overrides"];
bool joint_positions = mViewOption["show_joint_positions"];
@@ -2896,10 +2911,8 @@ BOOL LLModelPreview::render()
LLGLDisable fog(GL_FOG);
{
- if (use_shaders)
- {
- gUIProgram.bind();
- }
+ gUIProgram.bind();
+
//clear background to grey
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.pushMatrix();
@@ -2918,10 +2931,7 @@ BOOL LLModelPreview::render()
gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.popMatrix();
- if (use_shaders)
- {
- gUIProgram.unbind();
- }
+ gUIProgram.unbind();
}
LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance;
@@ -3074,10 +3084,7 @@ BOOL LLModelPreview::render()
refresh();
}
- if (use_shaders)
- {
- gObjectPreviewProgram.bind();
- }
+ gObjectPreviewProgram.bind();
gGL.loadIdentity();
gPipeline.enableLightsPreview();
@@ -3137,6 +3144,11 @@ BOOL LLModelPreview::render()
genBuffers(mPreviewLOD, skin_weight);
}
+ if (physics && mVertexBuffer[LLModel::LOD_PHYSICS].empty())
+ {
+ genBuffers(LLModel::LOD_PHYSICS, false);
+ }
+
if (!skin_weight)
{
for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
@@ -3198,6 +3210,7 @@ BOOL LLModelPreview::render()
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glLineWidth(1.f);
}
+ buffer->flush();
}
gGL.popMatrix();
}
@@ -3278,7 +3291,7 @@ BOOL LLModelPreview::render()
}
gGL.diffuseColor4ubv(hull_colors[i].mV);
- LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions, physics.mMesh[i].mNormals);
+ LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions);
if (explode > 0.f)
{
@@ -3291,11 +3304,6 @@ BOOL LLModelPreview::render()
if (render_mesh)
{
- if (mVertexBuffer[LLModel::LOD_PHYSICS].empty())
- {
- genBuffers(LLModel::LOD_PHYSICS, false);
- }
-
U32 num_models = mVertexBuffer[LLModel::LOD_PHYSICS][model].size();
if (pass > 0){
for (U32 i = 0; i < num_models; ++i)
@@ -3315,6 +3323,8 @@ BOOL LLModelPreview::render()
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glLineWidth(1.f);
+
+ buffer->flush();
}
}
}
@@ -3359,11 +3369,6 @@ BOOL LLModelPreview::render()
if (physics.mHull.empty())
{
- if (mVertexBuffer[LLModel::LOD_PHYSICS].empty())
- {
- genBuffers(LLModel::LOD_PHYSICS, false);
- }
-
U32 num_models = mVertexBuffer[LLModel::LOD_PHYSICS][model].size();
for (U32 v = 0; v < num_models; ++v)
{
@@ -3390,6 +3395,8 @@ BOOL LLModelPreview::render()
buffer->draw(LLRender::POINTS, 3, i);
}
}
+
+ buffer->flush();
}
}
}
@@ -3450,7 +3457,7 @@ BOOL LLModelPreview::render()
LLJoint *joint = getPreviewAvatar()->getJoint(skin->mJointNums[j]);
if (joint)
{
- const LLVector3& jointPos = skin->mAlternateBindMatrix[j].getTranslation();
+ const LLVector3& jointPos = LLVector3(skin->mAlternateBindMatrix[j].getTranslation());
if (joint->aboveJointPosThreshold(jointPos))
{
bool override_changed;
@@ -3492,11 +3499,10 @@ BOOL LLModelPreview::render()
//build matrix palette
LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT];
- LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, joint_count,
+ LLSkinningUtil::initSkinningMatrixPalette(mat, joint_count,
skin, getPreviewAvatar());
- LLMatrix4a bind_shape_matrix;
- bind_shape_matrix.loadu(skin->mBindShapeMatrix);
+ const LLMatrix4a& bind_shape_matrix = skin->mBindShapeMatrix;
U32 max_joints = LLSkinningUtil::getMaxJointCount();
for (U32 j = 0; j < buffer->getNumVerts(); ++j)
{
@@ -3579,10 +3585,7 @@ BOOL LLModelPreview::render()
}
}
- if (use_shaders)
- {
- gObjectPreviewProgram.unbind();
- }
+ gObjectPreviewProgram.unbind();
gGL.popMatrix();