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.cpp345
1 files changed, 213 insertions, 132 deletions
diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp
index ac41558721..3e8b7f72e7 100644
--- a/indra/newview/llmodelpreview.cpp
+++ b/indra/newview/llmodelpreview.cpp
@@ -68,6 +68,8 @@
#include "lltabcontainer.h"
#include "lltextbox.h"
+#include <filesystem>
+
#include <boost/algorithm/string.hpp>
bool LLModelPreview::sIgnoreLoadedCallback = false;
@@ -93,7 +95,7 @@ const F32 SKIN_WEIGHT_CAMERA_DISTANCE = 16.f;
LLViewerFetchedTexture* bindMaterialDiffuseTexture(const LLImportMaterial& material)
{
- LLViewerFetchedTexture *texture = LLViewerTextureManager::getFetchedTexture(material.getDiffuseMap(), FTT_DEFAULT, TRUE, LLGLTexture::BOOST_PREVIEW);
+ LLViewerFetchedTexture *texture = LLViewerTextureManager::getFetchedTexture(material.getDiffuseMap(), FTT_DEFAULT, true, LLGLTexture::BOOST_PREVIEW);
if (texture)
{
@@ -132,25 +134,17 @@ std::string getLodSuffix(S32 lod)
void FindModel(LLModelLoader::scene& scene, const std::string& name_to_match, LLModel*& baseModelOut, LLMatrix4& matOut)
{
- LLModelLoader::scene::iterator base_iter = scene.begin();
- bool found = false;
- while (!found && (base_iter != scene.end()))
+ for (auto scene_iter = scene.begin(); scene_iter != scene.end(); scene_iter++)
{
- matOut = base_iter->first;
-
- LLModelLoader::model_instance_list::iterator base_instance_iter = base_iter->second.begin();
- while (!found && (base_instance_iter != base_iter->second.end()))
+ for (auto model_iter = scene_iter->second.begin(); model_iter != scene_iter->second.end(); model_iter++)
{
- LLModelInstance& base_instance = *base_instance_iter++;
- LLModel* base_model = base_instance.mModel;
-
- if (base_model && (base_model->mLabel == name_to_match))
+ if (model_iter->mModel && (model_iter->mModel->mLabel == name_to_match))
{
- baseModelOut = base_model;
+ baseModelOut = model_iter->mModel;
+ matOut = scene_iter->first;
return;
}
}
- base_iter++;
}
}
@@ -159,7 +153,7 @@ void FindModel(LLModelLoader::scene& scene, const std::string& name_to_match, LL
//-----------------------------------------------------------------------------
LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp)
- : LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE), LLMutex()
+ : LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, false), LLMutex()
, mLodsQuery()
, mLodsWithParsingError()
, mPelvisZOffset(0.0f)
@@ -173,7 +167,7 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp)
, mHasDegenerate(false)
, mImporterDebug(LLCachedControl<bool>(gSavedSettings, "ImporterDebug", false))
{
- mNeedsUpdate = TRUE;
+ mNeedsUpdate = true;
mCameraDistance = 0.f;
mCameraYaw = 0.f;
mCameraPitch = 0.f;
@@ -210,9 +204,12 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp)
LLModelPreview::~LLModelPreview()
{
+ LLMutexLock lock(this);
+
if (mModelLoader)
{
mModelLoader->shutdown();
+ mModelLoader = NULL;
}
if (mPreviewAvatar)
@@ -240,7 +237,7 @@ void LLModelPreview::updateDimentionsAndOffsets()
std::set<LLModel*> accounted;
- mPelvisZOffset = mFMP ? mFMP->childGetValue("pelvis_offset").asReal() : 3.0f;
+ mPelvisZOffset = mFMP ? (F32)mFMP->childGetValue("pelvis_offset").asReal() : 3.0f;
if (mFMP && mFMP->childGetValue("upload_joints").asBoolean())
{
@@ -260,7 +257,7 @@ void LLModelPreview::updateDimentionsAndOffsets()
accounted.insert(instance.mModel);
// update instance skin info for each lods pelvisZoffset
- for (int j = 0; j<LLModel::NUM_LODS; ++j)
+ for (int j = 0; j < LLModel::NUM_LODS; ++j)
{
if (instance.mLOD[j])
{
@@ -270,7 +267,7 @@ void LLModelPreview::updateDimentionsAndOffsets()
}
}
- F32 scale = mFMP ? mFMP->childGetValue("import_scale").asReal()*2.f : 2.f;
+ F32 scale = mFMP ? (F32)mFMP->childGetValue("import_scale").asReal()*2.f : 2.f;
mDetailsSignal((F32)(mPreviewScale[0] * scale), (F32)(mPreviewScale[1] * scale), (F32)(mPreviewScale[2] * scale));
@@ -291,17 +288,17 @@ void LLModelPreview::rebuildUploadData()
LLSpinCtrl* scale_spinner = mFMP->getChild<LLSpinCtrl>("import_scale");
- F32 scale = scale_spinner->getValue().asReal();
+ F32 scale = (F32)scale_spinner->getValue().asReal();
LLMatrix4 scale_mat;
scale_mat.initScale(LLVector3(scale, scale, scale));
F32 max_scale = 0.f;
- BOOL legacyMatching = gSavedSettings.getBOOL("ImporterLegacyMatching");
+ bool legacyMatching = gSavedSettings.getBOOL("ImporterLegacyMatching");
U32 load_state = 0;
- for (LLModelLoader::scene::iterator iter = mBaseScene.begin(); iter != mBaseScene.end(); ++iter)
+ for (auto iter = mBaseScene.begin(); iter != mBaseScene.end(); ++iter)
{ //for each transform in scene
LLMatrix4 mat = iter->first;
@@ -320,9 +317,9 @@ void LLModelPreview::rebuildUploadData()
mat *= scale_mat;
- for (LLModelLoader::model_instance_list::iterator model_iter = iter->second.begin(); model_iter != iter->second.end();)
+ for (auto model_iter = iter->second.begin(); model_iter != iter->second.end(); ++model_iter)
{ // for each instance with said transform applied
- LLModelInstance instance = *model_iter++;
+ LLModelInstance instance = *model_iter;
LLModel* base_model = instance.mModel;
@@ -541,6 +538,32 @@ void LLModelPreview::rebuildUploadData()
}
instance.mTransform = mat;
mUploadData.push_back(instance);
+
+ // if uploading textures, make sure textures are present
+ if (mFMP->childGetValue("upload_textures").asBoolean()) // too early to cheack if still loading
+ {
+ for (auto& mat_pair : instance.mMaterial)
+ {
+ LLImportMaterial& material = mat_pair.second;
+
+ if (material.mDiffuseMapFilename.size())
+ {
+ LLViewerFetchedTexture* texture = LLMeshUploadThread::FindViewerTexture(material);
+ if (texture && texture->isMissingAsset())
+ {
+ // in case user provided a missing file later
+ texture->setIsMissingAsset(false);
+ texture->setLoadedCallback(LLModelPreview::textureLoadedCallback, 0, true, false, this, NULL, false);
+ texture->forceToSaveRawImage(0, F32_MAX);
+ texture->updateFetch();
+ if (mModelLoader)
+ {
+ mModelLoader->mNumOfFetchingTextures++;
+ }
+ }
+ }
+ }
+ }
}
}
@@ -667,7 +690,7 @@ void LLModelPreview::saveUploadData(const std::string& filename,
save_skinweights,
save_joint_positions,
lock_scale_if_joint_position,
- FALSE, TRUE, instance.mModel->mSubmodelID);
+ false, true, instance.mModel->mSubmodelID);
data["mesh"][instance.mModel->mLocalID] = str.str();
}
@@ -882,7 +905,7 @@ void LLModelPreview::clearIncompatible(S32 lod)
{
mBaseModel = mModel[lod];
mBaseScene = mScene[lod];
- mVertexBuffer[5].clear();
+ mVertexBuffer[LLModel::NUM_LODS].clear();
replaced_base_model = true;
}
}
@@ -1067,6 +1090,29 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)
{ //only replace given LoD
mModel[loaded_lod] = mModelLoader->mModelList;
mScene[loaded_lod] = mModelLoader->mScene;
+
+ // Duplicate the model if it is an internal bounding box model
+ if (loaded_lod == LLModel::LOD_PHYSICS &&
+ mBaseModel.size() > 1 && // This makes sense for multiple models only
+ mModelLoader->mModelList.size() == 1 && // Just on the off-chance
+ mModelLoader->mScene.size() == 1 && // Just on the off-chance
+ std::filesystem::path(mModelLoader->mFilename).filename() == "cube.dae")
+ {
+ // Create a copy of the just loaded model for each model in mBaseModel
+ const LLModel* origin = mModelLoader->mModelList.front();
+ const LLModelInstance& mi = mModelLoader->mScene.begin()->second.front();
+ for (U32 i = 1; i < mBaseModel.size(); ++i)
+ {
+ LLPointer<LLModel> copy(new LLModel(origin->getParams(), origin->getDetail()));
+ copy->mLabel = origin->mLabel;
+ copy->copyVolumeFaces(origin);
+ copy->mPosition = origin->mPosition;
+ copy->mMaterialList = origin->mMaterialList;
+ mModel[loaded_lod].push_back(copy);
+ mScene[loaded_lod][mi.mTransform].push_back(LLModelInstance(copy, copy->mLabel, mi.mTransform, mi.mMaterial));
+ }
+ }
+
mVertexBuffer[loaded_lod].clear();
setPreviewLOD(loaded_lod);
@@ -1081,7 +1127,7 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)
mBaseModel = mModel[loaded_lod];
mBaseScene = mScene[loaded_lod];
- mVertexBuffer[5].clear();
+ mVertexBuffer[LLModel::NUM_LODS].clear();
}
else
{
@@ -1093,18 +1139,18 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)
mDefaultPhysicsShapeP = out_model;
mWarnOfUnmatchedPhyicsMeshes = true;
}
- BOOL legacyMatching = gSavedSettings.getBOOL("ImporterLegacyMatching");
+ bool legacyMatching = gSavedSettings.getBOOL("ImporterLegacyMatching");
if (!legacyMatching)
{
if (!mBaseModel.empty())
{
- BOOL name_based = FALSE;
- BOOL has_submodels = FALSE;
+ bool name_based = false;
+ bool has_submodels = false;
for (U32 idx = 0; idx < mBaseModel.size(); ++idx)
{
if (mBaseModel[idx]->mSubmodelID)
{ // don't do index-based renaming when the base model has submodels
- has_submodels = TRUE;
+ has_submodels = true;
if (mImporterDebug)
{
std::ostringstream out;
@@ -1125,12 +1171,12 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)
FindModel(mBaseScene, loaded_name, found_model, transform);
if (found_model)
{ // don't rename correctly named models (even if they are placed in a wrong order)
- name_based = TRUE;
+ name_based = true;
}
if (mModel[loaded_lod][idx]->mSubmodelID)
{ // don't rename the models when loaded LOD model has submodels
- has_submodels = TRUE;
+ has_submodels = true;
}
}
@@ -1164,6 +1210,17 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)
LLFloaterModelPreview::addStringToLog(out, false);
}
mModel[loaded_lod][idx]->mLabel = name;
+ // Rename the correspondent instance as well
+ [&]()
+ {
+ for (auto& p : mScene[loaded_lod])
+ for (auto& i : p.second)
+ if (i.mModel == mModel[loaded_lod][idx])
+ {
+ i.mLabel = name;
+ return;
+ }
+ }();
}
}
}
@@ -1186,7 +1243,7 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)
{
if (!mBaseModel.empty())
{
- const std::string& model_name = mBaseModel[0]->getName();
+ std::string model_name = mBaseModel.front()->getName();
LLLineEditor* description_form = mFMP->getChild<LLLineEditor>("description_form");
if (description_form->getText().empty())
{
@@ -1207,6 +1264,8 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)
void LLModelPreview::resetPreviewTarget()
{
+ LLMutexLock lock(this);
+
if (mModelLoader)
{
mPreviewTarget = (mModelLoader->mExtents[0] + mModelLoader->mExtents[1]) * 0.5f;
@@ -1228,7 +1287,7 @@ void LLModelPreview::generateNormals()
return;
}
- F32 angle_cutoff = mFMP->childGetValue("crease_angle").asReal();
+ F32 angle_cutoff = (F32)mFMP->childGetValue("crease_angle").asReal();
mRequestedCreaseAngle[which_lod] = angle_cutoff;
@@ -1252,7 +1311,7 @@ void LLModelPreview::generateNormals()
(*it)->generateNormals(angle_cutoff);
}
- mVertexBuffer[5].clear();
+ mVertexBuffer[LLModel::NUM_LODS].clear();
}
bool perform_copy = mModelFacesCopy[which_lod].empty();
@@ -1326,7 +1385,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
S32 size_indices = 0;
S32 size_vertices = 0;
- for (U32 face_idx = 0; face_idx < base_model->getNumVolumeFaces(); ++face_idx)
+ for (S32 face_idx = 0; face_idx < base_model->getNumVolumeFaces(); ++face_idx)
{
const LLVolumeFace &face = base_model->getVolumeFace(face_idx);
size_indices += face.mNumIndices;
@@ -1352,7 +1411,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
S32 combined_positions_shift = 0;
S32 indices_idx_shift = 0;
S32 combined_indices_shift = 0;
- for (U32 face_idx = 0; face_idx < base_model->getNumVolumeFaces(); ++face_idx)
+ for (S32 face_idx = 0; face_idx < base_model->getNumVolumeFaces(); ++face_idx)
{
const LLVolumeFace &face = base_model->getVolumeFace(face_idx);
@@ -1427,7 +1486,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
target_indices = 3;
}
- size_new_indices = LLMeshOptimizer::simplifyU32(
+ size_new_indices = (S32)LLMeshOptimizer::simplifyU32(
output_indices,
source_indices,
size_indices,
@@ -1477,7 +1536,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
S32 valid_faces = 0;
// Crude method to copy indices back into face
- for (U32 face_idx = 0; face_idx < base_model->getNumVolumeFaces(); ++face_idx)
+ for (S32 face_idx = 0; face_idx < base_model->getNumVolumeFaces(); ++face_idx)
{
const LLVolumeFace &face = base_model->getVolumeFace(face_idx);
@@ -1495,7 +1554,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
// Copy relevant indices and vertices
for (S32 i = 0; i < size_new_indices; ++i)
{
- U32 idx = output_indices[i];
+ S32 idx = (S32)output_indices[i];
if ((i % 3) == 0)
{
@@ -1524,7 +1583,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
// U16 vertices overflow shouldn't happen, but just in case
size_new_indices = 0;
valid_faces = 0;
- for (U32 face_idx = 0; face_idx < base_model->getNumVolumeFaces(); ++face_idx)
+ for (S32 face_idx = 0; face_idx < base_model->getNumVolumeFaces(); ++face_idx)
{
genMeshOptimizerPerFace(base_model, target_model, face_idx, indices_decimator, error_threshold, simplification_mode);
const LLVolumeFace &face = target_model->getVolumeFace(face_idx);
@@ -1668,7 +1727,7 @@ F32 LLModelPreview::genMeshOptimizerPerFace(LLModel *base_model, LLModel *target
target_indices = 3;
}
- size_new_indices = LLMeshOptimizer::simplify(
+ size_new_indices = (S32)LLMeshOptimizer::simplify(
output_indices,
source_indices,
size_indices,
@@ -1789,7 +1848,7 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
{
if (!enforce_tri_limit)
{
- triangle_limit = base_triangle_count;
+ triangle_limit = (F32)base_triangle_count;
// reset to default value for this lod
F32 pw = pow((F32)decimation, (F32)(LLModel::LOD_HIGH - which_lod));
@@ -1799,7 +1858,7 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
{
// UI spacifies limit for all models of single lod
- triangle_limit = mFMP->childGetValue("lod_triangle_limit_" + lod_name[which_lod]).asInteger();
+ triangle_limit = (F32)mFMP->childGetValue("lod_triangle_limit_" + lod_name[which_lod]).asReal();
}
// meshoptimizer doesn't use triangle limit, it uses indices limit, so convert it to aproximate ratio
@@ -1809,14 +1868,14 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
else
{
// UI shows 0 to 100%, but meshoptimizer works with 0 to 1
- lod_error_threshold = mFMP->childGetValue("lod_error_threshold_" + lod_name[which_lod]).asReal() / 100.f;
+ lod_error_threshold = (F32)mFMP->childGetValue("lod_error_threshold_" + lod_name[which_lod]).asReal() / 100.f;
}
}
else
{
// we are genrating all lods and each lod will get own indices_decimator
indices_decimator = 1;
- triangle_limit = base_triangle_count;
+ triangle_limit = (F32)base_triangle_count;
}
mMaxTriangleLimit = base_triangle_count;
@@ -1844,7 +1903,7 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
}
}
- mRequestedTriangleCount[lod] = triangle_limit;
+ mRequestedTriangleCount[lod] = (S32)triangle_limit;
mRequestedErrorThreshold[lod] = lod_error_threshold * 100;
mRequestedLoDMode[lod] = lod_mode;
@@ -1870,7 +1929,7 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
LLModel* target_model = mModel[lod][mdl_idx];
// carry over normalized transform into simplified model
- for (int i = 0; i < base->getNumVolumeFaces(); ++i)
+ for (S32 i = 0; i < base->getNumVolumeFaces(); ++i)
{
LLVolumeFace& src = base->getVolumeFace(i);
LLVolumeFace& dst = target_model->getVolumeFace(i);
@@ -1884,7 +1943,7 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
if (model_meshopt_mode == MESH_OPTIMIZER_PRECISE)
{
// Run meshoptimizer for each face
- for (U32 face_idx = 0; face_idx < base->getNumVolumeFaces(); ++face_idx)
+ for (S32 face_idx = 0; face_idx < base->getNumVolumeFaces(); ++face_idx)
{
F32 res = genMeshOptimizerPerFace(base, target_model, face_idx, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_FULL);
if (res < 0)
@@ -1900,7 +1959,7 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
if (model_meshopt_mode == MESH_OPTIMIZER_SLOPPY)
{
// Run meshoptimizer for each face
- for (U32 face_idx = 0; face_idx < base->getNumVolumeFaces(); ++face_idx)
+ for (S32 face_idx = 0; face_idx < base->getNumVolumeFaces(); ++face_idx)
{
if (genMeshOptimizerPerFace(base, target_model, face_idx, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_NO_TOPOLOGY) < 0)
{
@@ -2094,7 +2153,7 @@ void LLModelPreview::updateStatusMessages()
S32 total_verts[LLModel::NUM_LODS];
S32 total_submeshes[LLModel::NUM_LODS];
- for (U32 i = 0; i < LLModel::NUM_LODS - 1; i++)
+ for (U32 i = 0; i < LLModel::NUM_LODS; i++)
{
total_tris[i] = 0;
total_verts[i] = 0;
@@ -2247,7 +2306,7 @@ void LLModelPreview::updateStatusMessages()
mModelNoErrors = true;
const U32 lod_high = LLModel::LOD_HIGH;
- U32 high_submodel_count = mModel[lod_high].size() - countRootModels(mModel[lod_high]);
+ U32 high_submodel_count = static_cast<U32>(mModel[lod_high].size()) - countRootModels(mModel[lod_high]);
for (S32 lod = 0; lod <= lod_high; ++lod)
{
@@ -2344,7 +2403,7 @@ void LLModelPreview::updateStatusMessages()
//warn if hulls have more than 256 points in them
- BOOL physExceededVertexLimit = FALSE;
+ bool physExceededVertexLimit = false;
for (U32 i = 0; mModelNoErrors && i < mModel[LLModel::LOD_PHYSICS].size(); ++i)
{
LLModel* mdl = mModel[LLModel::LOD_PHYSICS][i];
@@ -2355,7 +2414,7 @@ void LLModelPreview::updateStatusMessages()
{
if (mdl->mPhysics.mHull[j].size() > 256)
{
- physExceededVertexLimit = TRUE;
+ physExceededVertexLimit = true;
LL_INFOS() << "Physical model " << mdl->mLabel << " exceeds vertex per hull limitations." << LL_ENDL;
break;
}
@@ -2398,12 +2457,16 @@ void LLModelPreview::updateStatusMessages()
}
}
- if (mModelNoErrors && mModelLoader)
+ if (mModelNoErrors)
{
- if (!mModelLoader->areTexturesReady() && mFMP->childGetValue("upload_textures").asBoolean())
+ LLMutexLock lock(this);
+ if (mModelLoader)
{
- // Some textures are still loading, prevent upload until they are done
- mModelNoErrors = false;
+ if (!mModelLoader->areTexturesReady() && mFMP->childGetValue("upload_textures").asBoolean())
+ {
+ // Some textures are still loading, prevent upload until they are done
+ mModelNoErrors = false;
+ }
}
}
@@ -2446,10 +2509,10 @@ void LLModelPreview::updateStatusMessages()
if (!decomp.empty())
{
- phys_hulls += decomp.size();
+ phys_hulls += static_cast<S32>(decomp.size());
for (U32 i = 0; i < decomp.size(); ++i)
{
- phys_points += decomp[i].size();
+ phys_points += static_cast<S32>(decomp[i].size());
}
}
else
@@ -2686,7 +2749,7 @@ void LLModelPreview::updateLodControls(S32 lod)
LLSpinCtrl* threshold = mFMP->getChild<LLSpinCtrl>("lod_error_threshold_" + lod_name[lod]);
LLSpinCtrl* limit = mFMP->getChild<LLSpinCtrl>("lod_triangle_limit_" + lod_name[lod]);
- limit->setMaxValue(mMaxTriangleLimit);
+ limit->setMaxValue((F32)mMaxTriangleLimit);
limit->forceSetValue(mRequestedTriangleCount[lod]);
threshold->forceSetValue(mRequestedErrorThreshold[lod]);
@@ -2698,8 +2761,8 @@ void LLModelPreview::updateLodControls(S32 lod)
limit->setVisible(true);
threshold->setVisible(false);
- limit->setMaxValue(mMaxTriangleLimit);
- limit->setIncrement(llmax((U32)1, mMaxTriangleLimit / 32));
+ limit->setMaxValue((F32)mMaxTriangleLimit);
+ limit->setIncrement((F32)llmax((U32)1, mMaxTriangleLimit / 32));
}
else
{
@@ -2732,10 +2795,10 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
{
LLModelLoader::model_list* model = NULL;
- if (lod < 0 || lod > 4)
+ if (lod < 0 || lod >= LLModel::NUM_LODS)
{
model = &mBaseModel;
- lod = 5;
+ lod = LLModel::NUM_LODS;
}
else
{
@@ -2766,9 +2829,9 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
LLMatrix4a mat_normal;
if (skinned)
{
- glh::matrix4f m((F32*)mdl->mSkinInfo.mBindShapeMatrix.getF32ptr());
- m = m.inverse().transpose();
- mat_normal.loadu(m.m);
+ glm::mat4 m = glm::make_mat4((F32*)mdl->mSkinInfo.mBindShapeMatrix.getF32ptr());
+ m = glm::transpose(glm::inverse(m));
+ mat_normal.loadu(glm::value_ptr(m));
}
S32 num_faces = mdl->getNumVolumeFaces();
@@ -2972,8 +3035,9 @@ void LLModelPreview::loadedCallback(
S32 lod,
void* opaque)
{
- LLModelPreview* pPreview = static_cast< LLModelPreview* >(opaque);
- if (pPreview && !LLModelPreview::sIgnoreLoadedCallback)
+ LLModelPreview* pPreview = static_cast<LLModelPreview*>(opaque);
+ LLMutexLock lock(pPreview);
+ if (pPreview && pPreview->mModelLoader && !LLModelPreview::sIgnoreLoadedCallback)
{
// Load loader's warnings into floater's log tab
const LLSD out = pPreview->mModelLoader->logOut();
@@ -2994,7 +3058,9 @@ void LLModelPreview::loadedCallback(
}
const LLVOAvatar* avatarp = pPreview->getPreviewAvatar();
- if (avatarp) { // set up ground plane for possible rendering
+ if (avatarp && avatarp->mRoot && avatarp->mDrawable)
+ {
+ // set up ground plane for possible rendering
const LLVector3 root_pos = avatarp->mRoot->getPosition();
const LLVector4a* ext = avatarp->mDrawable->getSpatialExtents();
const LLVector4a min = ext[0], max = ext[1];
@@ -3071,8 +3137,15 @@ U32 LLModelPreview::loadTextures(LLImportMaterial& material, void* opaque)
material.mOpaqueData = new LLPointer< LLViewerFetchedTexture >;
LLPointer< LLViewerFetchedTexture >& tex = (*reinterpret_cast< LLPointer< LLViewerFetchedTexture > * >(material.mOpaqueData));
- tex = LLViewerTextureManager::getFetchedTextureFromUrl("file://" + LLURI::unescape(material.mDiffuseMapFilename), FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_PREVIEW);
- tex->setLoadedCallback(LLModelPreview::textureLoadedCallback, 0, TRUE, FALSE, opaque, NULL, FALSE);
+ tex = LLViewerTextureManager::getFetchedTextureFromUrl("file://" + LLURI::unescape(material.mDiffuseMapFilename), FTT_LOCAL_FILE, true, LLGLTexture::BOOST_PREVIEW);
+ if (tex->getDiscardLevel() < tex->getMaxDiscardLevel())
+ {
+ // file was loaded previosly, reload image to get potential changes
+ tex->clearFetchedResults();
+ }
+ // Todo: might cause a crash if preview gets closed before we get the callback.
+ // Use a callback list or guard callback in some way
+ tex->setLoadedCallback(LLModelPreview::textureLoadedCallback, 0, true, false, opaque, NULL, false);
tex->forceToSaveRawImage(0, F32_MAX);
material.setDiffuseMap(tex->getID()); // record tex ID
return 1;
@@ -3124,19 +3197,19 @@ void LLModelPreview::addEmptyFace(LLModel* pTarget)
//-----------------------------------------------------------------------------
// Todo: we shouldn't be setting all those UI elements on render.
// Note: Render happens each frame with skinned avatars
-BOOL LLModelPreview::render()
+bool LLModelPreview::render()
{
assert_main_thread();
LLMutexLock lock(this);
- mNeedsUpdate = FALSE;
+ mNeedsUpdate = false;
- bool edges = mViewOption["show_edges"];
- bool joint_overrides = mViewOption["show_joint_overrides"];
- bool joint_positions = mViewOption["show_joint_positions"];
- bool skin_weight = mViewOption["show_skin_weight"];
- bool textures = mViewOption["show_textures"];
- bool physics = mViewOption["show_physics"];
+ bool show_edges = mViewOption["show_edges"];
+ bool show_joint_overrides = mViewOption["show_joint_overrides"];
+ bool show_joint_positions = mViewOption["show_joint_positions"];
+ bool show_skin_weight = mViewOption["show_skin_weight"];
+ bool show_textures = mViewOption["show_textures"];
+ bool show_physics = mViewOption["show_physics"];
S32 width = getWidth();
S32 height = getHeight();
@@ -3153,7 +3226,7 @@ BOOL LLModelPreview::render()
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.pushMatrix();
gGL.loadIdentity();
- gGL.ortho(0.0f, width, 0.0f, height, -1.0f, 1.0f);
+ gGL.ortho(0.0f, (F32)width, 0.0f, (F32)height, -1.0f, 1.0f);
gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.pushMatrix();
@@ -3213,15 +3286,15 @@ BOOL LLModelPreview::render()
fmp->childSetValue("upload_skin", true);
mFirstSkinUpdate = false;
upload_skin = true;
- skin_weight = true;
+ show_skin_weight = true;
mViewOption["show_skin_weight"] = true;
}
fmp->enableViewOption("show_skin_weight");
- fmp->setViewOptionEnabled("show_joint_overrides", skin_weight);
- fmp->setViewOptionEnabled("show_joint_positions", skin_weight);
+ fmp->setViewOptionEnabled("show_joint_overrides", show_skin_weight);
+ fmp->setViewOptionEnabled("show_joint_positions", show_skin_weight);
mFMP->childEnable("upload_skin");
- mFMP->childSetValue("show_skin_weight", skin_weight);
+ mFMP->childSetValue("show_skin_weight", show_skin_weight);
}
else if ((flags & LEGACY_RIG_FLAG_TOO_MANY_JOINTS) > 0)
@@ -3244,11 +3317,12 @@ BOOL LLModelPreview::render()
fmp->disableViewOption("show_joint_overrides");
fmp->disableViewOption("show_joint_positions");
- skin_weight = false;
+ show_skin_weight = false;
mFMP->childSetValue("show_skin_weight", false);
- fmp->setViewOptionEnabled("show_skin_weight", skin_weight);
+ fmp->setViewOptionEnabled("show_skin_weight", show_skin_weight);
}
}
+ //if (this) return TRUE;
if (upload_skin && !has_skin_weights)
{ //can't upload skin weights if model has no skin weights
@@ -3291,7 +3365,7 @@ BOOL LLModelPreview::render()
mFMP->childSetEnabled("upload_joints", upload_skin);
}
- F32 explode = mFMP->childGetValue("physics_explode").asReal();
+ F32 explode = (F32)mFMP->childGetValue("physics_explode").asReal();
LLGLDepthTest gls_depth(GL_TRUE); // SL-12781 re-enable z-buffer for 3D model preview
@@ -3311,7 +3385,7 @@ BOOL LLModelPreview::render()
F32 z_near = 0.001f;
F32 z_far = mCameraDistance*10.0f + mPreviewScale.magVec() + mCameraOffset.magVec();
- if (skin_weight)
+ if (show_skin_weight)
{
target_pos = getPreviewAvatar()->getPositionAgent() + offset;
z_near = 0.01f;
@@ -3321,7 +3395,7 @@ BOOL LLModelPreview::render()
refresh();
}
- gObjectPreviewProgram.bind(skin_weight);
+ gObjectPreviewProgram.bind(show_skin_weight);
gGL.loadIdentity();
gPipeline.enableLightsPreview();
@@ -3330,7 +3404,7 @@ BOOL LLModelPreview::render()
LLQuaternion(mCameraYaw, LLVector3::z_axis);
LLQuaternion av_rot = camera_rot;
- F32 camera_distance = skin_weight ? SKIN_WEIGHT_CAMERA_DISTANCE : mCameraDistance;
+ F32 camera_distance = show_skin_weight ? SKIN_WEIGHT_CAMERA_DISTANCE : mCameraDistance;
LLViewerCamera::getInstance()->setOriginAndLookAt(
target_pos + ((LLVector3(camera_distance, 0.f, 0.f) + offset) * av_rot), // camera
LLVector3::z_axis, // up
@@ -3339,16 +3413,16 @@ BOOL LLModelPreview::render()
z_near = llclamp(z_far * 0.001f, 0.001f, 0.1f);
- LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, width, height, FALSE, z_near, z_far);
+ LLViewerCamera::getInstance()->setPerspective(false, mOrigin.mX, mOrigin.mY, width, height, false, z_near, z_far);
stop_glerror();
gGL.pushMatrix();
gGL.color4fv(PREVIEW_EDGE_COL.mV);
- if (!mBaseModel.empty() && mVertexBuffer[5].empty())
+ if (!mBaseModel.empty() && mVertexBuffer[LLModel::NUM_LODS].empty())
{
- genBuffers(-1, skin_weight);
+ genBuffers(-1, show_skin_weight);
//genBuffers(3);
}
@@ -3363,26 +3437,26 @@ BOOL LLModelPreview::render()
if (!vb_vec.empty())
{
const LLVertexBuffer* buff = vb_vec[0];
- regen = buff->hasDataType(LLVertexBuffer::TYPE_WEIGHT4) != skin_weight;
+ regen = buff->hasDataType(LLVertexBuffer::TYPE_WEIGHT4) != show_skin_weight;
}
else
{
LL_INFOS() << "Vertex Buffer[" << mPreviewLOD << "]" << " is EMPTY!!!" << LL_ENDL;
- regen = TRUE;
+ regen = true;
}
}
if (regen)
{
- genBuffers(mPreviewLOD, skin_weight);
+ genBuffers(mPreviewLOD, show_skin_weight);
}
- if (physics && mVertexBuffer[LLModel::LOD_PHYSICS].empty())
+ if (show_physics && mVertexBuffer[LLModel::LOD_PHYSICS].empty())
{
genBuffers(LLModel::LOD_PHYSICS, false);
}
- if (!skin_weight)
+ if (!show_skin_weight)
{
for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
{
@@ -3401,16 +3475,12 @@ BOOL LLModelPreview::render()
gGL.multMatrix((GLfloat*)mat.mMatrix);
- U32 num_models = mVertexBuffer[mPreviewLOD][model].size();
- for (U32 i = 0; i < num_models; ++i)
+ auto num_models = mVertexBuffer[mPreviewLOD][model].size();
+ for (size_t i = 0; i < num_models; ++i)
{
- LLVertexBuffer* buffer = mVertexBuffer[mPreviewLOD][model][i];
-
- buffer->setBuffer();
-
- if (textures)
+ if (show_textures)
{
- int materialCnt = instance.mModel->mMaterialList.size();
+ auto materialCnt = instance.mModel->mMaterialList.size();
if (i < materialCnt)
{
const std::string& binding = instance.mModel->mMaterialList[i];
@@ -3432,10 +3502,16 @@ BOOL LLModelPreview::render()
gGL.diffuseColor4fv(PREVIEW_BASE_COL.mV);
}
+ // Zero this variable for an obligatory buffer initialization
+ // See https://github.com/secondlife/viewer/issues/912
+ LLVertexBuffer::sGLRenderBuffer = 0;
+ LLVertexBuffer* buffer = mVertexBuffer[mPreviewLOD][model][i];
+ buffer->setBuffer();
buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts() - 1, buffer->getNumIndices(), 0);
+
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.diffuseColor4fv(PREVIEW_EDGE_COL.mV);
- if (edges)
+ if (show_edges)
{
glLineWidth(PREVIEW_EDGE_WIDTH);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
@@ -3448,7 +3524,7 @@ BOOL LLModelPreview::render()
gGL.popMatrix();
}
- if (physics)
+ if (show_physics)
{
glClear(GL_DEPTH_BUFFER_BIT);
@@ -3548,15 +3624,17 @@ BOOL LLModelPreview::render()
if (render_mesh)
{
- U32 num_models = mVertexBuffer[LLModel::LOD_PHYSICS][model].size();
+ auto num_models = mVertexBuffer[LLModel::LOD_PHYSICS][model].size();
if (pass > 0){
- for (U32 i = 0; i < num_models; ++i)
+ for (size_t i = 0; i < num_models; ++i)
{
- LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i];
-
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.diffuseColor4fv(PREVIEW_PSYH_FILL_COL.mV);
+ // Zero this variable for an obligatory buffer initialization
+ // See https://github.com/secondlife/viewer/issues/912
+ LLVertexBuffer::sGLRenderBuffer = 0;
+ LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i];
buffer->setBuffer();
buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts() - 1, buffer->getNumIndices(), 0);
@@ -3613,13 +3691,14 @@ BOOL LLModelPreview::render()
if (physics.mHull.empty())
{
- U32 num_models = mVertexBuffer[LLModel::LOD_PHYSICS][model].size();
- for (U32 v = 0; v < num_models; ++v)
+ auto num_models = mVertexBuffer[LLModel::LOD_PHYSICS][model].size();
+ for (size_t v = 0; v < num_models; ++v)
{
+ // Zero this variable for an obligatory buffer initialization
+ // See https://github.com/secondlife/viewer/issues/912
+ LLVertexBuffer::sGLRenderBuffer = 0;
LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][v];
-
buffer->setBuffer();
-
LLStrider<LLVector3> pos_strider;
buffer->getVertexStrider(pos_strider, 0);
LLVector4a* pos = (LLVector4a*)pos_strider.get();
@@ -3681,9 +3760,9 @@ BOOL LLModelPreview::render()
const LLMeshSkinInfo *skin = &model->mSkinInfo;
LLSkinningUtil::initJointNums(&model->mSkinInfo, getPreviewAvatar());// inits skin->mJointNums if nessesary
U32 joint_count = LLSkinningUtil::getMeshJointCount(skin);
- U32 bind_count = skin->mAlternateBindMatrix.size();
+ auto bind_count = skin->mAlternateBindMatrix.size();
- if (joint_overrides
+ if (show_joint_overrides
&& bind_count > 0
&& joint_count == bind_count)
{
@@ -3726,18 +3805,16 @@ BOOL LLModelPreview::render()
}
}
- for (U32 i = 0, e = mVertexBuffer[mPreviewLOD][model].size(); i < e; ++i)
+ for (U32 i = 0, e = static_cast<U32>(mVertexBuffer[mPreviewLOD][model].size()); i < e; ++i)
{
- LLVertexBuffer* buffer = mVertexBuffer[mPreviewLOD][model][i];
-
model->mSkinInfo.updateHash();
LLRenderPass::uploadMatrixPalette(mPreviewAvatar, &model->mSkinInfo);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- if (textures)
+ if (show_textures)
{
- int materialCnt = instance.mModel->mMaterialList.size();
+ auto materialCnt = instance.mModel->mMaterialList.size();
if (i < materialCnt)
{
const std::string& binding = instance.mModel->mMaterialList[i];
@@ -3759,10 +3836,14 @@ BOOL LLModelPreview::render()
gGL.diffuseColor4fv(PREVIEW_BASE_COL.mV);
}
+ // Zero this variable for an obligatory buffer initialization
+ // See https://github.com/secondlife/viewer/issues/912
+ LLVertexBuffer::sGLRenderBuffer = 0;
+ LLVertexBuffer* buffer = mVertexBuffer[mPreviewLOD][model][i];
buffer->setBuffer();
buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0);
- if (edges)
+ if (show_edges)
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.diffuseColor4fv(PREVIEW_EDGE_COL.mV);
@@ -3777,7 +3858,7 @@ BOOL LLModelPreview::render()
}
}
- if (joint_positions)
+ if (show_joint_positions)
{
LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
if (shader)
@@ -3812,7 +3893,7 @@ BOOL LLModelPreview::render()
gGL.popMatrix();
- return TRUE;
+ return true;
}
void LLModelPreview::renderGroundPlane(float z_offset)
@@ -3842,7 +3923,7 @@ void LLModelPreview::renderGroundPlane(float z_offset)
//-----------------------------------------------------------------------------
void LLModelPreview::refresh()
{
- mNeedsUpdate = TRUE;
+ mNeedsUpdate = true;
}
//-----------------------------------------------------------------------------
@@ -3911,12 +3992,12 @@ void LLModelPreview::setPreviewLOD(S32 lod)
//static
void LLModelPreview::textureLoadedCallback(
- BOOL success,
+ bool success,
LLViewerFetchedTexture *src_vi,
LLImageRaw* src,
LLImageRaw* src_aux,
S32 discard_level,
- BOOL final,
+ bool final,
void* userdata)
{
LLModelPreview* preview = (LLModelPreview*)userdata;