summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llprimitive/llmodel.cpp4
-rw-r--r--indra/llprimitive/llmodel.h2
-rw-r--r--indra/newview/llfloatermodelpreview.cpp1333
-rw-r--r--indra/newview/llfloatermodelpreview.h56
-rw-r--r--indra/newview/skins/default/colors.xml6
-rw-r--r--indra/newview/skins/default/xui/en/floater_model_preview.xml371
6 files changed, 996 insertions, 776 deletions
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index f7eafb2fff..eacf2377fe 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -1056,9 +1056,9 @@ void LLModel::addFace(const LLVolumeFace& face)
}
-void LLModel::smoothNormals(F32 angle_cutoff)
+void LLModel::generateNormals(F32 angle_cutoff)
{
- //smooth normals for all faces by:
+ //generate normals for all faces by:
// 1 - Create faceted copy of face with no texture coordinates
// 2 - Weld vertices in faceted copy that are shared between triangles with less than "angle_cutoff" difference between normals
// 3 - Generate smoothed set of normals based on welding results
diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h
index b45bca626a..b81bc662a0 100644
--- a/indra/llprimitive/llmodel.h
+++ b/indra/llprimitive/llmodel.h
@@ -114,7 +114,7 @@ public:
U32 num_verts,
U32 num_indices);
- void smoothNormals(F32 angle_cutoff);
+ void generateNormals(F32 angle_cutoff);
void addFace(const LLVolumeFace& face);
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 1c73a6cb31..b52e54275a 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -105,28 +105,54 @@ const S32 PREVIEW_TEXTURE_HEIGHT = 300;
void drawBoxOutline(const LLVector3& pos, const LLVector3& size);
-std::string limit_name[] =
+
+std::string lod_name[] =
+{
+ "lowest",
+ "low",
+ "medium",
+ "high",
+ "I went off the end of the lod_name array. Me so smart."
+};
+
+std::string lod_triangles_name[] =
{
- "lowest limit",
- "low limit",
- "medium limit",
- "high limit",
- "physics limit",
+ "lowest_triangles",
+ "low_triangles",
+ "medium_triangles",
+ "high_triangles",
+ "I went off the end of the lod_triangles_name array. Me so smart."
+};
- "I went off the end of the limit_name array. Me so smart."
+std::string lod_vertices_name[] =
+{
+ "lowest_vertices",
+ "low_vertices",
+ "medium_vertices",
+ "high_vertices",
+ "I went off the end of the lod_vertices_name array. Me so smart."
};
-std::string info_name[] =
+std::string lod_status_name[] =
{
- "lowest info",
- "low info",
- "medium info",
- "high info",
- "physics info",
+ "lowest_status",
+ "low_status",
+ "medium_status",
+ "high_status",
+ "I went off the end of the lod_status_name array. Me so smart."
+};
- "I went off the end of the info_name array. Me so smart."
+std::string lod_label_name[] =
+{
+ "lowest_label",
+ "low_label",
+ "medium_label",
+ "high_label",
+ "I went off the end of the lod_label_name array. Me so smart."
};
+
+
bool validate_face(const LLVolumeFace& face)
{
for (U32 i = 0; i < face.mNumIndices; ++i)
@@ -185,20 +211,6 @@ BOOL stop_gloderror()
return FALSE;
}
-LLPhysicsDecompFloater::LLPhysicsDecompFloater(LLSD& key)
-: LLFloater(key)
-{
-
-}
-
-LLPhysicsDecompFloater::~LLPhysicsDecompFloater()
-{
- if (LLFloaterModelPreview::sInstance && LLFloaterModelPreview::sInstance->mDecompFloater)
- {
- LLFloaterModelPreview::sInstance->mDecompFloater = NULL;
- }
-}
-
class LLMeshFilePicker : public LLFilePickerThread
{
public:
@@ -230,7 +242,6 @@ LLFloaterModelPreview::LLFloaterModelPreview(const LLSD& key) :
mLastMouseY = 0;
mGLName = 0;
mLoading = FALSE;
- mDecompFloater = NULL;
}
//-----------------------------------------------------------------------------
@@ -243,75 +254,73 @@ BOOL LLFloaterModelPreview::postBuild()
return FALSE;
}
- childSetCommitCallback("high detail combo", onHighLODCommit, this);
- childSetCommitCallback("medium detail combo", onMediumLODCommit, this);
- childSetCommitCallback("low detail combo", onLowLODCommit, this);
- childSetCommitCallback("lowest detail combo", onLowestLODCommit, this);
- childSetCommitCallback("physics detail combo", onPhysicsLODCommit, this);
-
-
- childSetCommitCallback("high limit", onHighLimitCommit, this);
- childSetCommitCallback("medium limit", onMediumLimitCommit, this);
- childSetCommitCallback("low limit", onLowLimitCommit, this);
- childSetCommitCallback("lowest limit", onLowestLimitCommit, this);
- childSetCommitCallback("physics limit", onPhysicsLimitCommit, this);
-
- childSetCommitCallback("smooth normals", onSmoothNormalsCommit, this);
+ 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("auto fill", onAutoFillCommit, this);
+ childSetCommitCallback("lod_generate", onAutoFillCommit, this);
childSetTextArg("status", "[STATUS]", getString("status_idle"));
- for (S32 lod = 0; lod < LLModel::NUM_LODS; ++lod)
- {
- if (lod == LLModel::LOD_PHYSICS)
- {
- childSetTextArg(info_name[lod], "[TRIANGLES]", std::string("0"));
- childSetTextArg(info_name[lod], "[HULLS]", std::string("0"));
- childSetTextArg(info_name[lod], "[POINTS]", std::string("0"));
- }
- else
- {
- childSetTextArg(info_name[lod], "[TRIANGLES]", std::string("0"));
- childSetTextArg(info_name[lod], "[VERTICES]", std::string("0"));
- childSetTextArg(info_name[lod], "[SUBMESHES]", std::string("0"));
- std::string msg = getString("required");
- childSetTextArg(info_name[lod], "[MESSAGE]", msg);
- }
-
- childSetVisible(limit_name[lod], FALSE);
- }
-
//childSetLabelArg("ok_btn", "[AMOUNT]", llformat("%d",sUploadAmount));
childSetAction("ok_btn", onUpload, this);
childSetAction("consolidate", onConsolidate, this);
- childSetAction("scrub materials", onScrubMaterials, this);
-
- childSetAction("decompose_btn", onDecompose, this);
+ childSetAction("clear_materials", onClearMaterials, this);
childSetCommitCallback("preview_lod_combo", onPreviewLODCommit, this);
childSetCommitCallback("upload_skin", onUploadSkinCommit, this);
childSetCommitCallback("upload_joints", onUploadJointsCommit, this);
- childSetCommitCallback("debug scale", onDebugScaleCommit, this);
+ childSetCommitCallback("import_scale", onImportScaleCommit, this);
+
+ childSetCommitCallback("lod_file_or_limit", refresh, this);
+ childSetCommitCallback("physics_load_radio", refresh, this);
childDisable("upload_skin");
childDisable("upload_joints");
+
+ initDecompControls();
- const U32 width = 512;
- const U32 height = 512;
+ LLView* preview_panel = getChild<LLView>("preview_panel");
- mPreviewRect.set(getRect().getWidth()-PREVIEW_HPAD-width,
- PREVIEW_HPAD+height,
- getRect().getWidth()-PREVIEW_HPAD,
- PREVIEW_HPAD);
+ mPreviewRect = preview_panel->getRect();
mModelPreview = new LLModelPreview(512, 512, this);
mModelPreview->setPreviewTarget(16.f);
+ //set callbacks for left click on line editor rows
+ for (U32 i = 0; i <= LLModel::LOD_HIGH; i++)
+ {
+ LLTextBox* text = getChild<LLTextBox>(lod_label_name[i]);
+ if (text)
+ {
+ text->setMouseDownCallback(boost::bind(&LLModelPreview::setPreviewLOD, mModelPreview, i));
+ }
+
+ text = getChild<LLTextBox>(lod_triangles_name[i]);
+ if (text)
+ {
+ text->setMouseDownCallback(boost::bind(&LLModelPreview::setPreviewLOD, mModelPreview, i));
+ }
+
+ text = getChild<LLTextBox>(lod_vertices_name[i]);
+ if (text)
+ {
+ text->setMouseDownCallback(boost::bind(&LLModelPreview::setPreviewLOD, mModelPreview, i));
+ }
+
+ text = getChild<LLTextBox>(lod_status_name[i]);
+ if (text)
+ {
+ text->setMouseDownCallback(boost::bind(&LLModelPreview::setPreviewLOD, mModelPreview, i));
+ }
+ }
+
return TRUE;
}
@@ -333,12 +342,6 @@ LLFloaterModelPreview::~LLFloaterModelPreview()
{
LLImageGL::deleteTextures(1, &mGLName );
}
-
- if (mDecompFloater)
- {
- mDecompFloater->closeFloater();
- mDecompFloater = NULL;
- }
}
void LLFloaterModelPreview::loadModel(S32 lod)
@@ -348,58 +351,6 @@ void LLFloaterModelPreview::loadModel(S32 lod)
(new LLMeshFilePicker(this, lod))->getFile();
}
-void LLFloaterModelPreview::setLODMode(S32 lod, S32 mode)
-{
- if (mode == 0)
- {
- if (lod != LLModel::LOD_PHYSICS)
- {
- for (S32 i = lod; i >= 0; i--)
- {
- mModelPreview->clearModel(i);
- }
- }
- else
- {
- mModelPreview->clearModel(lod);
- }
-
- mModelPreview->refresh();
- mModelPreview->calcResourceCost();
- }
- else if (mode == 1)
- {
- loadModel(lod);
- }
- else if (mode != mModelPreview->mLODMode[lod])
- {
- mModelPreview->mLODMode[lod] = mode;
- mModelPreview->genLODs(lod);
- }
-
- mModelPreview->setPreviewLOD(lod);
-
-
- LLSpinCtrl* lim = getChild<LLSpinCtrl>(limit_name[lod], TRUE);
-
- if (mode == 2) //triangle count
- {
- U32 tri_count = 0;
- for (LLModelLoader::model_list::iterator iter = mModelPreview->mBaseModel.begin();
- iter != mModelPreview->mBaseModel.end(); ++iter)
- {
- tri_count += (*iter)->getNumTriangles();
- }
-
- lim->setMaxValue(tri_count);
- lim->setVisible(TRUE);
- }
- else
- {
- lim->setVisible(FALSE);
- }
-}
-
void LLFloaterModelPreview::setLimit(S32 lod, S32 limit)
{
if (limit != mModelPreview->mLimit[lod])
@@ -411,7 +362,7 @@ void LLFloaterModelPreview::setLimit(S32 lod, S32 limit)
}
//static
-void LLFloaterModelPreview::onDebugScaleCommit(LLUICtrl*,void* userdata)
+void LLFloaterModelPreview::onImportScaleCommit(LLUICtrl*,void* userdata)
{
LLFloaterModelPreview *fp =(LLFloaterModelPreview *)userdata;
@@ -421,6 +372,7 @@ void LLFloaterModelPreview::onDebugScaleCommit(LLUICtrl*,void* userdata)
}
fp->mModelPreview->calcResourceCost();
+ fp->mModelPreview->refresh();
}
//static
@@ -472,68 +424,6 @@ void LLFloaterModelPreview::onPreviewLODCommit(LLUICtrl* ctrl, void* userdata)
}
//static
-void LLFloaterModelPreview::setLODMode(S32 lod, void* userdata)
-{
- LLFloaterModelPreview *fp =(LLFloaterModelPreview *)userdata;
-
- if (!fp->mModelPreview)
- {
- return;
- }
-
- S32 which_mode = 0;
-
- std::string combo_name[] =
- {
- "lowest detail combo",
- "low detail combo",
- "medium detail combo",
- "high detail combo",
- "physics detail combo",
-
- "I went off the end of the combo_name array. Me so smart."
- };
-
- LLCtrlSelectionInterface* iface = fp->childGetSelectionInterface(combo_name[lod]);
- if (iface)
- {
- which_mode = iface->getFirstSelectedIndex();
- }
-
- fp->setLODMode(lod, which_mode);
-}
-
-//static
-void LLFloaterModelPreview::onHighLODCommit(LLUICtrl* ctrl, void* userdata)
-{
- LLFloaterModelPreview::setLODMode(3, userdata);
-}
-
-//static
-void LLFloaterModelPreview::onMediumLODCommit(LLUICtrl* ctrl, void* userdata)
-{
- LLFloaterModelPreview::setLODMode(2, userdata);
-}
-
-//static
-void LLFloaterModelPreview::onLowLODCommit(LLUICtrl* ctrl, void* userdata)
-{
- LLFloaterModelPreview::setLODMode(1, userdata);
-}
-
-//static
-void LLFloaterModelPreview::onLowestLODCommit(LLUICtrl* ctrl, void* userdata)
-{
- LLFloaterModelPreview::setLODMode(0, userdata);
-}
-
-//static
-void LLFloaterModelPreview::onPhysicsLODCommit(LLUICtrl* ctrl, void* userdata)
-{
- LLFloaterModelPreview::setLODMode(4, userdata);
-}
-
-//static
void LLFloaterModelPreview::setLimit(S32 lod, void* userdata)
{
LLFloaterModelPreview *fp =(LLFloaterModelPreview *)userdata;
@@ -543,48 +433,26 @@ void LLFloaterModelPreview::setLimit(S32 lod, void* userdata)
return;
}
- S32 limit = fp->childGetValue(limit_name[lod]).asInteger();
+ S32 limit = fp->childGetValue("lod_triangle_limit").asInteger();
fp->setLimit(lod, limit);
}
//static
-void LLFloaterModelPreview::onHighLimitCommit(LLUICtrl* ctrl, void* userdata)
-{
- LLFloaterModelPreview::setLimit(3, userdata);
-}
-
-//static
-void LLFloaterModelPreview::onMediumLimitCommit(LLUICtrl* ctrl, void* userdata)
-{
- LLFloaterModelPreview::setLimit(2, userdata);
-}
-
-//static
-void LLFloaterModelPreview::onLowLimitCommit(LLUICtrl* ctrl, void* userdata)
+void LLFloaterModelPreview::onTriangleLimitCommit(LLUICtrl* ctrl, void* userdata)
{
- LLFloaterModelPreview::setLimit(1, userdata);
-}
-
-//static
-void LLFloaterModelPreview::onLowestLimitCommit(LLUICtrl* ctrl, void* userdata)
-{
- LLFloaterModelPreview::setLimit(0, userdata);
-}
+ LLFloaterModelPreview* fp = (LLFloaterModelPreview*) userdata;
-//static
-void LLFloaterModelPreview::onPhysicsLimitCommit(LLUICtrl* ctrl, void* userdata)
-{
- LLFloaterModelPreview::setLimit(4, userdata);
+ LLFloaterModelPreview::setLimit(fp->mModelPreview->mPreviewLOD, userdata);
}
//static
-void LLFloaterModelPreview::onSmoothNormalsCommit(LLUICtrl* ctrl, void* userdata)
+void LLFloaterModelPreview::onGenerateNormalsCommit(LLUICtrl* ctrl, void* userdata)
{
LLFloaterModelPreview* fp = (LLFloaterModelPreview*) userdata;
- fp->mModelPreview->smoothNormals();
+ fp->mModelPreview->generateNormals();
}
//static
@@ -627,22 +495,14 @@ void LLFloaterModelPreview::draw()
childSetTextArg("status", "[STATUS]", getString("status_idle"));
}
- childSetTextArg("description_label", "[PRIM_COST]", llformat("%d", mModelPreview->mResourceCost));
+ childSetTextArg("prim_cost", "[PRIM_COST]", llformat("%d", mModelPreview->mResourceCost));
childSetTextArg("description_label", "[TEXTURES]", llformat("%d", mModelPreview->mTextureSet.size()));
- if (mDecompFloater)
+ if (mCurRequest.notNull())
{
- if (mCurRequest.notNull())
- {
- mDecompFloater->childSetText("status", mCurRequest->mStatusMessage);
- }
- else
- {
- const std::string idle("Idle.");
- mDecompFloater->childSetText("status", idle);
- }
+ childSetTextArg("status", "[STATUS]", mCurRequest->mStatusMessage);
}
-
+
U32 resource_cost = mModelPreview->mResourceCost*10;
if (childGetValue("upload_textures").asBoolean())
@@ -658,6 +518,16 @@ void LLFloaterModelPreview::draw()
gGL.getTexUnit(0)->bind(mModelPreview);
+
+ LLView* preview_panel = getChild<LLView>("preview_panel");
+
+ LLRect rect = preview_panel->getRect();
+ if (rect != mPreviewRect)
+ {
+ mModelPreview->refresh();
+ mPreviewRect = preview_panel->getRect();
+ }
+
gGL.begin( LLRender::QUADS );
{
gGL.texCoord2f(0.f, 1.f);
@@ -807,13 +677,10 @@ void LLFloaterModelPreview::onPhysicsStageExecute(LLUICtrl* ctrl, void* data)
if (sInstance->mModelPreview)
{
- if (sInstance->mDecompFloater)
+ S32 idx = sInstance->childGetValue("physics_layer").asInteger();
+ if (idx >= 0 && idx < sInstance->mModelPreview->mModel[LLModel::LOD_PHYSICS].size())
{
- S32 idx = sInstance->mDecompFloater->childGetValue("model").asInteger();
- if (idx >= 0 && idx < sInstance->mModelPreview->mModel[LLModel::LOD_PHYSICS].size())
- {
- mdl = sInstance->mModelPreview->mModel[LLModel::LOD_PHYSICS][idx];
- }
+ mdl = sInstance->mModelPreview->mModel[LLModel::LOD_PHYSICS][idx];
}
}
}
@@ -823,276 +690,198 @@ void LLFloaterModelPreview::onPhysicsStageExecute(LLUICtrl* ctrl, void* data)
sInstance->mCurRequest = new DecompRequest(stage->mName, mdl);
gMeshRepo.mDecompThread->submitRequest(sInstance->mCurRequest);
}
+
+ const std::string decompose("Decompose");
+
+ if (decompose == stage->mName)
+ { //hide decompose panel and show simplify panel
+ sInstance->childSetVisible("physics step 2", false);
+ sInstance->childSetVisible("physics step 3", true);
+ }
}
//static
-void LLFloaterModelPreview::onPhysicsStageCancel(LLUICtrl* ctrl, void*data)
+void LLFloaterModelPreview::onPhysicsOptimize(LLUICtrl* ctrl, void *data)
{
- if (sInstance && sInstance->mCurRequest.notNull())
- {
- sInstance->mCurRequest->mContinue = 0;
- }
+ //hide step 1 panel and show step 2 panel + info
+ sInstance->childSetVisible("physics step 1", false);
+ sInstance->childSetVisible("physics step 2", true);
+ sInstance->childSetVisible("physics info", true);
+}
+
+//static
+void LLFloaterModelPreview::onPhysicsBrowse(LLUICtrl* ctrl, void* userdata)
+{
+ sInstance->loadModel(LLModel::LOD_PHYSICS);
}
-void LLFloaterModelPreview::showDecompFloater()
+//static
+void LLFloaterModelPreview::onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata)
{
- if (!mDecompFloater)
+ S32 which_mode = 3;
+ LLCtrlSelectionInterface* iface = sInstance->childGetSelectionInterface("physics_lod_combo");
+ if (iface)
{
- LLSD key;
- mDecompFloater = new LLPhysicsDecompFloater(key);
+ which_mode = iface->getFirstSelectedIndex();
+ }
- S32 left = 20;
- S32 right = 320;
-
- S32 cur_y = 30;
+ sInstance->mModelPreview->setPhysicsFromLOD(which_mode);
+}
- {
- //add status text
- LLTextBox::Params p;
- p.name("status");
- p.rect(LLRect(left, cur_y, right-80, cur_y-20));
- mDecompFloater->addChild(LLUICtrlFactory::create<LLTextBox>(p));
- }
+//static
+void LLFloaterModelPreview::onPhysicsDecomposeBack(LLUICtrl* ctrl, void* userdata)
+{
+ //hide step 2 panel and info and show step 1 panel
+ sInstance->childSetVisible("physics step 1", true);
+ sInstance->childSetVisible("physics step 2", false);
+ sInstance->childSetVisible("physics info", false);
+}
+//static
+void LLFloaterModelPreview::onPhysicsSimplifyBack(LLUICtrl* ctrl, void* userdata)
+{
+ //hide step 3 panel and show step 2 panel
+ sInstance->childSetVisible("physics step 3", false);
+ sInstance->childSetVisible("physics step 2", true);
+}
+
+//static
+void LLFloaterModelPreview::onPhysicsStageCancel(LLUICtrl* ctrl, void*data)
+{
+ if (sInstance && sInstance->mCurRequest.notNull())
+ {
+ sInstance->mCurRequest->mContinue = 0;
+ }
+}
- { //add cancel button
- LLButton::Params p;
- p.name("Cancel");
- p.label("Cancel");
- p.rect(LLRect(right-80, cur_y, right, cur_y-20));
- LLButton* button = LLUICtrlFactory::create<LLButton>(p);
- button->setCommitCallback(onPhysicsStageCancel, NULL);
- mDecompFloater->addChild(button);
- }
+void LLFloaterModelPreview::initDecompControls()
+{
+ LLSD key;
- cur_y += 30;
+ childSetCommitCallback("cancel_btn", onPhysicsStageCancel, NULL);
+ childSetCommitCallback("physics_lod_combo", onPhysicsUseLOD, NULL);
+ childSetCommitCallback("physics_browse", onPhysicsBrowse, NULL);
+ childSetCommitCallback("physics_optimize", onPhysicsOptimize, NULL);
+ childSetCommitCallback("decompose_back", onPhysicsDecomposeBack, NULL);
+ childSetCommitCallback("simplify_back", onPhysicsSimplifyBack, NULL);
+ childSetCommitCallback("physics_layer", refresh, NULL);
+ static const LLCDStageData* stage = NULL;
+ static S32 stage_count = 0;
- static const LLCDStageData* stage = NULL;
- static S32 stage_count = 0;
+ if (!stage && LLConvexDecomposition::getInstance() != NULL)
+ {
+ stage_count = LLConvexDecomposition::getInstance()->getStages(&stage);
+ }
- if (!stage && LLConvexDecomposition::getInstance() != NULL)
- {
- stage_count = LLConvexDecomposition::getInstance()->getStages(&stage);
- }
+ static const LLCDParam* param = NULL;
+ static S32 param_count = 0;
+ if (!param && LLConvexDecomposition::getInstance() != NULL)
+ {
+ param_count = LLConvexDecomposition::getInstance()->getParameters(&param);
+ }
- static const LLCDParam* param = NULL;
- static S32 param_count = 0;
- if (!param && LLConvexDecomposition::getInstance() != NULL)
+ for (S32 j = stage_count-1; j >= 0; --j)
+ {
+ LLButton* button = getChild<LLButton>(stage[j].mName);
+ if (button)
{
- param_count = LLConvexDecomposition::getInstance()->getParameters(&param);
+ button->setCommitCallback(onPhysicsStageExecute, (void*) &stage[j]);
}
- for (S32 j = stage_count-1; j >= 0; --j)
- {
- LLButton::Params p;
- p.name(stage[j].mName);
- p.label(stage[j].mName);
- p.rect(LLRect(left, cur_y, right, cur_y-20));
- LLButton* button = LLUICtrlFactory::create<LLButton>(p);
- button->setCommitCallback(onPhysicsStageExecute, (void*) &stage[j]);
- mDecompFloater->addChild(button);
- gMeshRepo.mDecompThread->mStageID[stage[j].mName] = j;
- cur_y += 30;
- // protected against stub by stage_count being 0 for stub above
- LLConvexDecomposition::getInstance()->registerCallback(j, LLPhysicsDecomp::llcdCallback);
+ gMeshRepo.mDecompThread->mStageID[stage[j].mName] = j;
+ // protected against stub by stage_count being 0 for stub above
+ LLConvexDecomposition::getInstance()->registerCallback(j, LLPhysicsDecomp::llcdCallback);
- llinfos << "Physics decomp stage " << stage[j].mName << " (" << j << ") parameters:" << llendl;
- llinfos << "------------------------------------" << llendl;
+ //llinfos << "Physics decomp stage " << stage[j].mName << " (" << j << ") parameters:" << llendl;
+ //llinfos << "------------------------------------" << llendl;
- for (S32 i = 0; i < param_count; ++i)
+ for (S32 i = 0; i < param_count; ++i)
+ {
+ if (param[i].mStage != j)
{
- if (param[i].mStage != j)
- {
- continue;
- }
+ continue;
+ }
- std::string name(param[i].mName ? param[i].mName : "");
- std::string description(param[i].mDescription ? param[i].mDescription : "");
+ std::string name(param[i].mName ? param[i].mName : "");
+ std::string description(param[i].mDescription ? param[i].mDescription : "");
- std::string type = "unknown";
+ std::string type = "unknown";
- llinfos << name << " - " << description << llendl;
+ llinfos << name << " - " << description << llendl;
- if (param[i].mType == LLCDParam::LLCD_FLOAT)
+ if (param[i].mType == LLCDParam::LLCD_FLOAT)
+ {
+ mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mFloat);
+ //llinfos << "Type: float, Default: " << param[i].mDefault.mFloat << llendl;
+
+ LLSliderCtrl* slider = getChild<LLSliderCtrl>(name);
+ if (slider)
{
- mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mFloat);
- llinfos << "Type: float, Default: " << param[i].mDefault.mFloat << llendl;
-
- LLSliderCtrl::Params p;
- p.name(name);
- p.label(name);
- p.rect(LLRect(left, cur_y, right, cur_y-20));
- p.min_value(param[i].mDetails.mRange.mLow.mFloat);
- p.max_value(param[i].mDetails.mRange.mHigh.mFloat);
- p.increment(param[i].mDetails.mRange.mDelta.mFloat);
- p.tool_tip(description);
- p.decimal_digits(3);
- p.initial_value(param[i].mDefault.mFloat);
- LLSliderCtrl* slider = LLUICtrlFactory::create<LLSliderCtrl>(p);
+ slider->setMinValue(param[i].mDetails.mRange.mLow.mFloat);
+ slider->setMaxValue(param[i].mDetails.mRange.mHigh.mFloat);
+ slider->setIncrement(param[i].mDetails.mRange.mDelta.mFloat);
+ slider->setValue(param[i].mDefault.mFloat);
slider->setCommitCallback(onPhysicsParamCommit, (void*) &param[i]);
- mDecompFloater->addChild(slider);
- cur_y += 30;
}
- else if (param[i].mType == LLCDParam::LLCD_INTEGER)
+ }
+ else if (param[i].mType == LLCDParam::LLCD_INTEGER)
+ {
+ mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mIntOrEnumValue);
+ //llinfos << "Type: integer, Default: " << param[i].mDefault.mIntOrEnumValue << llendl;
+
+ LLSliderCtrl* slider = getChild<LLSliderCtrl>(name);
+ if (slider)
{
- mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mIntOrEnumValue);
- llinfos << "Type: integer, Default: " << param[i].mDefault.mIntOrEnumValue << llendl;
- LLSliderCtrl::Params p;
- p.name(name);
- p.label(name);
- p.rect(LLRect(left, cur_y, right, cur_y-20));
- p.min_value(param[i].mDetails.mRange.mLow.mIntOrEnumValue);
- p.max_value(param[i].mDetails.mRange.mHigh.mIntOrEnumValue);
- p.increment(param[i].mDetails.mRange.mDelta.mIntOrEnumValue);
- p.tool_tip(description);
- p.initial_value(param[i].mDefault.mIntOrEnumValue);
- LLSliderCtrl* slider = LLUICtrlFactory::create<LLSliderCtrl>(p);
+ slider->setMinValue(param[i].mDetails.mRange.mLow.mIntOrEnumValue);
+ slider->setMaxValue(param[i].mDetails.mRange.mHigh.mIntOrEnumValue);
+ slider->setIncrement(param[i].mDetails.mRange.mDelta.mIntOrEnumValue);
+ slider->setValue(param[i].mDefault.mIntOrEnumValue);
slider->setCommitCallback(onPhysicsParamCommit, (void*) &param[i]);
- mDecompFloater->addChild(slider);
- cur_y += 30;
}
- else if (param[i].mType == LLCDParam::LLCD_BOOLEAN)
+ }
+ else if (param[i].mType == LLCDParam::LLCD_BOOLEAN)
+ {
+ mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mBool);
+ //llinfos << "Type: boolean, Default: " << (param[i].mDefault.mBool ? "True" : "False") << llendl;
+
+ LLCheckBoxCtrl* check_box = getChild<LLCheckBoxCtrl>(name);
+ if (check_box)
{
- mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mBool);
- llinfos << "Type: boolean, Default: " << (param[i].mDefault.mBool ? "True" : "False") << llendl;
-
- LLCheckBoxCtrl::Params p;
- p.rect(LLRect(left, cur_y, right, cur_y-20));
- p.name(name);
- p.label(name);
- p.initial_value(param[i].mDefault.mBool);
- p.tool_tip(description);
- LLCheckBoxCtrl* check_box = LLUICtrlFactory::create<LLCheckBoxCtrl>(p);
+ check_box->setValue(param[i].mDefault.mBool);
check_box->setCommitCallback(onPhysicsParamCommit, (void*) &param[i]);
- mDecompFloater->addChild(check_box);
- cur_y += 30;
}
- else if (param[i].mType == LLCDParam::LLCD_ENUM)
- {
- S32 cur_x = left;
- mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mIntOrEnumValue);
- llinfos << "Type: enum, Default: " << param[i].mDefault.mIntOrEnumValue << llendl;
-
- { //add label
- LLTextBox::Params p;
- const LLFontGL* font = (LLFontGL*) p.font();
-
- p.rect(LLRect(left, cur_y, left+font->getWidth(name), cur_y-20));
- p.name(name);
- p.label(name);
- p.initial_value(name);
- LLTextBox* text_box = LLUICtrlFactory::create<LLTextBox>(p);
- mDecompFloater->addChild(text_box);
- cur_x += text_box->getRect().getWidth();
- }
-
- { //add combo_box
- LLComboBox::Params p;
- p.rect(LLRect(cur_x, cur_y, right-right/4, cur_y-20));
- p.name(name);
- p.label(name);
- p.tool_tip(description);
-
- llinfos << "Accepted values: " << llendl;
- LLComboBox* combo_box = LLUICtrlFactory::create<LLComboBox>(p);
- for (S32 k = 0; k < param[i].mDetails.mEnumValues.mNumEnums; ++k)
- {
- llinfos << param[i].mDetails.mEnumValues.mEnumsArray[k].mValue
- << " - " << param[i].mDetails.mEnumValues.mEnumsArray[k].mName << llendl;
+ }
+ else if (param[i].mType == LLCDParam::LLCD_ENUM)
+ {
+ mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mIntOrEnumValue);
+ //llinfos << "Type: enum, Default: " << param[i].mDefault.mIntOrEnumValue << llendl;
- combo_box->add(param[i].mDetails.mEnumValues.mEnumsArray[k].mName,
- LLSD::Integer(param[i].mDetails.mEnumValues.mEnumsArray[k].mValue));
- }
- combo_box->setValue(param[i].mDefault.mIntOrEnumValue);
- combo_box->setCommitCallback(onPhysicsParamCommit, (void*) &param[i]);
- mDecompFloater->addChild(combo_box);
- cur_y += 30;
+ { //plug into combo box
+
+ //llinfos << "Accepted values: " << llendl;
+ LLComboBox* combo_box = getChild<LLComboBox>(name);
+ for (S32 k = 0; k < param[i].mDetails.mEnumValues.mNumEnums; ++k)
+ {
+ //llinfos << param[i].mDetails.mEnumValues.mEnumsArray[k].mValue
+ // << " - " << param[i].mDetails.mEnumValues.mEnumsArray[k].mName << llendl;
+ combo_box->add(param[i].mDetails.mEnumValues.mEnumsArray[k].mName,
+ LLSD::Integer(param[i].mDetails.mEnumValues.mEnumsArray[k].mValue));
}
-
- llinfos << "----" << llendl;
+ combo_box->setValue(param[i].mDefault.mIntOrEnumValue);
+ combo_box->setCommitCallback(onPhysicsParamCommit, (void*) &param[i]);
}
- llinfos << "-----------------------------" << llendl;
- }
- }
-
- cur_y += 30;
- //explode slider
- {
- LLSliderCtrl::Params p;
- p.initial_value(0);
- p.min_value(0);
- p.max_value(1);
- p.decimal_digits(2);
- p.increment(0.05f);
- p.label("Explode");
- p.name("explode");
- p.rect(LLRect(left, cur_y, right, cur_y-20));
- LLSliderCtrl* slider = LLUICtrlFactory::create<LLSliderCtrl>(p);
-
- mDecompFloater->addChild(slider);
- cur_y += 30;
- }
-
- //mesh render checkbox
- {
- LLCheckBoxCtrl::Params p;
- p.label("Mesh: ");
- p.name("render_mesh");
- p.rect(LLRect(left, cur_y, right/4, cur_y-20));
- LLCheckBoxCtrl* check = LLUICtrlFactory::create<LLCheckBoxCtrl>(p);
- check->setValue(true);
- mDecompFloater->addChild(check);
- }
- //hull render checkbox
- {
- LLCheckBoxCtrl::Params p;
- p.label("Hull: ");
- p.name("render_hull");
- p.rect(LLRect(right/4, cur_y, right/2, cur_y-20));
- LLCheckBoxCtrl* check = LLUICtrlFactory::create<LLCheckBoxCtrl>(p);
- check->setValue(true);
- mDecompFloater->addChild(check);
- }
-
- { //submesh combo box label
- LLTextBox::Params p;
- p.label("Model");
- p.name("model label");
- p.rect(LLRect(right/2, cur_y, right-right/3, cur_y-20));
- LLTextBox* text_box = LLUICtrlFactory::create<LLTextBox>(p);
- text_box->setValue("Model");
- mDecompFloater->addChild(text_box);
- }
-
- {
- //add submesh combo box
- LLComboBox::Params p;
- p.rect(LLRect(right-right/2+p.font()->getWidth("Model"), cur_y, right, cur_y-20));
- p.name("model");
- LLComboBox* combo_box = LLUICtrlFactory::create<LLComboBox>(p);
- for (S32 i = 0; i < mModelPreview->mBaseModel.size(); ++i)
- {
- LLModel* mdl = mModelPreview->mBaseModel[i];
- combo_box->add(mdl->mLabel, i);
+ //llinfos << "----" << llendl;
}
- combo_box->setValue(0);
- mDecompFloater->addChild(combo_box);
- cur_y += 30;
+ //llinfos << "-----------------------------" << llendl;
}
-
- mDecompFloater->childSetCommitCallback("model", LLFloaterModelPreview::refresh, LLFloaterModelPreview::sInstance);
- mDecompFloater->childSetCommitCallback("render_mesh", LLFloaterModelPreview::refresh, LLFloaterModelPreview::sInstance);
- mDecompFloater->childSetCommitCallback("render_hull", LLFloaterModelPreview::refresh, LLFloaterModelPreview::sInstance);
-
- mDecompFloater->setRect(LLRect(10, cur_y+20, right+20, 10));
}
- mDecompFloater->childSetCommitCallback("explode", LLFloaterModelPreview::onExplodeCommit, this);
-
- mDecompFloater->openFloater();
+ childSetCommitCallback("physics_layer", LLFloaterModelPreview::refresh, LLFloaterModelPreview::sInstance);
+ childSetCommitCallback("physics_explode", LLFloaterModelPreview::onExplodeCommit, this);
+ childSetCommitCallback("show physics", LLFloaterModelPreview::refresh, this);
}
//-----------------------------------------------------------------------------
@@ -2080,18 +1869,15 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloaterModelPreview* fmp
mCameraPitch = 0.f;
mCameraZoom = 1.f;
mTextureName = 0;
- mPreviewLOD = 3;
+ mPreviewLOD = 0;
mModelLoader = NULL;
mDirty = false;
for (U32 i = 0; i < LLModel::NUM_LODS; i++)
{
- mLODMode[i] = 1;
mLimit[i] = 0;
}
- mLODMode[0] = 0;
-
mFMP = fmp;
glodInit();
@@ -2118,10 +1904,9 @@ U32 LLModelPreview::calcResourceCost()
U32 num_points = 0;
U32 num_hulls = 0;
- F32 debug_scale = mFMP->childGetValue("debug scale").asReal();
+ F32 debug_scale = mFMP->childGetValue("import_scale").asReal();
F32 streaming_cost = 0.f;
-
for (U32 i = 0; i < mUploadData.size(); ++i)
{
LLModelInstance& instance = mUploadData[i];
@@ -2173,13 +1958,13 @@ U32 LLModelPreview::calcResourceCost()
}
}
- mFMP->childSetTextArg(info_name[LLModel::LOD_PHYSICS], "[HULLS]", llformat("%d",num_hulls));
- mFMP->childSetTextArg(info_name[LLModel::LOD_PHYSICS], "[POINTS]", llformat("%d",num_points));
+ //mFMP->childSetTextArg(info_name[LLModel::LOD_PHYSICS], "[HULLS]", llformat("%d",num_hulls));
+ //mFMP->childSetTextArg(info_name[LLModel::LOD_PHYSICS], "[POINTS]", llformat("%d",num_points));
mFMP->childSetTextArg("streaming cost", "[COST]", llformat("%.3f", streaming_cost));
- F32 scale = mFMP->childGetValue("debug scale").asReal()*2.f;
- mFMP->childSetTextArg("dimensions", "[X]", llformat("%.3f", mPreviewScale[0]*scale));
- mFMP->childSetTextArg("dimensions", "[Y]", llformat("%.3f", mPreviewScale[1]*scale));
- mFMP->childSetTextArg("dimensions", "[Z]", llformat("%.3f", mPreviewScale[2]*scale));
+ F32 scale = mFMP->childGetValue("import_scale").asReal()*2.f;
+ mFMP->childSetTextArg("import_dimensions", "[X]", llformat("%.3f", mPreviewScale[0]*scale));
+ mFMP->childSetTextArg("import_dimensions", "[Y]", llformat("%.3f", mPreviewScale[1]*scale));
+ mFMP->childSetTextArg("import_dimensions", "[Z]", llformat("%.3f", mPreviewScale[2]*scale));
updateStatusMessages();
@@ -2193,11 +1978,11 @@ void LLModelPreview::rebuildUploadData()
//fill uploaddata instance vectors from scene data
- LLSpinCtrl* scale_spinner = mFMP->getChild<LLSpinCtrl>("debug scale");
+ LLSpinCtrl* scale_spinner = mFMP->getChild<LLSpinCtrl>("import_scale");
if (!scale_spinner)
{
- llerrs << "floater_model_preview.xml MUST contain debug scale spinner." << llendl;
+ llerrs << "floater_model_preview.xml MUST contain import_scale spinner." << llendl;
}
F32 scale = scale_spinner->getValue().asReal();
@@ -2266,6 +2051,21 @@ void LLModelPreview::rebuildUploadData()
{
scale_spinner->setValue(max_import_scale);
}
+
+ //refill "layer" combo in physics panel
+ LLComboBox* combo_box = mFMP->getChild<LLComboBox>("physics_layer");
+ if (combo_box)
+ {
+ S32 current = combo_box->getCurrentIndex();
+ combo_box->removeall();
+
+ for (S32 i = 0; i < mBaseModel.size(); ++i)
+ {
+ LLModel* mdl = mBaseModel[i];
+ combo_box->add(mdl->mLabel, i);
+ }
+ combo_box->setCurrentByIndex(current);
+ }
}
@@ -2304,6 +2104,8 @@ void LLModelPreview::loadModel(std::string filename, S32 lod)
return;
}
+ mLODFile[lod] = filename;
+
if (lod == 3 && !mGroup.empty())
{
for (std::map<LLPointer<LLModel>, U32>::iterator iter = mGroup.begin(); iter != mGroup.end(); ++iter)
@@ -2327,16 +2129,35 @@ void LLModelPreview::loadModel(std::string filename, S32 lod)
mModelLoader->start();
mFMP->childSetTextArg("status", "[STATUS]", mFMP->getString("status_reading_file"));
+
+ setPreviewLOD(lod);
- if (mFMP->childGetValue("description_form").asString().empty())
+ if (lod == mPreviewLOD)
+ {
+ mFMP->childSetText("lod_file", mLODFile[mPreviewLOD]);
+ }
+ else if (lod == LLModel::LOD_PHYSICS)
{
- std::string name = gDirUtilp->getBaseFileName(filename, true);
- mFMP->childSetValue("description_form", name);
+ mFMP->childSetText("physics_file", mLODFile[lod]);
}
mFMP->openFloater();
}
+void LLModelPreview::setPhysicsFromLOD(S32 lod)
+{
+ if (lod >= 0 && lod <= 3)
+ {
+ mModel[LLModel::LOD_PHYSICS] = mModel[lod];
+ mScene[LLModel::LOD_PHYSICS] = mScene[lod];
+ mLODFile[LLModel::LOD_PHYSICS].clear();
+ mFMP->childSetText("physics_file", mLODFile[LLModel::LOD_PHYSICS]);
+ mVertexBuffer[LLModel::LOD_PHYSICS].clear();
+ rebuildUploadData();
+ refresh();
+ }
+}
+
void LLModelPreview::clearIncompatible(S32 lod)
{
for (U32 i = 0; i <= LLModel::LOD_HIGH; i++)
@@ -2405,7 +2226,7 @@ void LLModelPreview::resetPreviewTarget()
setPreviewTarget(mPreviewScale.magVec()*2.f);
}
-void LLModelPreview::smoothNormals()
+void LLModelPreview::generateNormals()
{
S32 which_lod = mPreviewLOD;
@@ -2416,7 +2237,7 @@ void LLModelPreview::smoothNormals()
return;
}
- F32 angle_cutoff = mFMP->childGetValue("edge threshold").asReal();
+ F32 angle_cutoff = mFMP->childGetValue("crease_angle").asReal();
angle_cutoff *= DEG_TO_RAD;
@@ -2424,7 +2245,7 @@ void LLModelPreview::smoothNormals()
{
for (LLModelLoader::model_list::iterator iter = mBaseModel.begin(); iter != mBaseModel.end(); ++iter)
{
- (*iter)->smoothNormals(angle_cutoff);
+ (*iter)->generateNormals(angle_cutoff);
}
mVertexBuffer[5].clear();
@@ -2432,7 +2253,7 @@ void LLModelPreview::smoothNormals()
for (LLModelLoader::model_list::iterator iter = mModel[which_lod].begin(); iter != mModel[which_lod].end(); ++iter)
{
- (*iter)->smoothNormals(angle_cutoff);
+ (*iter)->generateNormals(angle_cutoff);
}
mVertexBuffer[which_lod].clear();
@@ -2621,7 +2442,7 @@ void LLModelPreview::consolidate()
refresh();
}
-void LLModelPreview::scrubMaterials()
+void LLModelPreview::clearMaterials()
{
for (LLModelLoader::scene::iterator iter = mScene[mPreviewLOD].begin(); iter != mScene[mPreviewLOD].end(); ++iter)
{ //for each transform in current scene
@@ -2644,7 +2465,6 @@ void LLModelPreview::scrubMaterials()
}
}
-
mVertexBuffer[mPreviewLOD].clear();
if (mPreviewLOD == LLModel::LOD_HIGH)
@@ -2808,25 +2628,9 @@ void LLModelPreview::genLODs(S32 which_lod)
start = end = which_lod;
}
+ LLSpinCtrl* lim = mFMP->getChild<LLSpinCtrl>("lod_triangle_limit", TRUE);
+ lim->setMaxValue(base_triangle_count);
- std::string combo_name[] =
- {
- "lowest detail combo",
- "low detail combo",
- "medium detail combo",
- "high detail combo",
- "physics detail combo"
- };
-
- std::string limit_name[] =
- {
- "lowest limit",
- "low limit",
- "medium limit",
- "high limit",
- "physics limit"
- };
-
for (S32 lod = start; lod >= end; --lod)
{
if (which_lod == -1)
@@ -2841,13 +2645,6 @@ void LLModelPreview::genLODs(S32 which_lod)
triangle_count = limit;
}
- LLComboBox* combo_box = mFMP->findChild<LLComboBox>(combo_name[lod]);
- combo_box->setCurrentByIndex(2);
-
- LLSpinCtrl* lim = mFMP->getChild<LLSpinCtrl>(limit_name[lod], TRUE);
- lim->setMaxValue(base_triangle_count);
- lim->setVisible(true);
-
mModel[lod].clear();
mModel[lod].resize(mBaseModel.size());
mVertexBuffer[lod].clear();
@@ -3037,32 +2834,44 @@ void LLModelPreview::updateStatusMessages()
}
}
+ 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");
- std::string upload_message;
-
- mFMP->childSetTextArg(info_name[LLModel::LOD_PHYSICS], "[TRIANGLES]", llformat("%d", total_tris[LLModel::LOD_PHYSICS]));
+ bool upload_ok = true;
for (S32 lod = 0; lod <= LLModel::LOD_HIGH; ++lod)
{
- mFMP->childSetTextArg(info_name[lod], "[TRIANGLES]", llformat("%d", total_tris[lod]));
- mFMP->childSetTextArg(info_name[lod], "[VERTICES]", llformat("%d", total_verts[lod]));
- mFMP->childSetTextArg(info_name[lod], "[SUBMESHES]", llformat("%d", total_submeshes[lod]));
+ if (total_tris[lod] > 0)
+ {
+ mFMP->childSetText(lod_triangles_name[lod], llformat("%d", total_tris[lod]));
+ mFMP->childSetText(lod_vertices_name[lod], llformat("%d", total_verts[lod]));
+ }
+ else
+ {
+ mFMP->childSetText(lod_triangles_name[lod], mesh_status_na);
+ mFMP->childSetText(lod_vertices_name[lod], mesh_status_na);
+ }
- std::string message = "good";
+
+ 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])
- {
- message = "mesh_mismatch";
- upload_message = "bad_lod";
+ { //number of submeshes is different
+ message = mesh_status_bad;
+ upload_ok = false;
}
else if (!tris[lod].empty() && tris[lod].size() != tris[lod_high].size())
- {
- message = "model_mismatch";
- upload_message = "bad_lod";
+ { //number of meshes is different
+ message = mesh_status_bad;
+ upload_ok = false;
}
else if (!verts[lod].empty())
{
@@ -3071,27 +2880,119 @@ void LLModelPreview::updateStatusMessages()
S32 max_verts = verts[lod+1][i];
if (verts[lod][i] > max_verts)
- {
- message = "too_heavy";
- upload_message = "bad_lod";
+ { //too many vertices in this lod
+ message = mesh_status_bad;
+ upload_ok = false;
}
}
}
+ else
+ { //no mesh
+ message = mesh_status_none;
+ }
}
- mFMP->childSetTextArg(info_name[lod], "[MESSAGE]", mFMP->getString(message));
+ mFMP->childSetText(lod_status_name[lod], message);
}
- if (upload_message.empty())
+ if (upload_ok)
{
- mFMP->childSetTextArg("upload_message", "[MESSAGE]", std::string(""));
mFMP->childEnable("ok_btn");
}
else
{
- mFMP->childSetTextArg("upload_message", "[MESSAGE]", mFMP->getString(upload_message));
mFMP->childDisable("ok_btn");
}
+
+ //add up physics triangles etc
+ S32 start = 0;
+ S32 end = mModel[LLModel::LOD_PHYSICS].size();
+
+ S32 idx = mFMP->childGetValue("physics_layer").asInteger();
+
+ if (idx >= 0 && idx < mModel[LLModel::LOD_PHYSICS].size())
+ {
+ start = idx;
+ end = idx+1;
+ }
+
+ S32 phys_tris = 0;
+ S32 phys_hulls = 0;
+ S32 phys_points = 0;
+
+ for (S32 i = start; i < end; ++i)
+ { //add up hulls and points and triangles for selected mesh(es)
+ LLModel* model = mModel[LLModel::LOD_PHYSICS][i];
+ S32 cur_submeshes = model->getNumVolumeFaces();
+
+ LLModel::convex_hull_decomposition& decomp = model->mConvexHullDecomp;
+
+ if (!decomp.empty())
+ {
+ phys_hulls += decomp.size();
+ for (U32 i = 0; i < decomp.size(); ++i)
+ {
+ phys_points += decomp[i].size();
+ }
+ }
+ else
+ { //choose physics shape OR decomposition, can't use both
+ for (S32 j = 0; j < cur_submeshes; ++j)
+ { //for each submesh (face), add triangles and vertices to current total
+ const LLVolumeFace& face = model->getVolumeFace(j);
+ phys_tris += face.mNumIndices/3;
+ }
+ }
+ }
+
+ if (phys_tris > 0)
+ {
+ mFMP->childSetTextArg("physics_triangles", "[TRIANGLES]", llformat("%d", phys_tris));
+ }
+ else
+ {
+ mFMP->childSetTextArg("physics_triangles", "[TRIANGLES]", mesh_status_na);
+ }
+
+ if (phys_hulls > 0)
+ {
+ mFMP->childSetTextArg("physics_hulls", "[HULLS]", llformat("%d", phys_hulls));
+ mFMP->childSetTextArg("physics_points", "[POINTS]", llformat("%d", phys_points));
+ }
+ else
+ {
+ mFMP->childSetTextArg("physics_hulls", "[HULLS]", mesh_status_na);
+ mFMP->childSetTextArg("physics_points", "[POINTS]", mesh_status_na);
+ }
+
+ //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");
+ }
+ else
+ {
+ mFMP->childEnable("lod_triangle_limit");
+ mFMP->childEnable("lod_generate");
+ mFMP->childDisable("lod_file");
+ mFMP->childDisable("lod_browse");
+ }
+
+ if (mFMP->childGetValue("physics_load_from_file").asBoolean())
+ {
+ mFMP->childDisable("physics_lod_combo");
+ mFMP->childEnable("physics_file");
+ mFMP->childEnable("physics_browse");
+ }
+ else
+ {
+ mFMP->childEnable("physics_lod_combo");
+ mFMP->childDisable("physics_file");
+ mFMP->childDisable("physics_browse");
+ }
}
void LLModelPreview::setPreviewTarget(F32 distance)
@@ -3243,6 +3144,7 @@ void LLModelPreview::update()
{
mDirty = false;
mResourceCost = calcResourceCost();
+ refresh();
}
}
@@ -3263,18 +3165,27 @@ BOOL LLModelPreview::render()
LLGLDepthTest depth(GL_TRUE);
LLGLDisable fog(GL_FOG);
- glMatrixMode(GL_PROJECTION);
- gGL.pushMatrix();
- glLoadIdentity();
- glOrtho(0.0f, width, 0.0f, height, -1.0f, 1.0f);
+ {
+ //clear background to blue
+ glMatrixMode(GL_PROJECTION);
+ gGL.pushMatrix();
+ glLoadIdentity();
+ glOrtho(0.0f, width, 0.0f, height, -1.0f, 1.0f);
- glMatrixMode(GL_MODELVIEW);
- gGL.pushMatrix();
- glLoadIdentity();
-
- gGL.color4f(0.15f, 0.2f, 0.3f, 1.f);
+ glMatrixMode(GL_MODELVIEW);
+ gGL.pushMatrix();
+ glLoadIdentity();
+
+ gGL.color4f(0.15f, 0.2f, 0.3f, 1.f);
+
+ gl_rect_2d_simple( width, height );
- gl_rect_2d_simple( width, height );
+ glMatrixMode(GL_PROJECTION);
+ gGL.popMatrix();
+
+ glMatrixMode(GL_MODELVIEW);
+ gGL.popMatrix();
+ }
bool avatar_preview = false;
bool upload_skin = mFMP->childGetValue("upload_skin").asBoolean();
@@ -3328,24 +3239,20 @@ BOOL LLModelPreview::render()
mFMP->childSetEnabled("consolidate", !avatar_preview);
- F32 explode = mFMP->mDecompFloater ? mFMP->mDecompFloater->childGetValue("explode").asReal() : 0.f;
-
- glMatrixMode(GL_PROJECTION);
- gGL.popMatrix();
-
- glMatrixMode(GL_MODELVIEW);
- gGL.popMatrix();
+ F32 explode = mFMP->childGetValue("physics_explode").asReal();
glClear(GL_DEPTH_BUFFER_BIT);
- LLViewerCamera::getInstance()->setAspect((F32) width / height );
+ F32 aspect = (F32) mFMP->mPreviewRect.getWidth()/mFMP->mPreviewRect.getHeight();
+
+ LLViewerCamera::getInstance()->setAspect(aspect);
LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom);
- LLVector3 target_pos = mPreviewTarget;
LLVector3 offset = mCameraOffset;
+ LLVector3 target_pos = mPreviewTarget+offset;
- F32 z_near = llmax(mCameraDistance-mPreviewScale.magVec(), 0.001f);
- F32 z_far = mCameraDistance+mPreviewScale.magVec();
+ F32 z_near = 0.001f;
+ F32 z_far = mCameraDistance+mPreviewScale.magVec()+mCameraOffset.magVec();
if (avatar_preview)
{
@@ -3386,21 +3293,10 @@ BOOL LLModelPreview::render()
//genBuffers(3);
//genLODs();
}
-
- bool physics = (mPreviewLOD == LLModel::LOD_PHYSICS);
-
- S32 physics_idx = -1;
-
- bool render_mesh = true;
- bool render_hull = false;
-
- if (physics && mFMP->mDecompFloater)
- {
- physics_idx = mFMP->mDecompFloater->childGetValue("model").asInteger();
- render_mesh = mFMP->mDecompFloater->childGetValue("render_mesh").asBoolean();
- render_hull = mFMP->mDecompFloater->childGetValue("render_hull").asBoolean();
- }
-
+
+ bool physics = mFMP->childGetValue("show physics").asBoolean();
+ S32 physics_idx = mFMP->childGetValue("physics_layer").asInteger();
+
if (!mModel[mPreviewLOD].empty())
{
if (mVertexBuffer[mPreviewLOD].empty())
@@ -3410,68 +3306,175 @@ BOOL LLModelPreview::render()
if (!avatar_preview)
{
- //for (LLModelLoader::scene::iterator iter = mScene[mPreviewLOD].begin(); iter != mScene[mPreviewLOD].end(); ++iter)
for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
{
LLModelInstance& instance = *iter;
+ LLModel* model = instance.mLOD[mPreviewLOD];
+
+ if (!model)
+ {
+ continue;
+ }
+
gGL.pushMatrix();
LLMatrix4 mat = instance.mTransform;
- glMultMatrixf((GLfloat*) mat.mMatrix);
+ glMultMatrixf((GLfloat*) mat.mMatrix);
+
+ for (U32 i = 0; i < mVertexBuffer[mPreviewLOD][model].size(); ++i)
+ {
+ LLVertexBuffer* buffer = mVertexBuffer[mPreviewLOD][model][i];
+
+ 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())
+ {
+ gGL.getTexUnit(0)->bind(instance.mMaterial[i].mDiffuseMap, true);
+ if (instance.mMaterial[i].mDiffuseMap->getDiscardLevel() > -1)
+ {
+ mTextureSet.insert(instance.mMaterial[i].mDiffuseMap);
+ }
+ }
+
+ 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())
+ {
+ glLineWidth(3.f);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ glLineWidth(1.f);
+ }
+ }
+ gGL.popMatrix();
+ }
+
+ if (physics)
+ {
+ glClear(GL_DEPTH_BUFFER_BIT);
+ LLGLEnable blend(GL_BLEND);
+ gGL.blendFunc(LLRender::BF_ONE, LLRender::BF_ZERO);
+
+ LLModel* physics_model = NULL;
- //for (LLModelLoader::model_instance_list::iterator model_iter = iter->second.begin(); model_iter != iter->second.end(); ++model_iter)
+ if (physics_idx >= 0 && physics_idx < mModel[LLModel::LOD_PHYSICS].size() )
{
- //LLModelInstance& instance = *model_iter;
- LLModel* model = instance.mLOD[mPreviewLOD];
+ physics_model = mModel[LLModel::LOD_PHYSICS][physics_idx];
+ }
+
+ for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
+ {
+ LLModelInstance& instance = *iter;
+
+ LLModel* model = instance.mLOD[LLModel::LOD_PHYSICS];
if (!model)
{
continue;
}
- //if (instance.mTransform != mat)
- //{
- // llerrs << "WTF?" << llendl;
- //}
+ gGL.pushMatrix();
+ LLMatrix4 mat = instance.mTransform;
- if (render_mesh)
+ glMultMatrixf((GLfloat*) mat.mMatrix);
+
+
+ bool render_mesh = true;
+
+ LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread;
+ if (decomp)
{
- for (U32 i = 0; i < mVertexBuffer[mPreviewLOD][model].size(); ++i)
+ LLMutexLock(decomp->mMutex);
+
+ std::map<LLPointer<LLModel>, std::vector<LLPointer<LLVertexBuffer> > >::iterator iter =
+ mPhysicsMesh.find(model);
+ if (iter != mPhysicsMesh.end())
{
- LLVertexBuffer* buffer = mVertexBuffer[mPreviewLOD][model][i];
-
- buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0);
- if (physics)
+ render_mesh = false;
+ for (U32 i = 0; i < iter->second.size(); ++i)
{
- if (physics_idx > -1 && model == mModel[mPreviewLOD][physics_idx])
+ if (explode > 0.f)
{
- glColor4f(1,0,0,1);
+ gGL.pushMatrix();
+
+ LLVector3 offset = model->mHullCenter[i]-model->mCenterOfHullCenters;
+ offset *= explode;
+
+ gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]);
}
- else
+
+ static std::vector<LLColor4U> hull_colors;
+
+ if (i+1 >= hull_colors.size())
{
- glColor4f(0.75f, 0.75f, 0.75f, 1.f);
+ hull_colors.push_back(LLColor4U(rand()%128+127, rand()%128+127, rand()%128+127, 255));
}
- }
- else
- {
- glColor4fv(instance.mMaterial[i].mDiffuseColor.mV);
- if (i < instance.mMaterial.size() && instance.mMaterial[i].mDiffuseMap.notNull())
+
+ LLVertexBuffer* buff = iter->second[i];
+ if (buff)
{
- gGL.getTexUnit(0)->bind(instance.mMaterial[i].mDiffuseMap, true);
- if (instance.mMaterial[i].mDiffuseMap->getDiscardLevel() > -1)
+ buff->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL);
+
+ glColor4ubv(hull_colors[i].mV);
+ buff->drawArrays(LLRender::TRIANGLES, 0, buff->getNumVerts());
+
+ if (mFMP->childGetValue("show edges").asBoolean())
{
- mTextureSet.insert(instance.mMaterial[i].mDiffuseMap);
- }
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ glLineWidth(3.f);
+ glColor4ub(hull_colors[i].mV[0]/2, hull_colors[i].mV[1]/2, hull_colors[i].mV[2]/2, 255);
+ buff->drawArrays(LLRender::TRIANGLES, 0, buff->getNumVerts());
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ glLineWidth(1.f);
+ }
+ }
+
+ if (explode > 0.f)
+ {
+ gGL.popMatrix();
}
}
+ }
+ }
+
+ if (render_mesh)
+ {
+ if (mVertexBuffer[LLModel::LOD_PHYSICS].empty())
+ {
+ genBuffers(LLModel::LOD_PHYSICS, false);
+ }
+ for (U32 i = 0; i < mVertexBuffer[LLModel::LOD_PHYSICS][model].size(); ++i)
+ {
+ LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i];
+ 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())
+ {
+ gGL.getTexUnit(0)->bind(instance.mMaterial[i].mDiffuseMap, true);
+ if (instance.mMaterial[i].mDiffuseMap->getDiscardLevel() > -1)
+ {
+ mTextureSet.insert(instance.mMaterial[i].mDiffuseMap);
+ }
+ }
+
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 (mFMP->childGetValue("show edges").asBoolean() || model == physics_model)
{
+ if (model == physics_model)
+ {
+ glColor3f(1.f, 1.f, 0.f);
+ }
+
glLineWidth(3.f);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
@@ -3481,74 +3484,10 @@ BOOL LLModelPreview::render()
}
}
- if (render_hull)
- {
- LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread;
- if (decomp)
- {
- LLMutexLock(decomp->mMutex);
-
- std::map<LLPointer<LLModel>, std::vector<LLPointer<LLVertexBuffer> > >::iterator iter =
- mPhysicsMesh.find(model);
- if (iter != mPhysicsMesh.end())
- {
- for (U32 i = 0; i < iter->second.size(); ++i)
- {
- if (explode > 0.f)
- {
- gGL.pushMatrix();
-
- LLVector3 offset = model->mHullCenter[i]-model->mCenterOfHullCenters;
- offset *= explode;
-
- gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]);
- }
-
- static std::vector<LLColor4U> hull_colors;
-
- if (i+1 >= hull_colors.size())
- {
- hull_colors.push_back(LLColor4U(rand()%128+127, rand()%128+127, rand()%128+127, 255));
- }
-
- LLVertexBuffer* buff = iter->second[i];
- if (buff)
- {
- buff->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL);
-
- glColor4ubv(hull_colors[i].mV);
- buff->drawArrays(LLRender::TRIANGLES, 0, buff->getNumVerts());
-
- if (mFMP->childGetValue("show edges").asBoolean())
- {
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- glLineWidth(3.f);
- glColor4ub(hull_colors[i].mV[0]/2, hull_colors[i].mV[1]/2, hull_colors[i].mV[2]/2, 255);
- buff->drawArrays(LLRender::TRIANGLES, 0, buff->getNumVerts());
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- glLineWidth(1.f);
- }
- }
-
- if (explode > 0.f)
- {
- gGL.popMatrix();
- }
- }
- }
- }
-
- //mFMP->childSetTextArg(info_name[LLModel::LOD_PHYSICS], "[HULLS]", llformat("%d",decomp->mHulls.size()));
- //mFMP->childSetTextArg(info_name[LLModel::LOD_PHYSICS], "[POINTS]", llformat("%d",decomp->mTotalPoints));
- }
+ gGL.popMatrix();
}
- gGL.popMatrix();
- }
-
- if (physics)
- {
- mPreviewLOD = LLModel::LOD_PHYSICS;
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
}
}
else
@@ -3702,36 +3641,38 @@ void LLModelPreview::pan(F32 right, F32 up)
void LLModelPreview::setPreviewLOD(S32 lod)
{
- mPreviewLOD = llclamp(lod, 0, 4);
- refresh();
-}
+ lod = llclamp(lod, 0, (S32) LLModel::LOD_HIGH);
-//static
-void LLFloaterModelPreview::onBrowseHighLOD(void* data)
-{
- LLFloaterModelPreview* mp = (LLFloaterModelPreview*) data;
- mp->loadModel(3);
-}
+ if (lod != mPreviewLOD)
+ {
+ mPreviewLOD = lod;
+
+ LLComboBox* combo_box = mFMP->getChild<LLComboBox>("preview_lod_combo");
+ combo_box->setCurrentByIndex(mPreviewLOD);
+ mFMP->childSetTextArg("lod_table_footer", "[DETAIL]", mFMP->getString(lod_name[mPreviewLOD]));
+ mFMP->childSetText("lod_file", mLODFile[mPreviewLOD]);
-//static
-void LLFloaterModelPreview::onBrowseMediumLOD(void* data)
-{
- LLFloaterModelPreview* mp = (LLFloaterModelPreview*) data;
- mp->loadModel(2);
-}
+ LLColor4 highlight_color = LLUIColorTable::instance().getColor("MeshImportTableHighlightColor");
+ LLColor4 normal_color = LLUIColorTable::instance().getColor("MeshImportTableNormalColor");
-//static
-void LLFloaterModelPreview::onBrowseLowLOD(void* data)
-{
- LLFloaterModelPreview* mp = (LLFloaterModelPreview*) data;
- mp->loadModel(1);
+ for (S32 i = 0; i <= LLModel::LOD_HIGH; ++i)
+ {
+ const LLColor4& color = (i == lod) ? highlight_color : normal_color;
+
+ mFMP->childSetColor(lod_status_name[i], color);
+ mFMP->childSetColor(lod_label_name[i], color);
+ mFMP->childSetColor(lod_triangles_name[i], color);
+ mFMP->childSetColor(lod_vertices_name[i], color);
+ }
+ }
+ refresh();
}
//static
-void LLFloaterModelPreview::onBrowseLowestLOD(void* data)
+void LLFloaterModelPreview::onBrowseLOD(void* data)
{
LLFloaterModelPreview* mp = (LLFloaterModelPreview*) data;
- mp->loadModel(0);
+ mp->loadModel(mp->mModelPreview->mPreviewLOD);
}
//static
@@ -3739,11 +3680,6 @@ void LLFloaterModelPreview::onUpload(void* user_data)
{
LLFloaterModelPreview* mp = (LLFloaterModelPreview*) user_data;
- if (mp->mDecompFloater)
- {
- mp->mDecompFloater->closeFloater();
- }
-
mp->mModelPreview->rebuildUploadData();
gMeshRepo.uploadModel(mp->mModelPreview->mUploadData, mp->mModelPreview->mPreviewScale,
@@ -3760,24 +3696,17 @@ void LLFloaterModelPreview::onConsolidate(void* user_data)
}
//static
-void LLFloaterModelPreview::onScrubMaterials(void* user_data)
-{
- LLFloaterModelPreview* mp = (LLFloaterModelPreview*) user_data;
- mp->mModelPreview->scrubMaterials();
-}
-
-//static
-void LLFloaterModelPreview::onDecompose(void* user_data)
+void LLFloaterModelPreview::onClearMaterials(void* user_data)
{
LLFloaterModelPreview* mp = (LLFloaterModelPreview*) user_data;
- mp->showDecompFloater();
+ mp->mModelPreview->clearMaterials();
}
//static
void LLFloaterModelPreview::refresh(LLUICtrl* ctrl, void* user_data)
{
LLFloaterModelPreview* mp = (LLFloaterModelPreview*) user_data;
- mp->mModelPreview->refresh();
+ sInstance->mModelPreview->mDirty = true;
}
void LLFloaterModelPreview::updateResourceCost()
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index a7e87ba9a1..958a8f583a 100644
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -47,14 +47,6 @@ class daeElement;
class domProfile_COMMON;
class domInstance_geometry;
-class LLPhysicsDecompFloater : public LLFloater
-{
-public:
-
- LLPhysicsDecompFloater(LLSD& key);
- ~LLPhysicsDecompFloater();
-};
-
class LLModelLoader : public LLThread
{
public:
@@ -136,16 +128,12 @@ public:
static void onMouseCaptureLostModelPreview(LLMouseHandler*);
static void setUploadAmount(S32 amount) { sUploadAmount = amount; }
- static void onBrowseHighLOD(void* data);
- static void onBrowseMediumLOD(void* data);
- static void onBrowseLowLOD(void* data);
- static void onBrowseLowestLOD(void* data);
+ static void onBrowseLOD(void* data);
static void onUpload(void* data);
static void onConsolidate(void* data);
- static void onScrubMaterials(void* data);
- static void onDecompose(void* data);
+ static void onClearMaterials(void* data);
static void onModelDecompositionComplete(LLModel* model, std::vector<LLPointer<LLVertexBuffer> >& physics_mesh);
static void refresh(LLUICtrl* ctrl, void* data);
@@ -158,27 +146,16 @@ protected:
friend class LLModelPreview;
friend class LLMeshFilePicker;
friend class LLPhysicsDecomp;
- friend class LLPhysicsDecompFloater;
- static void onDebugScaleCommit(LLUICtrl*, void*);
+ static void onImportScaleCommit(LLUICtrl*, void*);
static void onUploadJointsCommit(LLUICtrl*,void*);
static void onUploadSkinCommit(LLUICtrl*,void*);
static void onPreviewLODCommit(LLUICtrl*,void*);
- static void onHighLODCommit(LLUICtrl*,void*);
- static void onMediumLODCommit(LLUICtrl*,void*);
- static void onLowLODCommit(LLUICtrl*,void*);
- static void onLowestLODCommit(LLUICtrl*,void*);
- static void onPhysicsLODCommit(LLUICtrl*,void*);
-
- static void onHighLimitCommit(LLUICtrl*,void*);
- static void onMediumLimitCommit(LLUICtrl*,void*);
- static void onLowLimitCommit(LLUICtrl*,void*);
- static void onLowestLimitCommit(LLUICtrl*,void*);
- static void onPhysicsLimitCommit(LLUICtrl*,void*);
+ static void onTriangleLimitCommit(LLUICtrl*,void*);
- static void onSmoothNormalsCommit(LLUICtrl*,void*);
+ static void onGenerateNormalsCommit(LLUICtrl*,void*);
static void onAutoFillCommit(LLUICtrl*,void*);
static void onShowEdgesCommit(LLUICtrl*,void*);
@@ -188,20 +165,24 @@ protected:
static void onPhysicsParamCommit(LLUICtrl* ctrl, void* userdata);
static void onPhysicsStageExecute(LLUICtrl* ctrl, void* userdata);
static void onPhysicsStageCancel(LLUICtrl* ctrl, void* userdata);
- static void onClosePhysicsFloater(LLUICtrl* ctrl, void* userdata);
+
+ static void onPhysicsBrowse(LLUICtrl* ctrl, void* userdata);
+ static void onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata);
+ static void onPhysicsOptimize(LLUICtrl* ctrl, void* userdata);
+ static void onPhysicsDecomposeBack(LLUICtrl* ctrl, void* userdata);
+ static void onPhysicsSimplifyBack(LLUICtrl* ctrl, void* userdata);
+
+
void draw();
- static void setLODMode(S32 lod, void* userdata);
- void setLODMode(S32 lod, S32 which_mode);
static void setLimit(S32 lod, void* userdata);
void setLimit(S32 lod, S32 limit);
- void showDecompFloater();
+ void initDecompControls();
LLModelPreview* mModelPreview;
- LLFloater* mDecompFloater;
LLPhysicsDecomp::decomp_params mDecompParams;
S32 mLastMouseX;
@@ -227,6 +208,7 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex
void setPreviewTarget(F32 distance);
void setTexture(U32 name) { mTextureName = name; }
+ void setPhysicsFromLOD(S32 lod);
BOOL render();
void update();
void genBuffers(S32 lod, bool skinned);
@@ -241,9 +223,9 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex
void loadModel(std::string filename, S32 lod);
void loadModelCallback(S32 lod);
void genLODs(S32 which_lod = -1);
- void smoothNormals();
+ void generateNormals();
void consolidate();
- void scrubMaterials();
+ void clearMaterials();
U32 calcResourceCost();
void rebuildUploadData();
void clearIncompatible(S32 lod);
@@ -271,9 +253,9 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex
LLVector3 mPreviewScale;
S32 mPreviewLOD;
U32 mResourceCost;
- S32 mLODMode[LLModel::NUM_LODS];
S32 mLimit[LLModel::NUM_LODS];
-
+ std::string mLODFile[LLModel::NUM_LODS];
+
LLModelLoader* mModelLoader;
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index ddd2ff196b..2a5d034789 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -778,4 +778,10 @@
<color
name="MenuBarProjectBgColor"
reference="MdBlue" />
+ <color
+ name="MeshImportTableNormalColor"
+ value="1 1 1 1"/>
+ <color
+ name="MeshImportTableHighlightColor"
+ value="0.2 0.8 1 1"/>
</colors>
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 c7433af226..f1b6024ff7 100644
--- a/indra/newview/skins/default/xui/en/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml
@@ -1,49 +1,358 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater can_close="true" can_drag_on_left="false" can_minimize="false"
- can_resize="false" height="656" min_height="656" min_width="856"
- name="Model Preview" title="Import Model" width="856">
-
- <text bottom_delta="20" left="10" name="status" height="15" follows="top|left">
- Status: [STATUS]
- </text>
+ can_resize="true" height="520" min_height="520" min_width="630"
+ name="Model Preview" title="Upload Model" width="630">
<string name="status_idle">Idle</string>
<string name="status_reading_file">Loading...</string>
<string name="status_generating_meshes">Generating Meshes...</string>
- <string name="missing_lod">Cannot upload, missing required level of detail.</string>
- <string name="bad_lod">Cannot upload, supplied levels of detail invalid.</string>"
- <string name="too_heavy">Too many vertices.</string>
- <string name="required">Required</string>
- <string name="good">Good</string>
- <string name="mesh_mismatch">Submesh count mismatch.</string>
- <string name="model_mismatch">Model count mismatch.</string>
-
- <combo_box bottom_delta="20" follows="right|top" height="18" label="Preview"
- left="450" name="preview_lod_combo" width="120" tool_tip="LOD to view in preview render">
- <combo_item name="preview_lowest">
+ <string name="high">High</string>
+ <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_na">N/A</string>
+ <string name="mesh_status_none">None</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">
+ 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_item name="lowest">
Lowest
</combo_item>
- <combo_item name="preview_low">
+ <combo_item name="low">
Low
</combo_item>
- <combo_item name="preview_medium">
+ <combo_item name="medium">
Medium
</combo_item>
- <combo_item name="preview_high">
+ <combo_item name="high">
High
</combo_item>
- <combo_item name="preview_high">
- Physics
- </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."/>
+
+ <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"/>
+
+ <tab_container
+ follows="right|top|bottom"
+ top="15"
+ left="330"
+ height="475"
+ width="280"
+ 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"
+ label="Level of Detail"
+ name="lod_panel">
+
+ <text left="10" width="240" bottom="20" height="15" follows="left|top" name="lod_table_header">
+ Select Level of Detail:
+ </text>
+
+ <text valign="center" halign="center" bg_visible="true" bottom_delta="16" left="75" width="65" height="18" follows="left|top" value="Triangles"/>
+ <text valign="center" halign="center" bg_visible="true" left_pad="0" width="65" height="18" follows="left|top" value="Vertices"/>
+ <text valign="center" halign="center" left_pad="0" width="65" bg_visible="true" height="18" follows="left|top" value="Status"/>
+
+ <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="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="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="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">
+ Level of Detail: [DETAIL]
+ </text>
+
+ <text top_pad="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>
+
+ <line_editor follows="left|top" bottom_delta="-60" 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:
+ </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>
+ <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
+ </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"/>
+ </panel>
+
+ <!-- PANEL -->
+ <panel
+ border="true"
+ label="Physics"
+ name="physics_panel">
+
+ <!-- PHYSICS STEP ONE-->
+ <panel
+ follows="top|left"
+ name="physics step 1"
+ left="0"
+ top="0"
+ width="260"
+ height="450"
+ visible="true">
+
+ <text follows="left|top" bottom="40" height="30" left="10" font="SansSerifBig">
+ Step 1: Geometry
+ </text>
+
+ <radio_group follows="top|left" top_pad="5" width="240" height="70" name="physics_load_radio" value="physics_load_from_file">
+ <radio_item bottom="50" name="physics_load_from_file" label="Load from file"/>
+ <radio_item bottom="0" name="physics_use_lod" label="Use Level of Detail"/>
+ </radio_group>
+
+ <line_editor follows="left|top" bottom_delta="-25" width="140" left="30" value="" name="physics_file" height="20"/>
+ <button bottom_delta="3" name="physics_browse" label="Browse..." left_pad="5" follows="left|top" width="70" height="25"/>
+
+ <combo_box left="30" bottom_delta="40" follows="left|top" height="18"
+ name="physics_lod_combo" width="90" tool_tip="LOD to use for physics shape">
+ <combo_item name="physics_lowest">
+ Lowest
+ </combo_item>
+ <combo_item name="physics_low">
+ Low
+ </combo_item>
+ <combo_item name="physics_medium">
+ Medium
+ </combo_item>
+ <combo_item name="physics_high">
+ High
+ </combo_item>
+ </combo_box>
+
+ <!--
+ <text follows="top|left" name="physics_triangles" top_pad="15" height="15" left="10">
+ Triangles: [TRIANGLES]
+ </text>
+ <text follows="top|left" name="physics_hulls" top_pad="5" height="15">
+ Hulls: [HULLS]
+ </text>
+ <text follows="top|left" name="physics_points" top_pad="5" height="15">
+ Points: [POINTS]
+ </text>
+
+ <text follows="top|left" left="140" width="100" bottom_delta="-40" height="15">
+ Layer:
+ </text>
+ <combo_box name="physics_layer" follows="top|left" width="100" height="20" top_pad="5"/>
+ -->
+
+ <button bottom="440" left="180" width="80" follows="bottom|right" label="Optimize" name="physics_optimize" height="20"/>
+
+ </panel>
+
+
+ <!-- PHYSICS STEP 2-->
+ <panel
+ follows="top|left"
+ name="physics step 2"
+ left="0"
+ top="0"
+ width="260"
+ height="450"
+ visible="false">
+
+ <text follows="left|top" bottom="40" height="30" left="10" font="SansSerifBig">
+ Step 2: Decompose
+ </text>
+
+ <text top_pad="100" follows="top|left" height="15">
+ Decompose Method:
+ </text>
+ <combo_box name="Method" follows="top|left" top_pad="5" height="20" width="100"/>
+ <text top_pad="10" follows="top|left" height="15">
+ Quality:
+ </text>
+ <combo_box name="Decompose Quality" follows="top|left" top_pad="5" height="20" width="100"/>
+
+ <check_box name="Simplify Coplanar" follows="top|left" top_pad="10" height="15" label="Simplify Coplaner"/>
+ <check_box name="Close Holes (Slow)" follows="top|left" top_pad="10" height="15" label="Close Holes (slow)"/>
+ <slider name="Cosine%" width="240" follows="top|left" top_pad="10" height="20" label="Cosine %"/>
+
+ <text follows="top|left" top_pad="20" height="30" width="260">
+ "Note: Only models that have been Decomposed"
+ "can be made Physical or used as Vehicles."
+ </text>
+
+ <button bottom="440" left="90" width="80" follows="bottom|right" label="&lt;&lt; Back" name="decompose_back" height="20"/>
+ <button left_pad="5" width="90" follows="bottom|right" label="Decompose" name="Decompose" height="20"/>
+ </panel>
+
+
+ <!-- PHYSICS STEP 3 -->
+ <panel
+ follows="top|left"
+ name="physics step 3"
+ left="0"
+ top="0"
+ width="260"
+ height="450"
+ visible="false">
+
+ <text follows="left|top" bottom="40" height="30" left="10" font="SansSerifBig">
+ Step 3: Simplify
+ </text>
+
+ <text left="10" top_pad="100" height="15" width="240" follows="top|left">
+ Simplify Method:
+ </text>
+
+ <combo_box top_pad="5" height="20" width="100" follows="top|left" name="Simplify Method"/>
+
+ <slider name="Combine Quality" label="Combine Quality:" label_width="100" width="260" follows="top|left" top_pad="10" height="20"/>
+ <slider name="Detail Scale" label="Detail Scale:" label_width="100" width="260" follows="top|left" top_pad="10" height="20"/>
+ <slider name="Retain%" label="Retain %:" label_width="100" width="260" follows="top|left" top_pad="10" height="20"/>
+
+ <button bottom="440" left="90" width="80" follows="bottom|right" label="&lt;&lt; Back" name="simplify_back" height="20"/>
+ <button left_pad="5" width="90" follows="bottom|right" label="Simplify" name="Simplify" height="20"/>
+
+ </panel>
+
+ <!-- INFO PANEL -->
+ <panel
+ left="0"
+ top="35"
+ width="260"
+ height="100"
+ follows="left|top"
+ name="physics info"
+ visible="false">
+
+ <text follows="top|left" name="physics_triangles" top_pad="15" height="15" left="10">
+ Triangles: [TRIANGLES]
+ </text>
+ <text follows="top|left" name="physics_hulls" top_pad="5" height="15">
+ Hulls: [HULLS]
+ </text>
+ <text follows="top|left" name="physics_points" top_pad="5" height="15">
+ Points: [POINTS]
+ </text>
+
+ <text follows="top|left" left="140" width="100" bottom_delta="-40" height="15">
+ Layer:
+ </text>
+ <combo_box name="physics_layer" follows="top|left" width="100" height="20" top_pad="5"/>
+
+ <slider name="physics_explode" follows="top|left" top_pad="25" left="10" label="Explode" min_val="0.0" max_val="3.0" height="20" width="240"/>
+ </panel>
+ </panel>
+
+
+
+ </tab_container>
+
+ <!--
<button bottom_delta="0" left="10" width="120" name="auto fill" label="Generate LOD" tool_tip="Automatically generate levels of detail"/>
<button bottom_delta="0" left="140" width="120" name="smooth normals" label="Generate Normals" tool_tip="Regenerate normals based on mesh shape"/>
<button bottom_delta="0" left="260" width="120" name="consolidate" label="Consolidate" tool_tip="Combine similar submeshes (reduces number of submeshes)"/>
<button bottom_delta="30" left="260" width="120" name="scrub materials" label="Scrub Materials" tool_tip="Remove all material information (clear textures, set all colors to white)."/>
<spinner bottom_delta="0" left="140" width="120" height="16" initial_value="75" label_width="60" name="edge threshold" decimal_digits="0" min_val="0" max_val="180" increment="5" label="Hard Angle" tool_tip="Maximum angle that will be smoothed between triangles when using Generate Normals"/>
- <check_box bottom_delta="0" left="450" label="Show Edges" name="show edges" width="120" height="16" tool_tip="Render wireframe in preview window"/>
+
<text bottom_delta="30" follows="top|left" height="15" left="10" name="high_lod_label">
High LOD:
</text>
@@ -163,12 +472,7 @@
<check_box bottom_delta="20" follow="bottom|left" height="20" label="Joint Positions"
left="15" width="125" name="upload_joints" tool_tip="Upload joint position information (will override avatar joint positions when mesh is worn)."/>
- <text bottom_delta="35" follows="top|left" height="15" name="description_label">
- Description:
- <!-- Info: [PRIM_COST] prim equivalents, [TEXTURES] textures. -->
- </text>
- <line_editor bottom_delta="24" follows="top|left|right" height="19" max_length="254"
- name="description_form" width="280" />
+
<button bottom_delta="25" follows="bottom|left" height="20" label="Upload"
left="15" name="ok_btn" width="125" tool_tip="Upload to simulator"/>
@@ -178,11 +482,10 @@
<text bottom_delta="20" left="15" width="280" follows="top|left" height="15" name="upload_message">
[MESSAGE]
</text>
- <text bottom_delta="20" left="15" width="280" follows="top|left" height="15" name="streaming cost">
- Estimated Streaming Cost: [COST]
- </text>
+
<spinner bottom_delta="20" label="Scale" left="15" width="120" name="debug scale" decimal_digits="3" increment="0.1" min_val="0" max_val="64" initial_value="1" tool_tip="Multiplier for incoming object scale. If incoming dimensions are very small or very large, modify this value to get dimensions into an acceptable range."/>
<text bottom_delta="30" left="15" width="280" follows="top|left" height="15" name="dimensions">
Model Dimensions: [X]m x [Y]m x [Z]m
</text>
+ -->
</floater>