diff options
-rw-r--r-- | indra/llmeshoptimizer/llmeshoptimizer.h | 3 | ||||
-rw-r--r-- | indra/newview/llmodelpreview.cpp | 180 |
2 files changed, 101 insertions, 82 deletions
diff --git a/indra/llmeshoptimizer/llmeshoptimizer.h b/indra/llmeshoptimizer/llmeshoptimizer.h index a0c53ed9e1..157de0251d 100644 --- a/indra/llmeshoptimizer/llmeshoptimizer.h +++ b/indra/llmeshoptimizer/llmeshoptimizer.h @@ -36,7 +36,8 @@ public: LLMeshOptimizer(); ~LLMeshOptimizer(); - // returns state + // returns amount of indices in destiantion + // result_error returns how far from original the model is in % if not NULL static U64 simplify( U16 *destination, const U16 *indices, diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index f23143e3fa..0cf44ca1cb 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -1404,7 +1404,7 @@ void LLModelPreview::genGlodLODs(S32 which_lod, U32 decimation, bool enforce_tri U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0; - U32 lod_mode = 0; + U32 lod_mode = LIMIT_TRIANGLES; F32 lod_error_threshold = 0; @@ -3569,7 +3569,7 @@ void LLModelPreview::onLODGenerateParamCommit(S32 lod, bool enforce_tri_limit) } } -void LLModelPreview::onLODMeshOptimizerParamCommit(S32 lod, bool enforce_tri_limit) +void LLModelPreview::onLODMeshOptimizerParamCommit(S32 requested_lod, bool enforce_tri_limit) { if (mLODFrozen) { @@ -3577,10 +3577,10 @@ void LLModelPreview::onLODMeshOptimizerParamCommit(S32 lod, bool enforce_tri_lim } // Allow LoD from -1 to LLModel::LOD_PHYSICS - if (lod < -1 || lod > LLModel::NUM_LODS - 1) + if (requested_lod < -1 || requested_lod > LLModel::NUM_LODS - 1) { std::ostringstream out; - out << "Invalid level of detail: " << lod; + out << "Invalid level of detail: " << requested_lod; LL_WARNS() << out.str() << LL_ENDL; LLFloaterModelPreview::addStringToLog(out, false); assert(lod >= -1 && lod < LLModel::NUM_LODS); @@ -3592,106 +3592,108 @@ void LLModelPreview::onLODMeshOptimizerParamCommit(S32 lod, bool enforce_tri_lim return; } - - U32 triangle_count = 0; - U32 instanced_triangle_count = 0; - - //get the triangle count for the whole scene - for (LLModelLoader::scene::iterator iter = mBaseScene.begin(), endIter = mBaseScene.end(); iter != endIter; ++iter) - { - for (LLModelLoader::model_instance_list::iterator instance = iter->second.begin(), end_instance = iter->second.end(); instance != end_instance; ++instance) - { - LLModel* mdl = instance->mModel; - if (mdl) - { - instanced_triangle_count += mdl->getNumTriangles(); - } - } - } - - //get the triangle count for the non-instanced set of models - for (U32 i = 0; i < mBaseModel.size(); ++i) + //get the triangle count for all base models + S32 base_triangle_count = 0; + for (S32 i = 0; i < mBaseModel.size(); ++i) { - triangle_count += mBaseModel[i]->getNumTriangles(); + base_triangle_count += mBaseModel[i]->getNumTriangles(); } - //get ratio of uninstanced triangles to instanced triangles - F32 triangle_ratio = (F32)triangle_count / (F32)instanced_triangle_count; - U32 base_triangle_count = triangle_count; - U32 lod_mode = 0; - F32 lod_error_threshold = 0; - - // Urgh... // TODO: add interface to mFMP to get error treshold or let mFMP write one into LLModelPreview // We should not be accesing views from other class! - LLCtrlSelectionInterface* iface = mFMP->childGetSelectionInterface("lod_mode_" + lod_name[lod]); - if (iface) + U32 lod_mode = LIMIT_TRIANGLES; + F32 indices_ratio = 0; + F32 triangle_limit = 0; + F32 lod_error_threshold = 100; + F32 decimation = 3.f; + + // If requesting a single lod + if (requested_lod > -1 && requested_lod < NUM_LOD) { - lod_mode = iface->getFirstSelectedIndex(); - } + LLCtrlSelectionInterface* iface = mFMP->childGetSelectionInterface("lod_mode_" + lod_name[requested_lod]); + if (iface) + { + lod_mode = iface->getFirstSelectedIndex(); + } - lod_error_threshold = mFMP->childGetValue("lod_error_threshold_" + lod_name[lod]).asReal(); + if (lod_mode == LIMIT_TRIANGLES) + { + if (!enforce_tri_limit && lod_mode == LIMIT_TRIANGLES) + { + triangle_limit = base_triangle_count; + // reset to default value for this lod + for (S32 j = LLModel::LOD_HIGH; j > requested_lod; --j) + { + triangle_limit /= decimation; + indices_ratio /= decimation; + } + } + else + { + // meshoptimizer doesn't use triangle limit, it uses indices limit, so convert it to ratio - if (lod != -1) - { - mRequestedLoDMode[lod] = lod_mode; - } + // UI spacifies limit for all models of single lod + triangle_limit = mFMP->childGetValue("lod_triangle_limit_" + lod_name[requested_lod]).asInteger(); - S32 limit = -1; - if (lod_mode == LIMIT_TRIANGLES) + // calculate aproximate ratio + indices_ratio = (F32)triangle_limit / (F32)base_triangle_count; + } + } + else + { + lod_error_threshold = mFMP->childGetValue("lod_error_threshold_" + lod_name[requested_lod]).asReal(); + } + } + else { - limit = mFMP->childGetValue("lod_triangle_limit_" + lod_name[lod]).asInteger(); - //convert from "scene wide" to "non-instanced" triangle limit - limit = (S32)((F32)limit*triangle_ratio); + // we are genrating all lods and each lod will get own indices_ratio + indices_ratio = 1; + triangle_limit = base_triangle_count; } - // Glod regenerates vertex buffer at this stage + mMaxTriangleLimit = base_triangle_count; + + // TODO: Glod regenerates vertex buffer at this stage + // check why, it might be needed to regenerate buffer as well // Build models S32 start = LLModel::LOD_HIGH; S32 end = 0; - S32 decimation = 3; - if (lod != -1) + if (requested_lod != -1) { - start = lod; - end = lod; + start = requested_lod; + end = requested_lod; } - mMaxTriangleLimit = base_triangle_count; + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + if (shader) + { + shader->unbind(); + } for (S32 lod = start; lod >= end; --lod) { - if (lod == -1) + if (requested_lod == -1) { + // we are genrating all lods and each lod gets own indices_ratio if (lod < start) { - triangle_count /= decimation; - } - } - else - { - if (enforce_tri_limit) - { - triangle_count = limit; - } - else - { - for (S32 j = LLModel::LOD_HIGH; j > lod; --j) - { - triangle_count /= decimation; - } + indices_ratio /= decimation; + triangle_limit /= decimation; } } + mRequestedTriangleCount[lod] = triangle_limit; + mRequestedErrorThreshold[lod] = lod_error_threshold; + mRequestedLoDMode[requested_lod] = lod_mode; + mModel[lod].clear(); mModel[lod].resize(mBaseModel.size()); mVertexBuffer[lod].clear(); - mRequestedTriangleCount[lod] = (S32)((F32)triangle_count / triangle_ratio); - mRequestedErrorThreshold[lod] = lod_error_threshold; for (U32 mdl_idx = 0; mdl_idx < mBaseModel.size(); ++mdl_idx) { @@ -3718,20 +3720,30 @@ void LLModelPreview::onLODMeshOptimizerParamCommit(S32 lod, bool enforce_tri_lim // todo: run generateShadowIndexBuffer, at some stage, potentially inside simplify - F32 error_code = 0; - LLMeshOptimizer::simplify(&output[0], - &face.mIndices[0], - num_indices, - &face.mPositions[0], - face.mNumVertices, - triangle_count * 3, //todo: indices limit, not triangles limit*3 - lod_error_threshold, - &error_code); + F32 result_code = 0; // how far from original the model is + S32 new_indices = LLMeshOptimizer::simplify(&output[0], + face.mIndices, + num_indices, + &face.mPositions[0], + face.mNumVertices, + num_indices * indices_ratio, + lod_error_threshold, + &result_code); - // todo: copy result into face - } + LLVolumeFace &new_face = target_model->getVolumeFace(face_idx); + + // Copy old values + // todo: no point copying faces? + new_face = face; - LL_WARNS() << "WORK IN PROGRESS" << LL_ENDL; + // Assign new values + S32 idx_size = (new_indices * sizeof(U16) + 0xF) & ~0xF; + LLVector4a::memcpyNonAliased16((F32*)new_face.mIndices, (F32*)(&output[0]), idx_size); + new_face.mNumIndices = new_indices; + + // clear unused values + new_face.optimize(); + } //blind copy skin weights and just take closest skin weight to point on //decimated mesh for now (auto-generating LODs with skin weights is still a bit @@ -3739,6 +3751,7 @@ void LLModelPreview::onLODMeshOptimizerParamCommit(S32 lod, bool enforce_tri_lim target_model->mPosition = base->mPosition; target_model->mSkinWeights = base->mSkinWeights; target_model->mSkinInfo = base->mSkinInfo; + //copy material list target_model->mMaterialList = base->mMaterialList; @@ -3774,6 +3787,11 @@ void LLModelPreview::onLODMeshOptimizerParamCommit(S32 lod, bool enforce_tri_lim mResourceCost = calcResourceCost(); + LLVertexBuffer::unbind(); + if (shader) + { + shader->bind(); + } refresh(); } |