summaryrefslogtreecommitdiff
path: root/indra/newview/llfloatermodelpreview.cpp
diff options
context:
space:
mode:
authorBrad Payne (Vir Linden) <vir@lindenlab.com>2010-12-13 17:51:14 -0500
committerBrad Payne (Vir Linden) <vir@lindenlab.com>2010-12-13 17:51:14 -0500
commit27f11d9868bc72e7096ae6266af1c6c9318c545e (patch)
tree12190521b6870891072e312c8b3e8864721aa075 /indra/newview/llfloatermodelpreview.cpp
parentfbab245e487650d6420c9fe33cf07123af12f422 (diff)
parentdd06d42c09e5e1f4b28559059ec8393e53f767a7 (diff)
merge
Diffstat (limited to 'indra/newview/llfloatermodelpreview.cpp')
-rwxr-xr-xindra/newview/llfloatermodelpreview.cpp866
1 files changed, 603 insertions, 263 deletions
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 4992661e92..007f6ee3ed 100755
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -67,7 +67,9 @@
#include "lleconomy.h"
#include "llfocusmgr.h"
#include "llfloaterperms.h"
+#include "lliconctrl.h"
#include "llmatrix4a.h"
+#include "llmenubutton.h"
#include "llmeshrepository.h"
#include "llsdutil_math.h"
#include "lltextbox.h"
@@ -80,17 +82,21 @@
#include "llvoavatarself.h"
#include "pipeline.h"
#include "lluictrlfactory.h"
+#include "llviewermenu.h"
#include "llviewermenufile.h"
#include "llviewerregion.h"
+#include "llviewertexturelist.h"
#include "llstring.h"
#include "llbutton.h"
#include "llcheckboxctrl.h"
#include "llsliderctrl.h"
#include "llspinctrl.h"
+#include "lltoggleablemenu.h"
#include "llvfile.h"
#include "llvfs.h"
+
#include "glod/glod.h"
//static
@@ -102,11 +108,12 @@ const S32 PREVIEW_RESIZE_HANDLE_SIZE = S32(RESIZE_HANDLE_WIDTH * OO_SQRT2) + PRE
const S32 PREVIEW_HPAD = PREVIEW_RESIZE_HANDLE_SIZE;
const S32 PREF_BUTTON_HEIGHT = 16 + 7 + 16;
const S32 PREVIEW_TEXTURE_HEIGHT = 300;
+const S32 NUM_LOD = 4;
void drawBoxOutline(const LLVector3& pos, const LLVector3& size);
-std::string lod_name[] =
+std::string lod_name[NUM_LOD+1] =
{
"lowest",
"low",
@@ -115,7 +122,7 @@ std::string lod_name[] =
"I went off the end of the lod_name array. Me so smart."
};
-std::string lod_triangles_name[] =
+std::string lod_triangles_name[NUM_LOD+1] =
{
"lowest_triangles",
"low_triangles",
@@ -124,7 +131,7 @@ std::string lod_triangles_name[] =
"I went off the end of the lod_triangles_name array. Me so smart."
};
-std::string lod_vertices_name[] =
+std::string lod_vertices_name[NUM_LOD+1] =
{
"lowest_vertices",
"low_vertices",
@@ -132,8 +139,8 @@ std::string lod_vertices_name[] =
"high_vertices",
"I went off the end of the lod_vertices_name array. Me so smart."
};
-
-std::string lod_status_name[] =
+
+std::string lod_status_name[NUM_LOD+1] =
{
"lowest_status",
"low_status",
@@ -142,7 +149,24 @@ std::string lod_status_name[] =
"I went off the end of the lod_status_name array. Me so smart."
};
-std::string lod_label_name[] =
+std::string lod_icon_name[NUM_LOD+1] =
+{
+ "status_icon_lowest",
+ "status_icon_low",
+ "status_icon_medium",
+ "status_icon_high",
+ "I went off the end of the lod_status_name array. Me so smart."
+};
+
+std::string lod_status_image[NUM_LOD+1] =
+{
+ "ModelImport_Status_Good",
+ "ModelImport_Status_Warning",
+ "ModelImport_Status_Error",
+ "I went off the end of the lod_status_image array. Me so smart."
+};
+
+std::string lod_label_name[NUM_LOD+1] =
{
"lowest_label",
"low_label",
@@ -152,7 +176,6 @@ std::string lod_label_name[] =
};
-
bool validate_face(const LLVolumeFace& face)
{
for (U32 i = 0; i < face.mNumIndices; ++i)
@@ -211,24 +234,18 @@ BOOL stop_gloderror()
return FALSE;
}
-class LLMeshFilePicker : public LLFilePickerThread
-{
-public:
- LLFloaterModelPreview* mFMP;
- S32 mLOD;
- LLMeshFilePicker(LLFloaterModelPreview* fmp, S32 lod)
+LLMeshFilePicker::LLMeshFilePicker(LLModelPreview* mp, S32 lod)
: LLFilePickerThread(LLFilePicker::FFLOAD_COLLADA)
{
- mFMP = fmp;
+ mMP = mp;
mLOD = lod;
}
-
- virtual void notify(const std::string& filename)
- {
- mFMP->mModelPreview->loadModel(mFile, mLOD);
- }
-};
+
+void LLMeshFilePicker::notify(const std::string& filename)
+{
+ mMP->loadModel(mFile, mLOD);
+}
//-----------------------------------------------------------------------------
@@ -241,7 +258,6 @@ LLFloater(key)
mLastMouseX = 0;
mLastMouseY = 0;
mGLName = 0;
- mLoading = FALSE;
}
//-----------------------------------------------------------------------------
@@ -254,14 +270,22 @@ BOOL LLFloaterModelPreview::postBuild()
return FALSE;
}
+ setViewOption("show_textures", true);
+
childSetAction("lod_browse", onBrowseLOD, this);
- childSetCommitCallback("lod_triangle_limit", onTriangleLimitCommit, this);
childSetCommitCallback("crease_angle", onGenerateNormalsCommit, this);
childSetCommitCallback("generate_normals", onGenerateNormalsCommit, this);
- childSetCommitCallback("show edges", onShowEdgesCommit, this);
childSetCommitCallback("lod_generate", onAutoFillCommit, this);
+
+ childSetCommitCallback("lod_mode", onLODParamCommit, this);
+ childSetCommitCallback("lod_error_threshold", onLODParamCommit, this);
+ childSetCommitCallback("lod_triangle_limit", onLODParamCommit, this);
+ childSetCommitCallback("build_operator", onLODParamCommit, this);
+ childSetCommitCallback("queue_mode", onLODParamCommit, this);
+ childSetCommitCallback("border_mode", onLODParamCommit, this);
+ childSetCommitCallback("share_tolerance", onLODParamCommit, this);
childSetTextArg("status", "[STATUS]", getString("status_idle"));
@@ -269,7 +293,6 @@ BOOL LLFloaterModelPreview::postBuild()
childSetAction("ok_btn", onUpload, this);
childDisable("ok_btn");
- childSetAction("consolidate", onConsolidate, this);
childSetAction("clear_materials", onClearMaterials, this);
childSetCommitCallback("preview_lod_combo", onPreviewLODCommit, this);
@@ -284,7 +307,19 @@ BOOL LLFloaterModelPreview::postBuild()
childDisable("upload_skin");
childDisable("upload_joints");
+ childDisable("ok_btn");
+
+ mViewOptionMenuButton = getChild<LLMenuButton>("options_gear_btn");
+
+ mCommitCallbackRegistrar.add("ModelImport.ViewOption.Action", boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _2));
+ mEnableCallbackRegistrar.add("ModelImport.ViewOption.Check", boost::bind(&LLFloaterModelPreview::isViewOptionChecked, this, _2));
+ mEnableCallbackRegistrar.add("ModelImport.ViewOption.Enabled", boost::bind(&LLFloaterModelPreview::isViewOptionEnabled, this, _2));
+
+
+ mViewOptionMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_model_import_gear_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ mViewOptionMenuButton->setMenu(mViewOptionMenu, LLMenuButton::MP_BOTTOM_LEFT);
+
initDecompControls();
LLView* preview_panel = getChild<LLView>("preview_panel");
@@ -345,21 +380,47 @@ LLFloaterModelPreview::~LLFloaterModelPreview()
}
}
-void LLFloaterModelPreview::loadModel(S32 lod)
+void LLFloaterModelPreview::onViewOptionChecked(const LLSD& userdata)
{
- mLoading = TRUE;
-
- (new LLMeshFilePicker(this, lod))->getFile();
+ mViewOption[userdata.asString()] = !mViewOption[userdata.asString()];
+ mModelPreview->refresh();
}
-void LLFloaterModelPreview::setLimit(S32 lod, S32 limit)
+bool LLFloaterModelPreview::isViewOptionChecked(const LLSD& userdata)
{
- if (limit != mModelPreview->mLimit[lod])
- {
- mModelPreview->mLimit[lod] = limit;
- mModelPreview->genLODs(lod);
- mModelPreview->setPreviewLOD(lod);
- }
+ return mViewOption[userdata.asString()];
+}
+
+bool LLFloaterModelPreview::isViewOptionEnabled(const LLSD& userdata)
+{
+ return !mViewOptionDisabled[userdata.asString()];
+}
+
+void LLFloaterModelPreview::setViewOptionEnabled(const std::string& option, bool enabled)
+{
+ mViewOptionDisabled[option] = !enabled;
+}
+
+void LLFloaterModelPreview::enableViewOption(const std::string& option)
+{
+ setViewOptionEnabled(option, true);
+}
+
+void LLFloaterModelPreview::disableViewOption(const std::string& option)
+{
+ setViewOptionEnabled(option, false);
+}
+
+void LLFloaterModelPreview::setViewOption(const std::string& option, bool value)
+{
+ mViewOption[option] = value;
+}
+
+void LLFloaterModelPreview::loadModel(S32 lod)
+{
+ mModelPreview->mLoading = true;
+
+ (new LLMeshFilePicker(mModelPreview, lod))->getFile();
}
//static
@@ -421,33 +482,10 @@ void LLFloaterModelPreview::onPreviewLODCommit(LLUICtrl* ctrl, void* userdata)
{
which_mode = iface->getFirstSelectedIndex();
}
+ which_mode = (NUM_LOD-1)-which_mode; // combo box list of lods is in reverse order
fp->mModelPreview->setPreviewLOD(which_mode);
}
-//static
-void LLFloaterModelPreview::setLimit(S32 lod, void* userdata)
-{
- LLFloaterModelPreview *fp =(LLFloaterModelPreview *)userdata;
-
- if (!fp->mModelPreview)
- {
- return;
- }
-
- S32 limit = fp->childGetValue("lod_triangle_limit").asInteger();
-
-
- fp->setLimit(lod, limit);
-}
-
-//static
-void LLFloaterModelPreview::onTriangleLimitCommit(LLUICtrl* ctrl, void* userdata)
-{
- LLFloaterModelPreview* fp = (LLFloaterModelPreview*) userdata;
-
- LLFloaterModelPreview::setLimit(fp->mModelPreview->mPreviewLOD, userdata);
-}
-
//static
void LLFloaterModelPreview::onGenerateNormalsCommit(LLUICtrl* ctrl, void* userdata)
{
@@ -457,14 +495,6 @@ void LLFloaterModelPreview::onGenerateNormalsCommit(LLUICtrl* ctrl, void* userda
}
//static
-void LLFloaterModelPreview::onShowEdgesCommit(LLUICtrl* ctrl, void* userdata)
-{
- LLFloaterModelPreview* fp = (LLFloaterModelPreview*) userdata;
-
- fp->mModelPreview->refresh();
-}
-
-//static
void LLFloaterModelPreview::onExplodeCommit(LLUICtrl* ctrl, void* userdata)
{
LLFloaterModelPreview* fp = LLFloaterModelPreview::sInstance;
@@ -480,6 +510,15 @@ void LLFloaterModelPreview::onAutoFillCommit(LLUICtrl* ctrl, void* userdata)
fp->mModelPreview->genLODs();
}
+//static
+void LLFloaterModelPreview::onLODParamCommit(LLUICtrl* ctrl, void* userdata)
+{
+ LLFloaterModelPreview* fp = (LLFloaterModelPreview*) userdata;
+ fp->mModelPreview->genLODs(fp->mModelPreview->mPreviewLOD);
+ fp->mModelPreview->updateStatusMessages();
+ fp->mModelPreview->refresh();
+}
+
//-----------------------------------------------------------------------------
// draw()
@@ -491,7 +530,7 @@ void LLFloaterModelPreview::draw()
mModelPreview->update();
- if (!mLoading)
+ if (!mModelPreview->mLoading)
{
childSetTextArg("status", "[STATUS]", getString("status_idle"));
}
@@ -882,7 +921,6 @@ void LLFloaterModelPreview::initDecompControls()
childSetCommitCallback("physics_layer", LLFloaterModelPreview::refresh, LLFloaterModelPreview::sInstance);
childSetCommitCallback("physics_explode", LLFloaterModelPreview::onExplodeCommit, this);
- childSetCommitCallback("show physics", LLFloaterModelPreview::refresh, this);
}
//-----------------------------------------------------------------------------
@@ -1553,9 +1591,11 @@ void LLModelLoader::run()
}
daeElement* scene = root->getDescendant("visual_scene");
+
if (!scene)
{
llwarns << "document has no visual_scene" << llendl;
+ setLoadState( ERROR_PARSING );
return;
}
@@ -1962,7 +2002,7 @@ LLColor4 LLModelLoader::getDaeColor(daeElement* element)
// LLModelPreview
//-----------------------------------------------------------------------------
-LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloaterModelPreview* fmp)
+LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp)
: LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE), LLMutex(NULL)
{
mNeedsUpdate = TRUE;
@@ -1973,12 +2013,15 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloaterModelPreview* fmp
mTextureName = 0;
mPreviewLOD = 0;
mModelLoader = NULL;
+ mMaxTriangleLimit = 0;
mDirty = false;
-
- for (U32 i = 0; i < LLModel::NUM_LODS; i++)
- {
- mLimit[i] = 0;
- }
+ mGenLOD = false;
+ mLoading = false;
+ mGroup = 0;
+ mBuildShareTolerance = 0.f;
+ mBuildQueueMode = GLOD_QUEUE_GREEDY;
+ mBuildBorderMode = GLOD_BORDER_UNLOCK;
+ mBuildOperator = GLOD_OPERATOR_HALF_EDGE_COLLAPSE;
mFMP = fmp;
@@ -2000,6 +2043,11 @@ LLModelPreview::~LLModelPreview()
U32 LLModelPreview::calcResourceCost()
{
rebuildUploadData();
+
+ if ( mModelLoader->getLoadState() != LLModelLoader::ERROR_PARSING )
+ {
+ mFMP->childEnable("ok_btn");
+ }
U32 cost = 0;
std::set<LLModel*> accounted;
@@ -2094,6 +2142,11 @@ void LLModelPreview::rebuildUploadData()
F32 max_scale = 0.f;
+ if ( mBaseScene.size() > 0 )
+ {
+ mFMP->childEnable("ok_btn");
+ }
+
for (LLModelLoader::scene::iterator iter = mBaseScene.begin(); iter != mBaseScene.end(); ++iter)
{ //for each transform in scene
LLMatrix4 mat = iter->first;
@@ -2202,28 +2255,15 @@ void LLModelPreview::loadModel(std::string filename, S32 lod)
mFMP->closeFloater(false);
}
- mFMP->mLoading = false;
+ mLoading = false;
return;
}
mLODFile[lod] = filename;
- if (lod == 3 && !mGroup.empty())
+ if (lod == LLModel::LOD_HIGH)
{
- for (std::map<LLPointer<LLModel>, U32>::iterator iter = mGroup.begin(); iter != mGroup.end(); ++iter)
- {
- glodDeleteGroup(iter->second);
- stop_gloderror();
- }
-
- for (std::map<LLPointer<LLModel>, U32>::iterator iter = mObject.begin(); iter != mObject.end(); ++iter)
- {
- glodDeleteObject(iter->second);
- stop_gloderror();
- }
-
- mGroup.clear();
- mObject.clear();
+ clearGLODGroup();
}
mModelLoader = new LLModelLoader(filename, lod, this);
@@ -2234,6 +2274,11 @@ void LLModelPreview::loadModel(std::string filename, S32 lod)
setPreviewLOD(lod);
+ if ( mModelLoader->getLoadState() == LLModelLoader::ERROR_PARSING )
+ {
+ mFMP->childDisable("ok_btn");
+ }
+
if (lod == mPreviewLOD)
{
mFMP->childSetText("lod_file", mLODFile[mPreviewLOD]);
@@ -2257,6 +2302,7 @@ void LLModelPreview::setPhysicsFromLOD(S32 lod)
mVertexBuffer[LLModel::LOD_PHYSICS].clear();
rebuildUploadData();
refresh();
+ updateStatusMessages();
}
}
@@ -2275,6 +2321,7 @@ void LLModelPreview::clearIncompatible(S32 lod)
if (i == LLModel::LOD_HIGH)
{
mBaseModel = mModel[lod];
+ clearGLODGroup();
mBaseScene = mScene[lod];
mVertexBuffer[5].clear();
}
@@ -2283,6 +2330,23 @@ void LLModelPreview::clearIncompatible(S32 lod)
}
}
+void LLModelPreview::clearGLODGroup()
+{
+ if (mGroup)
+ {
+ for (std::map<LLPointer<LLModel>, U32>::iterator iter = mObject.begin(); iter != mObject.end(); ++iter)
+ {
+ glodDeleteObject(iter->second);
+ stop_gloderror();
+ }
+ mObject.clear();
+
+ glodDeleteGroup(mGroup);
+ stop_gloderror();
+ mGroup = 0;
+ }
+}
+
void LLModelPreview::loadModelCallback(S32 lod)
{ //NOT the main thread
LLMutexLock lock(this);
@@ -2305,22 +2369,28 @@ void LLModelPreview::loadModelCallback(S32 lod)
if (lod == LLModel::LOD_HIGH)
{ //save a copy of the highest LOD for automatic LOD manipulation
+ if (mBaseModel.empty())
+ { //first time we've loaded a model, auto-gen LoD
+ mGenLOD = true;
+ }
+
mBaseModel = mModel[lod];
+ clearGLODGroup();
+
mBaseScene = mScene[lod];
mVertexBuffer[5].clear();
- //mModel[lod] = NULL;
}
clearIncompatible(lod);
mDirty = true;
-
+
if (lod == LLModel::LOD_HIGH)
{
resetPreviewTarget();
}
- mFMP->mLoading = FALSE;
+ mLoading = false;
refresh();
}
@@ -2534,6 +2604,7 @@ void LLModelPreview::consolidate()
{
mBaseScene = new_scene;
mBaseModel = new_model;
+ clearGLODGroup();
mVertexBuffer[5].clear();
}
@@ -2576,6 +2647,7 @@ void LLModelPreview::clearMaterials()
{
mBaseScene = mScene[mPreviewLOD];
mBaseModel = mModel[mPreviewLOD];
+ clearGLODGroup();
mVertexBuffer[5].clear();
}
@@ -2617,11 +2689,6 @@ void LLModelPreview::genLODs(S32 which_lod)
S32 limit = -1;
- if (which_lod != -1)
- {
- limit = mLimit[which_lod];
- }
-
U32 triangle_count = 0;
for (LLModelLoader::model_list::iterator iter = mBaseModel.begin(); iter != mBaseModel.end(); ++iter)
@@ -2637,37 +2704,132 @@ void LLModelPreview::genLODs(S32 which_lod)
U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0;
- if (mGroup[mBaseModel[0]] == 0)
- { //clear LOD maps
- mGroup.clear();
- mObject.clear();
- mPercentage.clear();
- mPatch.clear();
+ U32 lod_mode = 0;
+
+ LLCtrlSelectionInterface* iface = mFMP->childGetSelectionInterface("lod_mode");
+ if (iface)
+ {
+ lod_mode = iface->getFirstSelectedIndex();
}
+
+ F32 lod_error_threshold = mFMP->childGetValue("lod_error_threshold").asReal();
- for (LLModelLoader::model_list::iterator iter = mBaseModel.begin(); iter != mBaseModel.end(); ++iter)
- { //build GLOD objects for each model in base model list
- LLModel* mdl = *iter;
- if (mGroup[mdl] == 0)
+ if (lod_mode == 0)
+ {
+ lod_mode = GLOD_TRIANGLE_BUDGET;
+ if (which_lod != -1)
{
- mGroup[mdl] = cur_name++;
- mObject[mdl] = cur_name++;
-
- glodNewGroup(mGroup[mdl]);
- stop_gloderror();
-
- glodGroupParameteri(mGroup[mdl], GLOD_ADAPT_MODE, GLOD_TRIANGLE_BUDGET);
- stop_gloderror();
-
- glodGroupParameteri(mGroup[mdl], GLOD_ERROR_MODE, GLOD_OBJECT_SPACE_ERROR);
- stop_gloderror();
+ limit = mFMP->childGetValue("lod_triangle_limit").asInteger();
+ }
+ }
+ else
+ {
+ lod_mode = GLOD_ERROR_THRESHOLD;
+ }
+
+ U32 build_operator = 0;
+
+ iface = mFMP->childGetSelectionInterface("build_operator");
+ if (iface)
+ {
+ build_operator = iface->getFirstSelectedIndex();
+ }
+
+ if (build_operator == 0)
+ {
+ build_operator = GLOD_OPERATOR_HALF_EDGE_COLLAPSE;
+ }
+ else
+ {
+ build_operator = GLOD_OPERATOR_EDGE_COLLAPSE;
+ }
+
+ U32 queue_mode;
+ iface = mFMP->childGetSelectionInterface("queue_mode");
+ if (iface)
+ {
+ queue_mode = iface->getFirstSelectedIndex();
+ }
+
+ if (queue_mode == 0)
+ {
+ queue_mode = GLOD_QUEUE_GREEDY;
+ }
+ else if (queue_mode == 1)
+ {
+ queue_mode = GLOD_QUEUE_LAZY;
+ }
+ else
+ {
+ queue_mode = GLOD_QUEUE_INDEPENDENT;
+ }
+
+ U32 border_mode = 0;
+
+ iface = mFMP->childGetSelectionInterface("border_mode");
+ if (iface)
+ {
+ border_mode = iface->getFirstSelectedIndex();
+ }
+
+ if (border_mode == 0)
+ {
+ border_mode = GLOD_BORDER_UNLOCK;
+ }
+ else
+ {
+ border_mode = GLOD_BORDER_LOCK;
+ }
+
+ bool object_dirty = false;
+ if (border_mode != mBuildBorderMode)
+ {
+ mBuildBorderMode = border_mode;
+ object_dirty = true;
+ }
+
+ if (queue_mode != mBuildQueueMode)
+ {
+ mBuildQueueMode = queue_mode;
+ object_dirty = true;
+ }
+
+ if (build_operator != mBuildOperator)
+ {
+ mBuildOperator = build_operator;
+ object_dirty = true;
+ }
+
+ F32 share_tolerance = mFMP->childGetValue("share_tolerance").asReal();
+ if (share_tolerance != mBuildShareTolerance)
+ {
+ mBuildShareTolerance = share_tolerance;
+ object_dirty = true;
+ }
+
+ if (mGroup == 0)
+ {
+ object_dirty = true;
+ mGroup = cur_name++;
+ glodNewGroup(mGroup);
+ }
+
+ if (object_dirty)
+ {
+ for (LLModelLoader::model_list::iterator iter = mBaseModel.begin(); iter != mBaseModel.end(); ++iter)
+ { //build GLOD objects for each model in base model list
+ LLModel* mdl = *iter;
- glodGroupParameterf(mGroup[mdl], GLOD_OBJECT_SPACE_ERROR_THRESHOLD, 0.025f);
- stop_gloderror();
+ if (mObject[mdl] != 0)
+ {
+ glodDeleteObject(mObject[mdl]);
+ }
+
+ mObject[mdl] = cur_name++;
- glodNewObject(mObject[mdl], mGroup[mdl], GLOD_DISCRETE);
+ glodNewObject(mObject[mdl], mGroup, GLOD_DISCRETE);
stop_gloderror();
-
+
if (iter == mBaseModel.begin() && !mdl->mSkinWeights.empty())
{ //regenerate vertex buffer for skinned models to prevent animation feedback during LOD generation
mVertexBuffer[5].clear();
@@ -2690,38 +2852,22 @@ void LLModelPreview::genLODs(S32 which_lod)
tri_count += num_indices/3;
stop_gloderror();
}
-
- //store what percentage of total model (in terms of triangle count) this model makes up
- mPercentage[mdl] = (F32) tri_count / (F32) base_triangle_count;
-
- //build glodobject
+
+ glodObjectParameteri(mObject[mdl], GLOD_BUILD_OPERATOR, build_operator);
+ stop_gloderror();
+
+ glodObjectParameteri(mObject[mdl], GLOD_BUILD_QUEUE_MODE, queue_mode);
+ stop_gloderror();
+
+ glodObjectParameteri(mObject[mdl], GLOD_BUILD_BORDER_MODE, border_mode);
+ stop_gloderror();
+
+ glodObjectParameterf(mObject[mdl], GLOD_BUILD_SHARE_TOLERANCE, share_tolerance);
+ stop_gloderror();
+
glodBuildObject(mObject[mdl]);
- if (stop_gloderror())
- {
- glodDeleteGroup(mGroup[mdl]);
- stop_gloderror();
- glodDeleteObject(mObject[mdl]);
- stop_gloderror();
-
- mGroup[mdl] = 0;
- mObject[mdl] = 0;
-
- if (which_lod == -1)
- {
- mModel[LLModel::LOD_HIGH] = mBaseModel;
- }
-
- return;
- }
-
+ stop_gloderror();
}
-
- //generating LODs for all entries, or this entry has a triangle budget
- glodGroupParameteri(mGroup[mdl], GLOD_ADAPT_MODE, GLOD_TRIANGLE_BUDGET);
- stop_gloderror();
-
- glodGroupParameterf(mGroup[mdl], GLOD_OBJECT_SPACE_ERROR_THRESHOLD, 0.025f);
- stop_gloderror();
}
@@ -2733,9 +2879,8 @@ void LLModelPreview::genLODs(S32 which_lod)
start = end = which_lod;
}
- LLSpinCtrl* lim = mFMP->getChild<LLSpinCtrl>("lod_triangle_limit", TRUE);
- lim->setMaxValue(base_triangle_count);
-
+ mMaxTriangleLimit = base_triangle_count;
+
for (S32 lod = start; lod >= end; --lod)
{
if (which_lod == -1)
@@ -2758,23 +2903,25 @@ void LLModelPreview::genLODs(S32 which_lod)
U32 actual_verts = 0;
U32 submeshes = 0;
+ glodGroupParameteri(mGroup, GLOD_ADAPT_MODE, lod_mode);
+ stop_gloderror();
+
+ glodGroupParameteri(mGroup, GLOD_ERROR_MODE, GLOD_OBJECT_SPACE_ERROR);
+ stop_gloderror();
+
+ glodGroupParameteri(mGroup, GLOD_MAX_TRIANGLES, triangle_count);
+ stop_gloderror();
+
+ glodGroupParameterf(mGroup, GLOD_OBJECT_SPACE_ERROR_THRESHOLD, lod_error_threshold);
+ stop_gloderror();
+
+ glodAdaptGroup(mGroup);
+ stop_gloderror();
+
for (U32 mdl_idx = 0; mdl_idx < mBaseModel.size(); ++mdl_idx)
{
LLModel* base = mBaseModel[mdl_idx];
- U32 target_count = U32(mPercentage[base]*triangle_count);
-
- if (target_count < 4)
- {
- target_count = 4;
- }
-
- glodGroupParameteri(mGroup[base], GLOD_MAX_TRIANGLES, target_count);
- stop_gloderror();
-
- glodAdaptGroup(mGroup[base]);
- stop_gloderror();
-
GLint patch_count = 0;
glodGetObjectParameteriv(mObject[base], GLOD_NUM_PATCHES, &patch_count);
stop_gloderror();
@@ -2824,8 +2971,7 @@ void LLModelPreview::genLODs(S32 which_lod)
buff->getNormalStrider(norm);
buff->getTexCoord0Strider(tc);
buff->getIndexStrider(index);
-
-
+
target_model->setVolumeFaceData(names[i], pos, norm, tc, index, buff->getNumVerts(), buff->getNumIndices());
actual_tris += buff->getNumIndices()/3;
actual_verts += buff->getNumVerts();
@@ -2939,17 +3085,26 @@ void LLModelPreview::updateStatusMessages()
}
}
+ if (mMaxTriangleLimit == 0)
+ {
+ mMaxTriangleLimit = total_tris[LLModel::LOD_HIGH];
+ }
+
+
mFMP->childSetTextArg("submeshes_info", "[SUBMESHES]", llformat("%d", total_submeshes[LLModel::LOD_HIGH]));
- std::string mesh_status_good = mFMP->getString("mesh_status_good");
- std::string mesh_status_bad = mFMP->getString("mesh_status_bad");
std::string mesh_status_na = mFMP->getString("mesh_status_na");
- std::string mesh_status_none = mFMP->getString("mesh_status_none");
+
+ S32 upload_status[LLModel::LOD_HIGH+1];
bool upload_ok = true;
-
+
for (S32 lod = 0; lod <= LLModel::LOD_HIGH; ++lod)
{
+ upload_status[lod] = 0;
+
+ std::string message = "mesh_status_good";
+
if (total_tris[lod] > 0)
{
mFMP->childSetText(lod_triangles_name[lod], llformat("%d", total_tris[lod]));
@@ -2957,26 +3112,40 @@ void LLModelPreview::updateStatusMessages()
}
else
{
+ if (lod == LLModel::LOD_HIGH)
+ {
+ upload_status[lod] = 2;
+ message = "mesh_status_missing_lod";
+ }
+ else
+ {
+ for (S32 i = lod-1; i >= 0; --i)
+ {
+ if (total_tris[i] > 0)
+ {
+ upload_status[lod] = 2;
+ message = "mesh_status_missing_lod";
+ }
+ }
+ }
+
mFMP->childSetText(lod_triangles_name[lod], mesh_status_na);
mFMP->childSetText(lod_vertices_name[lod], mesh_status_na);
}
-
- std::string message = mesh_status_good;
-
const U32 lod_high = LLModel::LOD_HIGH;
if (lod != lod_high)
{
if (total_submeshes[lod] && total_submeshes[lod] != total_submeshes[lod_high])
{ //number of submeshes is different
- message = mesh_status_bad;
- upload_ok = false;
+ message = "mesh_status_submesh_mismatch";
+ upload_status[lod] = 2;
}
else if (!tris[lod].empty() && tris[lod].size() != tris[lod_high].size())
{ //number of meshes is different
- message = mesh_status_bad;
- upload_ok = false;
+ message = "mesh_status_mesh_mismatch";
+ upload_status[lod] = 2;
}
else if (!verts[lod].empty())
{
@@ -2984,23 +3153,39 @@ void LLModelPreview::updateStatusMessages()
{
S32 max_verts = i < verts[lod+1].size() ? verts[lod+1][i] : 0;
- if (verts[lod][i] > max_verts)
- { //too many vertices in this lod
- message = mesh_status_bad;
- upload_ok = false;
+ if (max_verts > 0)
+ {
+ if (verts[lod][i] > max_verts)
+ { //too many vertices in this lod
+ message = "mesh_status_too_many_vertices";
+ upload_status[lod] = 2;
+ }
}
}
}
- else
- { //no mesh
- message = mesh_status_none;
- }
}
- mFMP->childSetText(lod_status_name[lod], message);
+ LLIconCtrl* icon = mFMP->getChild<LLIconCtrl>(lod_icon_name[lod]);
+ LLUIImagePtr img = LLUI::getUIImage(lod_status_image[upload_status[lod]]);
+ icon->setVisible(true);
+ icon->setImage(img);
+
+ if (upload_status[lod] >= 2)
+ {
+ upload_ok = false;
+ }
+
+ if (lod == mPreviewLOD)
+ {
+ mFMP->childSetText("lod_status_message_text", mFMP->getString(message));
+ icon = mFMP->getChild<LLIconCtrl>("lod_status_message_icon");
+ icon->setImage(img);
+ }
}
- if (upload_ok)
+ bool errorStateFromLoader = mModelLoader->getLoadState() == LLModelLoader::ERROR_PARSING ? true : false;
+
+ if ( upload_ok && !errorStateFromLoader )
{
mFMP->childEnable("ok_btn");
}
@@ -3070,20 +3255,125 @@ void LLModelPreview::updateStatusMessages()
mFMP->childSetTextArg("physics_points", "[POINTS]", mesh_status_na);
}
+ LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance;
+ if (fmp)
+ {
+ if (phys_tris > 0 || phys_hulls > 0)
+ {
+ if (!fmp->isViewOptionEnabled("show_physics"))
+ {
+ fmp->enableViewOption("show_physics");
+ fmp->setViewOption("show_physics", true);
+ }
+ }
+ else
+ {
+ fmp->disableViewOption("show_physics");
+ fmp->setViewOption("show_physics", false);
+ }
+ }
+
+ const char* lod_controls[] =
+ {
+ "lod_mode",
+ "lod_triangle_limit",
+ "lod_error_tolerance",
+ "build_operator_text",
+ "queue_mode_text",
+ "border_mode_text",
+ "share_tolerance_text",
+ "build_operator",
+ "queue_mode",
+ "border_mode",
+ "share_tolerance"
+ };
+ const U32 num_lod_controls = sizeof(lod_controls)/sizeof(char*);
+
+ const char* file_controls[] =
+ {
+ "lod_browse",
+ "lod_file"
+ };
+ const U32 num_file_controls = sizeof(file_controls)/sizeof(char*);
+
//enable/disable controls based on radio groups
if (mFMP->childGetValue("lod_from_file").asBoolean())
{
- mFMP->childDisable("lod_triangle_limit");
- mFMP->childDisable("lod_generate");
- mFMP->childEnable("lod_file");
- mFMP->childEnable("lod_browse");
+ for (U32 i = 0; i < num_file_controls; ++i)
+ {
+ mFMP->childEnable(file_controls[i]);
+ }
+
+ for (U32 i = 0; i < num_lod_controls; ++i)
+ {
+ mFMP->childDisable(lod_controls[i]);
+ }
+
+
}
- else
+ else if (mFMP->childGetValue("lod_auto_generate").asBoolean())
{
- mFMP->childEnable("lod_triangle_limit");
- mFMP->childEnable("lod_generate");
- mFMP->childDisable("lod_file");
- mFMP->childDisable("lod_browse");
+ for (U32 i = 0; i < num_file_controls; ++i)
+ {
+ mFMP->childDisable(file_controls[i]);
+ }
+
+ for (U32 i = 0; i < num_lod_controls; ++i)
+ {
+ mFMP->childEnable(lod_controls[i]);
+ }
+
+ //if (threshold)
+ {
+ U32 lod_mode = 0;
+ LLCtrlSelectionInterface* iface = mFMP->childGetSelectionInterface("lod_mode");
+ if (iface)
+ {
+ lod_mode = iface->getFirstSelectedIndex();
+ }
+
+ LLSpinCtrl* threshold = mFMP->getChild<LLSpinCtrl>("lod_error_threshold");
+ LLSpinCtrl* limit = mFMP->getChild<LLSpinCtrl>("lod_triangle_limit");
+
+ limit->setMaxValue(mMaxTriangleLimit);
+ limit->setValue(total_tris[mPreviewLOD]);
+
+ if (lod_mode == 0)
+ {
+ limit->setVisible(true);
+ threshold->setVisible(false);
+
+ limit->setMaxValue(mMaxTriangleLimit);
+ }
+ else
+ {
+ limit->setVisible(false);
+ threshold->setVisible(true);
+ }
+ }
+ }
+ else
+ { // "None" is chosen
+ for (U32 i = 0; i < num_file_controls; ++i)
+ {
+ mFMP->childDisable(file_controls[i]);
+ }
+
+ for (U32 i = 0; i < num_lod_controls; ++i)
+ {
+ mFMP->childDisable(lod_controls[i]);
+ }
+
+ if (!mModel[mPreviewLOD].empty())
+ {
+ mModel[mPreviewLOD].clear();
+ mScene[mPreviewLOD].clear();
+ mVertexBuffer[mPreviewLOD].clear();
+
+ //this can cause phasing issues with the UI, so reenter this function and return
+ updateStatusMessages();
+ return;
+ }
}
if (mFMP->childGetValue("physics_load_from_file").asBoolean())
@@ -3117,7 +3407,7 @@ void LLModelPreview::clearBuffers()
}
}
-void LLModelPreview::genBuffers(S32 lod, bool avatar_preview)
+void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
{
U32 tri_count = 0;
U32 vertex_count = 0;
@@ -3168,7 +3458,7 @@ void LLModelPreview::genBuffers(S32 lod, bool avatar_preview)
LLVertexBuffer* vb = NULL;
- bool skinned = avatar_preview && !mdl->mSkinWeights.empty();
+ bool skinned = include_skin_weights && !mdl->mSkinWeights.empty();
U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0;
@@ -3250,7 +3540,17 @@ void LLModelPreview::update()
mDirty = false;
mResourceCost = calcResourceCost();
refresh();
+ updateStatusMessages();
+ }
+
+ if (mGenLOD)
+ {
+ mGenLOD = false;
+ genLODs();
+ refresh();
+ updateStatusMessages();
}
+
}
//-----------------------------------------------------------------------------
@@ -3261,6 +3561,22 @@ BOOL LLModelPreview::render()
LLMutexLock lock(this);
mNeedsUpdate = FALSE;
+ bool edges = false;
+ bool joint_positions = false;
+ bool skin_weight = false;
+ bool textures = false;
+ bool physics = false;
+
+ LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance;
+ if (fmp)
+ {
+ edges = fmp->isViewOptionChecked("show_edges");
+ joint_positions = fmp->isViewOptionChecked("show_joint_positions");
+ skin_weight = fmp->isViewOptionChecked("show_skin_weight");
+ textures = fmp->isViewOptionChecked("show_textures");
+ physics = fmp->isViewOptionChecked("show_physics");
+ }
+
S32 width = getWidth();
S32 height = getHeight();
@@ -3292,7 +3608,7 @@ BOOL LLModelPreview::render()
gGL.popMatrix();
}
- bool avatar_preview = false;
+ bool has_skin_weights = false;
bool upload_skin = mFMP->childGetValue("upload_skin").asBoolean();
bool upload_joints = mFMP->childGetValue("upload_joints").asBoolean();
@@ -3304,53 +3620,55 @@ BOOL LLModelPreview::render()
LLModel* model = instance.mModel;
if (!model->mSkinWeights.empty())
{
- avatar_preview = true;
+ has_skin_weights = true;
}
}
}
-
- if (upload_skin && !avatar_preview)
+
+ if (has_skin_weights)
+ { //model has skin weights, enable view options for skin weights and joint positions
+ if (fmp)
+ {
+ fmp->enableViewOption("show_skin_weight");
+ fmp->setViewOptionEnabled("show_joint_positions", skin_weight);
+ }
+ mFMP->childEnable("upload_skin");
+ }
+ else
{
+ mFMP->childDisable("upload_skin");
+ if (fmp)
+ {
+ fmp->setViewOption("show_skin_weight", false);
+ fmp->disableViewOption("show_skin_weight");
+ fmp->disableViewOption("show_joint_positions");
+ }
+ skin_weight = false;
+ }
+
+ if (upload_skin && !has_skin_weights)
+ { //can't upload skin weights if model has no skin weights
mFMP->childSetValue("upload_skin", false);
upload_skin = false;
}
if (!upload_skin && upload_joints)
- {
+ { //can't upload joints if not uploading skin weights
mFMP->childSetValue("upload_joints", false);
upload_joints = false;
}
- if (!avatar_preview)
- {
- mFMP->childDisable("upload_skin");
- }
- else
- {
- mFMP->childEnable("upload_skin");
- }
-
- if (!upload_skin)
- {
- mFMP->childDisable("upload_joints");
- }
- else
- {
- mFMP->childEnable("upload_joints");
- }
-
- avatar_preview = avatar_preview && upload_skin;
-
-
- mFMP->childSetEnabled("consolidate", !avatar_preview);
+ mFMP->childSetEnabled("upload_joints", upload_skin);
F32 explode = mFMP->childGetValue("physics_explode").asReal();
glClear(GL_DEPTH_BUFFER_BIT);
+
+ LLRect preview_rect = mFMP->getChildView("preview_panel")->getRect();
+ F32 aspect = (F32) preview_rect.getWidth()/preview_rect.getHeight();
+
+ LLViewerCamera::getInstance()->setAspect(aspect);
- F32 aspect = (F32) mFMP->mPreviewRect.getWidth()/mFMP->mPreviewRect.getHeight();
-
- LLViewerCamera::getInstance()->setAspect(aspect);
LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom);
LLVector3 offset = mCameraOffset;
@@ -3359,7 +3677,7 @@ BOOL LLModelPreview::render()
F32 z_near = 0.001f;
F32 z_far = mCameraDistance+mPreviewScale.magVec()+mCameraOffset.magVec();
- if (avatar_preview)
+ if (skin_weight)
{
target_pos = gAgentAvatarp->getPositionAgent();
z_near = 0.01f;
@@ -3370,6 +3688,7 @@ BOOL LLModelPreview::render()
refresh();
}
+ glLoadIdentity();
gPipeline.enableLightsPreview();
LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) *
@@ -3394,22 +3713,32 @@ BOOL LLModelPreview::render()
if (!mBaseModel.empty() && mVertexBuffer[5].empty())
{
- genBuffers(-1, avatar_preview);
+ genBuffers(-1, skin_weight);
//genBuffers(3);
//genLODs();
}
- bool physics = mFMP->childGetValue("show physics").asBoolean();
S32 physics_idx = mFMP->childGetValue("physics_layer").asInteger();
if (!mModel[mPreviewLOD].empty())
{
- if (mVertexBuffer[mPreviewLOD].empty())
+ bool regen = mVertexBuffer[mPreviewLOD].empty();
+ if (!regen)
{
- genBuffers(mPreviewLOD, avatar_preview);
+ const std::vector<LLPointer<LLVertexBuffer> >& vb_vec = mVertexBuffer[mPreviewLOD].begin()->second;
+ if (!vb_vec.empty())
+ {
+ const LLVertexBuffer* buff = vb_vec[0];
+ regen = buff->hasDataType(LLVertexBuffer::TYPE_WEIGHT4) != skin_weight;
+ }
+ }
+
+ if (regen)
+ {
+ genBuffers(mPreviewLOD, skin_weight);
}
- if (!avatar_preview)
+ if (!skin_weight)
{
for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
{
@@ -3433,21 +3762,28 @@ BOOL LLModelPreview::render()
buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0);
- glColor4fv(instance.mMaterial[i].mDiffuseColor.mV);
- if (i < instance.mMaterial.size() && instance.mMaterial[i].mDiffuseMap.notNull())
+ if (textures)
{
- gGL.getTexUnit(0)->bind(instance.mMaterial[i].mDiffuseMap, true);
- if (instance.mMaterial[i].mDiffuseMap->getDiscardLevel() > -1)
+ glColor4fv(instance.mMaterial[i].mDiffuseColor.mV);
+ if (i < instance.mMaterial.size() && instance.mMaterial[i].mDiffuseMap.notNull())
{
- mTextureSet.insert(instance.mMaterial[i].mDiffuseMap);
+ gGL.getTexUnit(0)->bind(instance.mMaterial[i].mDiffuseMap, true);
+ if (instance.mMaterial[i].mDiffuseMap->getDiscardLevel() > -1)
+ {
+ mTextureSet.insert(instance.mMaterial[i].mDiffuseMap);
+ }
}
}
+ else
+ {
+ glColor4f(1,1,1,1);
+ }
buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
glColor3f(0.4f, 0.4f, 0.4f);
- if (mFMP->childGetValue("show edges").asBoolean())
+ if (edges)
{
glLineWidth(3.f);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
@@ -3528,7 +3864,7 @@ BOOL LLModelPreview::render()
glColor4ubv(hull_colors[i].mV);
buff->drawArrays(LLRender::TRIANGLES, 0, buff->getNumVerts());
- if (mFMP->childGetValue("show edges").asBoolean())
+ if (edges)
{
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glLineWidth(3.f);
@@ -3559,21 +3895,28 @@ BOOL LLModelPreview::render()
buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0);
- glColor4fv(instance.mMaterial[i].mDiffuseColor.mV);
- if (i < instance.mMaterial.size() && instance.mMaterial[i].mDiffuseMap.notNull())
+ if (textures)
{
- gGL.getTexUnit(0)->bind(instance.mMaterial[i].mDiffuseMap, true);
- if (instance.mMaterial[i].mDiffuseMap->getDiscardLevel() > -1)
+ glColor4fv(instance.mMaterial[i].mDiffuseColor.mV);
+ if (i < instance.mMaterial.size() && instance.mMaterial[i].mDiffuseMap.notNull())
{
- mTextureSet.insert(instance.mMaterial[i].mDiffuseMap);
+ gGL.getTexUnit(0)->bind(instance.mMaterial[i].mDiffuseMap, true);
+ if (instance.mMaterial[i].mDiffuseMap->getDiscardLevel() > -1)
+ {
+ mTextureSet.insert(instance.mMaterial[i].mDiffuseMap);
+ }
}
}
+ else
+ {
+ glColor4f(1,1,1,1);
+ }
buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
glColor3f(0.4f, 0.4f, 0.4f);
- if (mFMP->childGetValue("show edges").asBoolean() || model == physics_model)
+ if (edges || model == physics_model)
{
if (model == physics_model)
{
@@ -3605,7 +3948,10 @@ BOOL LLModelPreview::render()
LLVector3::z_axis, // up
target_pos); // point of interest
- avatar->renderCollisionVolumes();
+ if (joint_positions)
+ {
+ avatar->renderCollisionVolumes();
+ }
for (LLModelLoader::scene::iterator iter = mScene[mPreviewLOD].begin(); iter != mScene[mPreviewLOD].end(); ++iter)
{
@@ -3690,7 +4036,7 @@ BOOL LLModelPreview::render()
buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0);
glColor3f(0.4f, 0.4f, 0.4f);
- if (mFMP->childGetValue("show edges").asBoolean())
+ if (edges)
{
glLineWidth(3.f);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
@@ -3753,7 +4099,7 @@ void LLModelPreview::setPreviewLOD(S32 lod)
mPreviewLOD = lod;
LLComboBox* combo_box = mFMP->getChild<LLComboBox>("preview_lod_combo");
- combo_box->setCurrentByIndex(mPreviewLOD);
+ combo_box->setCurrentByIndex((NUM_LOD-1)-mPreviewLOD); // combo box list of lods is in reverse order
mFMP->childSetTextArg("lod_table_footer", "[DETAIL]", mFMP->getString(lod_name[mPreviewLOD]));
mFMP->childSetText("lod_file", mLODFile[mPreviewLOD]);
@@ -3771,6 +4117,7 @@ void LLModelPreview::setPreviewLOD(S32 lod)
}
}
refresh();
+ updateStatusMessages();
}
//static
@@ -3793,12 +4140,6 @@ void LLFloaterModelPreview::onUpload(void* user_data)
mp->closeFloater(false);
}
-//static
-void LLFloaterModelPreview::onConsolidate(void* user_data)
-{
- LLFloaterModelPreview* mp = (LLFloaterModelPreview*) user_data;
- mp->mModelPreview->consolidate();
-}
//static
void LLFloaterModelPreview::onClearMaterials(void* user_data)
@@ -3887,4 +4228,3 @@ void LLFloaterModelPreview::DecompRequest::completed()
sInstance->mCurRequest = NULL;
}
}
-