summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorDave Parks <davep@lindenlab.com>2010-12-10 15:18:26 -0600
committerDave Parks <davep@lindenlab.com>2010-12-10 15:18:26 -0600
commit0ae6e2b451e9dc71800740240a615d934c91e581 (patch)
treea623d7c70addd51d768a7ebca61304894eb6de00 /indra/newview
parente0188f916d2f0d2ccad01d407b9f90e9094b05b7 (diff)
Reskin model importer according to latest spec, add extra LoD decimation parameters.
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llfloatermodelpreview.cpp666
-rw-r--r--indra/newview/llfloatermodelpreview.h36
-rw-r--r--indra/newview/llmeshreduction.cpp15
-rw-r--r--indra/newview/skins/default/textures/textures.xml4
-rw-r--r--indra/newview/skins/default/xui/en/floater_model_preview.xml254
5 files changed, 674 insertions, 301 deletions
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index b82e9dd62f..625f8924a2 100644
--- 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
@@ -132,16 +138,33 @@ 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[] =
+{
+ "lowest_status",
+ "low_status",
+ "medium_status",
+ "high_status",
+ "I went off the end of the lod_status_name array. Me so smart."
+};
+
+std::string lod_icon_name[] =
{
- "lowest_status",
- "low_status",
- "medium_status",
- "high_status",
+ "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[] =
+{
+ "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[] =
{
"lowest_label",
@@ -152,7 +175,6 @@ std::string lod_label_name[] =
};
-
bool validate_face(const LLVolumeFace& face)
{
for (U32 i = 0; i < face.mNumIndices; ++i)
@@ -254,21 +276,28 @@ 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"));
//childSetLabelArg("ok_btn", "[AMOUNT]", llformat("%d",sUploadAmount));
childSetAction("ok_btn", onUpload, this);
- childSetAction("consolidate", onConsolidate, this);
childSetAction("clear_materials", onClearMaterials, this);
childSetCommitCallback("preview_lod_combo", onPreviewLODCommit, this);
@@ -283,7 +312,18 @@ BOOL LLFloaterModelPreview::postBuild()
childDisable("upload_skin");
childDisable("upload_joints");
+
+ 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");
@@ -344,6 +384,42 @@ LLFloaterModelPreview::~LLFloaterModelPreview()
}
}
+void LLFloaterModelPreview::onViewOptionChecked(const LLSD& userdata)
+{
+ mViewOption[userdata.asString()] = !mViewOption[userdata.asString()];
+ mModelPreview->refresh();
+}
+
+bool LLFloaterModelPreview::isViewOptionChecked(const LLSD& userdata)
+{
+ 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)
{
mLoading = TRUE;
@@ -351,16 +427,6 @@ void LLFloaterModelPreview::loadModel(S32 lod)
(new LLMeshFilePicker(this, lod))->getFile();
}
-void LLFloaterModelPreview::setLimit(S32 lod, S32 limit)
-{
- if (limit != mModelPreview->mLimit[lod])
- {
- mModelPreview->mLimit[lod] = limit;
- mModelPreview->genLODs(lod);
- mModelPreview->setPreviewLOD(lod);
- }
-}
-
//static
void LLFloaterModelPreview::onImportScaleCommit(LLUICtrl*,void* userdata)
{
@@ -423,30 +489,6 @@ void LLFloaterModelPreview::onPreviewLODCommit(LLUICtrl* ctrl, void* userdata)
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)
{
@@ -456,14 +498,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;
@@ -479,6 +513,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()
@@ -881,7 +924,6 @@ void LLFloaterModelPreview::initDecompControls()
childSetCommitCallback("physics_layer", LLFloaterModelPreview::refresh, LLFloaterModelPreview::sInstance);
childSetCommitCallback("physics_explode", LLFloaterModelPreview::onExplodeCommit, this);
- childSetCommitCallback("show physics", LLFloaterModelPreview::refresh, this);
}
//-----------------------------------------------------------------------------
@@ -1972,12 +2014,14 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloaterModelPreview* fmp
mTextureName = 0;
mPreviewLOD = 0;
mModelLoader = NULL;
+ mMaxTriangleLimit = 0;
mDirty = false;
+ mGenLOD = false;
- for (U32 i = 0; i < LLModel::NUM_LODS; i++)
- {
- mLimit[i] = 0;
- }
+ mBuildShareTolerance = 0.f;
+ mBuildQueueMode = GLOD_QUEUE_GREEDY;
+ mBuildBorderMode = GLOD_BORDER_UNLOCK;
+ mBuildOperator = GLOD_OPERATOR_HALF_EDGE_COLLAPSE;
mFMP = fmp;
@@ -2256,6 +2300,7 @@ void LLModelPreview::setPhysicsFromLOD(S32 lod)
mVertexBuffer[LLModel::LOD_PHYSICS].clear();
rebuildUploadData();
refresh();
+ updateStatusMessages();
}
}
@@ -2304,16 +2349,20 @@ 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];
mBaseScene = mScene[lod];
mVertexBuffer[5].clear();
- //mModel[lod] = NULL;
}
clearIncompatible(lod);
mDirty = true;
-
+
if (lod == LLModel::LOD_HIGH)
{
resetPreviewTarget();
@@ -2616,11 +2665,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)
@@ -2644,29 +2688,132 @@ void LLModelPreview::genLODs(S32 which_lod)
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();
+
+ if (lod_mode == 0)
+ {
+ lod_mode = GLOD_TRIANGLE_BUDGET;
+ if (which_lod != -1)
+ {
+ 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;
+ }
+
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)
{
mGroup[mdl] = cur_name++;
+ }
+
+ if (mObject[mdl] == 0 || object_dirty)
+ {
+ if (mObject[mdl] != 0)
+ {
+ glodDeleteObject(mObject[mdl]);
+ }
+
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();
-
- glodGroupParameterf(mGroup[mdl], GLOD_OBJECT_SPACE_ERROR_THRESHOLD, 0.025f);
- stop_gloderror();
-
glodNewObject(mObject[mdl], mGroup[mdl], 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();
@@ -2689,38 +2836,25 @@ void LLModelPreview::genLODs(S32 which_lod)
tri_count += num_indices/3;
stop_gloderror();
}
+
+ 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]);
+ 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
- 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;
- }
-
- }
-
- //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();
+ }
}
@@ -2732,9 +2866,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)
@@ -2768,9 +2901,21 @@ void LLModelPreview::genLODs(S32 which_lod)
target_count = 4;
}
- glodGroupParameteri(mGroup[base], GLOD_MAX_TRIANGLES, target_count);
+ glodGroupParameteri(mGroup[base], GLOD_ADAPT_MODE, lod_mode);
+ stop_gloderror();
+
+ glodGroupParameteri(mGroup[base], GLOD_ADAPT_MODE, lod_mode);
+ stop_gloderror();
+
+ glodGroupParameteri(mGroup[base], GLOD_ERROR_MODE, GLOD_OBJECT_SPACE_ERROR);
stop_gloderror();
+ glodGroupParameteri(mGroup[base], GLOD_MAX_TRIANGLES, target_count);
+ stop_gloderror();
+
+ glodGroupParameterf(mGroup[base], GLOD_OBJECT_SPACE_ERROR_THRESHOLD, lod_error_threshold);
+ stop_gloderror();
+
glodAdaptGroup(mGroup[base]);
stop_gloderror();
@@ -2938,17 +3083,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]));
@@ -2956,26 +3110,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())
{
@@ -2983,20 +3151,34 @@ 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)
@@ -3069,20 +3251,121 @@ void LLModelPreview::updateStatusMessages()
mFMP->childSetTextArg("physics_points", "[POINTS]", mesh_status_na);
}
+ if (phys_tris > 0 || phys_hulls > 0)
+ {
+ if (!mFMP->isViewOptionEnabled("show_physics"))
+ {
+ mFMP->enableViewOption("show_physics");
+ mFMP->setViewOption("show_physics", true);
+ }
+ }
+ else
+ {
+ mFMP->disableViewOption("show_physics");
+ mFMP->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())
@@ -3116,7 +3399,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;
@@ -3167,7 +3450,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;
@@ -3249,7 +3532,17 @@ void LLModelPreview::update()
mDirty = false;
mResourceCost = calcResourceCost();
refresh();
+ updateStatusMessages();
}
+
+ if (mGenLOD)
+ {
+ mGenLOD = false;
+ genLODs();
+ refresh();
+ updateStatusMessages();
+ }
+
}
//-----------------------------------------------------------------------------
@@ -3260,6 +3553,12 @@ BOOL LLModelPreview::render()
LLMutexLock lock(this);
mNeedsUpdate = FALSE;
+ bool edges = mFMP->isViewOptionChecked("show_edges");
+ bool joint_positions = mFMP->isViewOptionChecked("show_joint_positions");
+ bool skin_weight = mFMP->isViewOptionChecked("show_skin_weight");
+ bool textures = mFMP->isViewOptionChecked("show_textures");
+ bool physics = mFMP->isViewOptionChecked("show_physics");
+
S32 width = getWidth();
S32 height = getHeight();
@@ -3291,7 +3590,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();
@@ -3303,45 +3602,39 @@ 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
+ mFMP->enableViewOption("show_skin_weight");
+ mFMP->setViewOptionEnabled("show_joint_positions", skin_weight);
+ mFMP->childEnable("upload_skin");
+ }
+ else
{
+ mFMP->childDisable("upload_skin");
+ mFMP->setViewOption("show_skin_weight", false);
+ mFMP->disableViewOption("show_skin_weight");
+ mFMP->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();
@@ -3358,7 +3651,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;
@@ -3369,6 +3662,7 @@ BOOL LLModelPreview::render()
refresh();
}
+ glLoadIdentity();
gPipeline.enableLightsPreview();
LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) *
@@ -3393,22 +3687,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)
+ {
+ 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, avatar_preview);
+ genBuffers(mPreviewLOD, skin_weight);
}
- if (!avatar_preview)
+ if (!skin_weight)
{
for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
{
@@ -3446,7 +3750,7 @@ BOOL LLModelPreview::render()
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);
@@ -3527,7 +3831,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);
@@ -3572,7 +3876,7 @@ BOOL LLModelPreview::render()
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)
{
@@ -3604,7 +3908,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)
{
@@ -3689,7 +3996,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);
@@ -3770,6 +4077,7 @@ void LLModelPreview::setPreviewLOD(S32 lod)
}
}
refresh();
+ updateStatusMessages();
}
//static
@@ -3792,12 +4100,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)
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index 05106644dc..4037a6976c 100644
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -48,6 +48,8 @@ class domProfile_COMMON;
class domInstance_geometry;
class domNode;
class domTranslate;
+class LLMenuButton;
+class LLToggleableMenu;
class LLModelLoader : public LLThread
{
@@ -142,7 +144,6 @@ public:
static void onUpload(void* data);
- static void onConsolidate(void* data);
static void onClearMaterials(void* data);
static void onModelDecompositionComplete(LLModel* model, std::vector<LLPointer<LLVertexBuffer> >& physics_mesh);
@@ -152,6 +153,14 @@ public:
void loadModel(S32 lod);
+ void onViewOptionChecked(const LLSD& userdata);
+ bool isViewOptionChecked(const LLSD& userdata);
+ bool isViewOptionEnabled(const LLSD& userdata);
+ void setViewOptionEnabled(const std::string& option, bool enabled);
+ void enableViewOption(const std::string& option);
+ void disableViewOption(const std::string& option);
+ void setViewOption(const std::string& option, bool value);
+
protected:
friend class LLModelPreview;
friend class LLMeshFilePicker;
@@ -163,12 +172,10 @@ protected:
static void onPreviewLODCommit(LLUICtrl*,void*);
- static void onTriangleLimitCommit(LLUICtrl*,void*);
-
static void onGenerateNormalsCommit(LLUICtrl*,void*);
static void onAutoFillCommit(LLUICtrl*,void*);
- static void onShowEdgesCommit(LLUICtrl*,void*);
+ static void onLODParamCommit(LLUICtrl*,void*);
static void onExplodeCommit(LLUICtrl*, void*);
@@ -186,9 +193,6 @@ protected:
void draw();
- static void setLimit(S32 lod, void* userdata);
- void setLimit(S32 lod, S32 limit);
-
void initDecompControls();
LLModelPreview* mModelPreview;
@@ -204,6 +208,13 @@ protected:
LLPointer<DecompRequest> mCurRequest;
+ std::map<std::string, bool> mViewOption;
+
+ //use "disabled" as false by default
+ std::map<std::string, bool> mViewOptionDisabled;
+
+ LLMenuButton* mViewOptionMenuButton;
+ LLToggleableMenu* mViewOptionMenu;
};
@@ -253,6 +264,7 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex
BOOL mNeedsUpdate;
bool mDirty;
+ bool mGenLOD;
U32 mTextureName;
F32 mCameraDistance;
F32 mCameraYaw;
@@ -263,9 +275,15 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex
LLVector3 mPreviewScale;
S32 mPreviewLOD;
U32 mResourceCost;
- S32 mLimit[LLModel::NUM_LODS];
std::string mLODFile[LLModel::NUM_LODS];
+ //GLOD object parameters (must rebuild object if these change)
+ F32 mBuildShareTolerance;
+ U32 mBuildQueueMode;
+ U32 mBuildOperator;
+ U32 mBuildBorderMode;
+
+
LLModelLoader* mModelLoader;
@@ -279,7 +297,7 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex
std::map<LLPointer<LLModel>, U32> mObject;
std::map<LLPointer<LLModel>, std::vector<U32> > mPatch;
std::map<LLPointer<LLModel>, F32> mPercentage;
-
+ U32 mMaxTriangleLimit;
std::map<LLPointer<LLModel>, std::vector<LLPointer<LLVertexBuffer> > > mPhysicsMesh;
LLMeshUploadThread::instance_list mUploadData;
diff --git a/indra/newview/llmeshreduction.cpp b/indra/newview/llmeshreduction.cpp
index b50b4cf063..14e8dd37b4 100644
--- a/indra/newview/llmeshreduction.cpp
+++ b/indra/newview/llmeshreduction.cpp
@@ -32,19 +32,8 @@
#include "glod/glod.h"
-static BOOL stop_gloderror()
-{
- GLuint error = glodGetError();
-
- if (error != GLOD_NO_ERROR)
- {
- llwarns << "GLOD error detected: " << std::hex << error << llendl;
- return TRUE;
- }
-
- return FALSE;
-}
+#if 0 //not used ?
void create_vertex_buffers_from_model(LLModel* model, std::vector<LLPointer <LLVertexBuffer> >& vertex_buffers)
{
@@ -280,4 +269,4 @@ LLPointer<LLModel> LLMeshReduction::reduce(LLModel* in_model, F32 limit, S32 mod
return out_model;
}
-
+#endif
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index b8030bfa91..e522159181 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -256,6 +256,10 @@ with the same filename but different name
<texture name="menu_separator" file_name="navbar/FileMenu_Divider.png" scale.left="4" scale.top="166" scale.right="0" scale.bottom="0" />
+ <texture name="ModelImport_Status_Good" file_name="lag_status_good.tga" preload="false"/>
+ <texture name="ModelImport_Status_Warning" file_name="lag_status_warning.tga" preload="false"/>
+ <texture name="ModelImport_Status_Error" file_name="lag_status_critical.tga" preload="false"/>
+
<texture name="MouseLook_View_Off" file_name="bottomtray/MouseLook_view_off.png" preload="false" />
<texture name="MouseLook_View_On" file_name="bottomtray/MouseLook_view_on.png" preload="false" />
diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml
index f1b6024ff7..952deb26f9 100644
--- a/indra/newview/skins/default/xui/en/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater can_close="true" can_drag_on_left="false" can_minimize="false"
- can_resize="true" height="520" min_height="520" min_width="630"
- name="Model Preview" title="Upload Model" width="630">
+ can_resize="true" height="550" min_height="550" min_width="620"
+ name="Model Preview" title="Upload Model" width="620">
<string name="status_idle">Idle</string>
<string name="status_reading_file">Loading...</string>
@@ -10,103 +10,89 @@
<string name="medium">Medium</string>
<string name="low">Low</string>
<string name="lowest">Lowest</string>
- <string name="mesh_status_good">Good</string>
- <string name="mesh_status_bad">Bad</string>"
+ <string name="mesh_status_good">Ship it!</string>
<string name="mesh_status_na">N/A</string>
<string name="mesh_status_none">None</string>
+ <string name="mesh_status_submesh_mismatch">Levels of detail have a different number of textureable faces.</string>
+ <string name="mesh_status_mesh_mismatch">Levels of detail have a different number of mesh instances.</string>
+ <string name="mesh_status_too_many_vertices">Level of detail has too many vertices.</string>
+ <string name="mesh_status_missing_lod">Missing required level of detail.</string>
<string name="layer_all">All</string> <!-- Text to display in physics layer combo box for "all layers" -->
<text left="15" bottom="25" follows="top|left" height="15" name="name_label">
Name:
</text>
- <line_editor bottom_delta="20" follows="top|left|right" height="19" max_length="254"
- name="description_form" width="310" />
- <text bottom_delta="24" follows="top|left" height="15" name="preview_label">
+ <line_editor bottom_delta="20" follows="top|left|right" height="19"
+ name="description_form" width="290" />
+
+ <text bottom_delta="20" left="15" follows="left|top" height="15" name="lod_label">
Preview:
</text>
-
- <!-- Placeholder panel for 3D preview render -->
- <panel
- name="preview_panel"
- left="15"
- width="310"
- height="310"
- follows="all"/>
-
- <text bottom_delta="25" left="15" width="100" follows="bottom|left" height="15" name="streaming cost">
- Prim Cost: [COST]
- </text>
-
- <text right="320" width="100" height="15" bottom_delta="0" follows="bottom|right" name="status">[STATUS]</text>
-
- <text bottom_delta="20" left="15" follows="left|bottom" height="15" name="lod_label">
- Level of Detail:
- </text>
- <combo_box bottom_delta="20" follows="left|bottom" height="18"
- name="preview_lod_combo" width="90" tool_tip="LOD to view in preview render">
+ <combo_box bottom_delta="20" follows="left|top" height="18"
+ name="preview_lod_combo" width="240" tool_tip="LOD to view in preview render">
<combo_item name="lowest">
- Lowest
+ Level of Detail: Lowest
</combo_item>
<combo_item name="low">
- Low
+ Level of Detail: Low
</combo_item>
<combo_item name="medium">
- Medium
+ Level of Detail: Medium
</combo_item>
<combo_item name="high">
- High
+ Level of Detail: High
</combo_item>
</combo_box>
- <check_box bottom="450" left="125" follows="left|bottom" label="Show Edges" name="show edges" width="120" height="16" tool_tip="Render wireframe in preview window"/>
- <check_box bottom_delta="15" left="125" follows="left|bottom" label="Show Physics" name="show physics" width="120" height="16" tool_tip="Show physics shape."/>
+ <menu_button follows="top|left"
+ image_hover_unselected="Toolbar_Left_Over"
+ image_overlay="OptionsMenu_Off"
+ image_selected="Toolbar_Left_Selected"
+ image_unselected="Toolbar_Left_Off"
+ layout="topleft"
+ left_pad="5"
+ name="options_gear_btn"
+ width="31"
+ height="25"/>
+ <!-- Placeholder panel for 3D preview render -->
+ <panel
+ name="preview_panel"
+ left="15"
+ width="290"
+ height="290"
+ follows="all"/>
- <button bottom="510" follows="bottom|left" height="20" label="Upload"
- left="15" width="80" name="ok_btn" tool_tip="Upload to simulator"/>
- <button left_pad="10" follows="left|bottom" height="20" width="80" label="Cancel" name="cancel_btn"/>
+ <text bottom_delta="25" left="25" width="100" follows="bottom|left">Upload Details</text>
+ <panel top_pad="5" border="true" left="15" width="290" height="70" follows="bottom|left"
+ bevel_style="in" bg_alpha_color="0 0 0 0" bg_opaque_color="0 0 0 0.3">
+ <text left="25" follows="bottom|left" width="140" height="15" name="streaming cost">
+ Resource Cost: [COST]
+ </text>
+ <text left="25" top_pad="5" width="140" follows="bottom|left" height="15" name="physics cost">
+ Physics Cost: Unknown
+ </text>
+ <text left="25" top_pad="5" follows="bottom|left" height="15" name="upload fee">
+ Upload Fee: N/A
+ </text>
+ </panel>
+
+ <text left="10" bottom="540" width="290" height="15" follows="bottom|left|right" name="status">[STATUS]</text>
+
+
+ <button bottom="540" left="430" follows="bottom|right" height="20" label="Upload"
+ width="80" name="ok_btn" tool_tip="Upload to simulator"/>
+ <button left_pad="10" follows="right|bottom" height="20" width="80" label="Cancel" name="cancel_btn"/>
<tab_container
follows="right|top|bottom"
top="15"
- left="330"
- height="475"
- width="280"
+ left="310"
+ height="470"
+ width="300"
name="import_tab"
border="true"
tab_position="top">
- <!-- MODIFIERS PANEL -->
- <panel
- border="true"
- label="Modifiers"
- name="modifiers_panel"
- left="330"
- width="280"
- height="450">
-
- <text left="10" width="90" bottom="30" follows="top|left" height="15">
- Scale:
- </text>
- <text left_pad="5" width="140" follows="top|left" height="15">
- Dimensions:
- </text>
-
- <spinner left="10" height="20" follows="top|left" width="80" top_pad="5" value="1.0" min_val="0.01" max_val="64.0" name="import_scale"/>
-
- <text left_pad="20" height="15" name="import_dimensions" follows="top|left">
- [X] x [Y] x [Z] m
- </text>
-
- <text left="10" top_pad="20" follows="top_left" height="15">
- Include:
- </text>
-
- <check_box top_pad="5" name="upload_textures" height="15" follows="top|left" label="Textures"/>
- <check_box top_pad="5" name="upload_skin" height="15" follows="top|left" label="Skin weight"/>
- <check_box top_pad="5" left="20" name="upload_joints" height="15" follows="top|left" label="Joint positions"/>
- </panel>
-
-
<!-- LOD PANEL -->
<panel
border="true"
@@ -124,60 +110,110 @@
<text valign="center" halign="center" bg_visible="true" name="high_label" left="10" top_pad="0" width="65" height="18" follows="left|top" value="High"/>
<text valign="center" halign="center" bg_visible="true" name="high_triangles" left_pad="0" width="65" height="18" follows="left|top" value="0"/>
<text valign="center" halign="center" bg_visible="true" name="high_vertices" left_pad="0" width="65" height="18" follows="left|top" value="0"/>
- <text valign="center" halign="center" bg_visible="true" name="high_status" left_pad="0" width="65" height="18" follows="left|top" value="Good"/>
+ <text valign="center" halign="center" bg_visible="true" name="high_status" left_pad="0" width="65" height="18" follows="left|top" value=""/>
+ <icon height="16" width="16" image_name="lag_status_critical.tga" mouse_opaque="true" name="status_icon_high" left_delta="20" top_delta="0" />
<text valign="center" halign="center" bg_visible="true" name="medium_label" left="10" top_pad="0" width="65" height="18" follows="left|top" value="Medium"/>
<text valign="center" halign="center" bg_visible="true" name="medium_triangles" left_pad="0" width="65" height="18" follows="left|top" value="0"/>
<text valign="center" halign="center" bg_visible="true" name="medium_vertices" left_pad="0" width="65" height="18" follows="left|top" value="0"/>
- <text valign="center" halign="center" bg_visible="true" name="medium_status" left_pad="0" width="65" height="18" follows="left|top" value="Good"/>
+ <text valign="center" halign="center" bg_visible="true" name="medium_status" left_pad="0" width="65" height="18" follows="left|top" value=""/>
+ <icon height="16" width="16" image_name="lag_status_critical.tga" mouse_opaque="true" name="status_icon_medium" left_delta="20" top_delta="0" />
<text valign="center" halign="center" bg_visible="true" name="low_label" left="10" top_pad="0" width="65" height="18" follows="left|top" value="Low"/>
<text valign="center" halign="center" bg_visible="true" name="low_triangles" left_pad="0" width="65" height="18" follows="left|top" value="0"/>
<text valign="center" halign="center" bg_visible="true" name="low_vertices" left_pad="0" width="65" height="18" follows="left|top" value="0"/>
- <text valign="center" halign="center" bg_visible="true" name="low_status" left_pad="0" width="65" height="18" follows="left|top" value="Good"/>
+ <text valign="center" halign="center" bg_visible="true" name="low_status" left_pad="0" width="65" height="18" follows="left|top" value=""/>
+ <icon height="16" width="16" image_name="lag_status_critical.tga" mouse_opaque="true" name="status_icon_low" left_delta="20" top_delta="0" />
<text valign="center" halign="center" bg_visible="true" name="lowest_label" left="10" top_pad="0" width="65" height="18" follows="left|top" value="Lowest"/>
<text valign="center" halign="center" bg_visible="true" name="lowest_triangles" left_pad="0" width="65" height="18" follows="left|top" value="0"/>
<text valign="center" halign="center" bg_visible="true" name="lowest_vertices" left_pad="0" width="65" height="18" follows="left|top" value="0"/>
- <text valign="center" halign="center" bg_visible="true" name="lowest_status" left_pad="0" width="65" height="18" follows="left|top" value="Good"/>
-
- <text left="10" width="240" height="15" top_pad="15" follows="left|top" name="lod_tabel_footer">
+ <text valign="center" halign="center" bg_visible="true" name="lowest_status" left_pad="0" width="65" height="18" follows="left|top" value=""/>
+ <icon height="16" width="16" image_name="lag_status_critical.tga" mouse_opaque="true" name="status_icon_lowest" left_delta="20" top_delta="0" />
+
+ <text left="10" width="240" height="15" top_pad="15" follows="left|top" name="lod_table_footer">
Level of Detail: [DETAIL]
</text>
- <text top_pad="10" height="15" follows="left|top">
+ <icon height="16" width="16" left="20" follows="left|top" name="lod_status_message_icon"/>
+ <text left_pad="5" width="200" height="15" follows="left|top" name="lod_status_message_text"/>
+
+ <text top_pad="10" left="10" height="15" follows="left|top">
Mesh
</text>
- <radio_group follows="top|left" height="100" left="30" name="lod_file_or_limit" width="240" value="lod_from_file">
- <radio_item bottom="85" label="Load from file" name="lod_from_file"/>
- <radio_item bottom="40" label="Auto generate" name="lod_auuto_generate"/>
+ <radio_group follows="top|left" height="210" left="30" name="lod_file_or_limit" width="240" value="lod_from_file">
+ <radio_item bottom="195" label="Load from file" name="lod_from_file"/>
+ <radio_item bottom="150" label="Auto generate" name="lod_auto_generate"/>
+ <radio_item bottom="0" label="None" name="lod_none"/>
</radio_group>
- <line_editor follows="left|top" bottom_delta="-60" width="140" left="45" value="" name="lod_file" height="20"/>
+ <line_editor follows="left|top" bottom_delta="-170" width="140" left="45" value="" name="lod_file" height="20"/>
<button bottom_delta="3" name="lod_browse" label="Browse..." left_pad="5" follows="left|top" width="70" height="25"/>
- <text follows="top|left" top_pad="22" width="140" left="45" height="15">
- Triangle Limit:
+ <combo_box follows="top|left" name="lod_mode" top_pad="22" width="100" left="45" height="20">
+ <combo_item name="triangle_limit">
+ Triangle Limit
+ </combo_item>
+ <combo_item name="error_threshold">
+ Error Threshold
+ </combo_item>
+ </combo_box>
+ <spinner follows="top|left" name="lod_triangle_limit" left_pad="5" height="20" width="100" decimal_digits="0" enabled="true"/>
+ <spinner left_delta="0" bottom_delta="0" follows="top|left" name="lod_error_threshold" min_val="0" max_val="100" height="20" width="100" decimal_digits="3" visible="false" enabled="true"/>
+
+ <text follows="top|left" name="build_operator_text" left="45" top_pad="10" width="100" height="15">
+ Build Operator:
+ </text>
+ <text follows="top|left" name="queue_mode_text" left_pad="5" width="100" height="15">
+ Queue Mode:
+ </text>
+ <combo_box follows="top|left" name="build_operator" top_pad="5" left="45" width="100" height="20">
+ <combo_item name="half_edge_collapse">
+ Half Edge Collapse
+ </combo_item>
+ <combo_item name="edge_collapse">
+ Edge Collapse
+ </combo_item>
+ </combo_box>
+
+ <combo_box follows="top|left" name="queue_mode" left_pad="5" width="100" height="20">
+ <combo_item name="greedy">
+ Greedy
+ </combo_item>
+ <combo_item name="lazy">
+ Lazy
+ </combo_item>
+ <combo_item name="independent">
+ Independent
+ </combo_item>
+ </combo_box>
+
+ <text top_pad="10" name="border_mode_text" left="45" follows="left|top" width="100" height="15">
+ Border Mode:
</text>
- <spinner follows="top|left" name="lod_triangle_limit" top_pad="5" height="20" width="60" decimal_digits="0" enabled="true"/>
-
- <button bottom_delta="3" left_pad="5" name="lod_generate" label="Generate" height="25" width="70" follows="left|top"/>
- <text name="submeshes_info" follows="left|top" left="10" top_pad="7" height="15 width=240">
- Layers: [SUBMESHES]
+ <text left_pad="5" name="share_tolderance_text" follows="left|top" width="100" height="15">
+ Share Tolerance:
</text>
- <button left="30" follows="top|left" top_pad="5" name="clear_materials" label="Clear Materials" width="100" height="25"/>
- <button left="30" follows="top|left" top_pad="5" name="consolidate" label="Consolidate" width="100" height="25"/>
- <text left="10" top_pad="10" follows="top|left" width="240" height="15">
- Normals
+ <combo_box follows="left|top" left="45" height="20" name="border_mode" width="100">
+ <combo_item name="border_unlock">
+ Unlock
+ </combo_item>
+ <combo_item name="border_lock">
+ Lock
+ </combo_item>
+ </combo_box>
+ <spinner follows="left|top" name="share_tolerance" left_pad="5" width="100" height="20"/>
+
+ <text left="10" top_pad="35" follows="top|left" width="240" height="15">
+ Generate Normals
</text>
<text left="35" top_pad="5" follows="top|left" width="100" height="15">
Crease Angle:
</text>
- <spinner follows="top|left" top_pad="5" min_val="0" max_val="180" value="75" width="60" height="20" name="crease_angle"/>
- <button follows="top|left" bottom_delta="3" left_pad="5" width="140" height="25" label="Generate Normals" name="generate_normals"/>
+ <spinner follows="top|left" left_pad="5" min_val="0" max_val="180" value="75" width="60" height="20" name="crease_angle"/>
</panel>
<!-- PANEL -->
@@ -341,8 +377,32 @@
</panel>
</panel>
-
-
+ <!-- MODIFIERS PANEL -->
+ <panel
+ border="true"
+ label="Modifiers"
+ name="modifiers_panel">
+ <text left="10" width="90" bottom="30" follows="top|left" height="15">
+ Scale:
+ </text>
+ <text left_pad="5" width="140" follows="top|left" height="15">
+ Dimensions:
+ </text>
+
+ <spinner left="10" height="20" follows="top|left" width="80" top_pad="5" value="1.0" min_val="0.01" max_val="64.0" name="import_scale"/>
+
+ <text left_pad="20" height="15" name="import_dimensions" follows="top|left">
+ [X] x [Y] x [Z] m
+ </text>
+
+ <text left="10" top_pad="20" follows="top|left" height="15">
+ Include:
+ </text>
+
+ <check_box top_pad="5" name="upload_textures" height="15" follows="top|left" label="Textures"/>
+ <check_box top_pad="5" name="upload_skin" height="15" follows="top|left" label="Skin weight"/>
+ <check_box top_pad="5" left="20" name="upload_joints" height="15" follows="top|left" label="Joint positions"/>
+ </panel>
</tab_container>
<!--