summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/app_settings/settings.xml199
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/previewV.glsl6
-rw-r--r--indra/newview/llcontrolavatar.cpp2
-rw-r--r--indra/newview/lldynamictexture.cpp15
-rw-r--r--indra/newview/llfloatermodelpreview.cpp439
-rw-r--r--indra/newview/llfloatermodelpreview.h2
-rw-r--r--indra/newview/llfloaterpreference.cpp121
-rw-r--r--indra/newview/llfloaterpreference.h15
-rw-r--r--indra/newview/llsearchableui.cpp159
-rw-r--r--indra/newview/llsearchableui.h121
-rw-r--r--indra/newview/llstatusbar.cpp92
-rw-r--r--indra/newview/llstatusbar.h17
-rw-r--r--indra/newview/lltexturectrl.cpp12
-rw-r--r--indra/newview/llviewerobject.cpp1
-rw-r--r--indra/newview/llvoavatar.cpp4
-rw-r--r--indra/newview/llworldmapview.cpp6
-rw-r--r--indra/newview/pipeline.cpp6
-rw-r--r--indra/newview/skins/default/xui/en/floater_model_preview.xml368
-rw-r--r--indra/newview/skins/default/xui/en/floater_preferences.xml42
-rw-r--r--indra/newview/skins/default/xui/en/panel_status_bar.xml40
21 files changed, 1363 insertions, 306 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 33886acb71..a8019ee168 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -532,6 +532,7 @@ set(viewer_SOURCE_FILES
llscrollingpanelparam.cpp
llscrollingpanelparambase.cpp
llsculptidsize.cpp
+ llsearchableui.cpp
llsearchcombobox.cpp
llsearchhistory.cpp
llsecapi.cpp
@@ -1148,6 +1149,7 @@ set(viewer_HEADER_FILES
llscrollingpanelparam.h
llscrollingpanelparambase.h
llsculptidsize.h
+ llsearchableui.h
llsearchcombobox.h
llsearchhistory.h
llsecapi.h
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 0eef5120eb..72301e7d14 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -6628,8 +6628,190 @@
<key>Value</key>
<integer>600</integer>
</map>
+ <key>MeshPreviewCanvasColor</key>
+ <map>
+ <key>Comment</key>
+ <string>Canvas colour for the Mesh uploader</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Color4</string>
+ <key>Value</key>
+ <array>
+ <real>0.169</real>
+ <real>0.169</real>
+ <real>0.169</real>
+ <real>1.0</real>
+ </array>
+ </map>
+ <key>MeshPreviewEdgeColor</key>
+ <map>
+ <key>Comment</key>
+ <string>Edge colour for the Mesh uploader preview</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Color4</string>
+ <key>Value</key>
+ <array>
+ <real>0.4</real>
+ <real>0.4</real>
+ <real>0.4</real>
+ <real>1.0</real>
+ </array>
+ </map>
+ <key>MeshPreviewBaseColor</key>
+ <map>
+ <key>Comment</key>
+ <string>base diffuse colour for the Mesh uploader</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Color4</string>
+ <key>Value</key>
+ <array>
+ <real>1.0</real>
+ <real>1.0</real>
+ <real>1.0</real>
+ <real>1.0</real>
+ </array>
+ </map>
+ <key>MeshPreviewBrightnessColor</key>
+ <map>
+ <key>Comment</key>
+ <string>Brightness modifier</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Color3</string>
+ <key>Value</key>
+ <array>
+ <real>0.9</real>
+ <real>0.9</real>
+ <real>0.9</real>
+ </array>
+ </map>
+ <key>MeshPreviewEdgeWidth</key>
+ <map>
+ <key>Comment</key>
+ <string>line thickness used when display edges is selected in mesh preview</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>1.0</real>
+ </map>
+ <key>MeshPreviewPhysicsEdgeColor</key>
+ <map>
+ <key>Comment</key>
+ <string>Edge colour for the Mesh uploader physics preview</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Color4</string>
+ <key>Value</key>
+ <array>
+ <real>0.0</real>
+ <real>0.25</real>
+ <real>0.5</real>
+ <real>0.25</real>
+ </array>
+ </map>
+ <key>MeshPreviewPhysicsFillColor</key>
+ <map>
+ <key>Comment</key>
+ <string>Fill colour for the Mesh uploader physics preview</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Color4</string>
+ <key>Value</key>
+ <array>
+ <real>0.0</real>
+ <real>0.5</real>
+ <real>1.0</real>
+ <real>0.5</real>
+ </array>
+ </map>
+ <key>MeshPreviewPhysicsEdgeWidth</key>
+ <map>
+ <key>Comment</key>
+ <string>line thickness used when display physics is selected in mesh preview</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>1.0</real>
+ </map>
+ <key>MeshPreviewDegenerateEdgeColor</key>
+ <map>
+ <key>Comment</key>
+ <string>Edge colour for the Mesh uploader Degenerate preview</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Color4</string>
+ <key>Value</key>
+ <array>
+ <real>1.0</real>
+ <real>0.0</real>
+ <real>0.0</real>
+ <real>1.0</real>
+ </array>
+ </map>
+ <key>MeshPreviewDegenerateFillColor</key>
+ <map>
+ <key>Comment</key>
+ <string>Fill colour for the Mesh uploader Degenerate preview</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Color4</string>
+ <key>Value</key>
+ <array>
+ <real>1.0</real>
+ <real>0.0</real>
+ <real>0.0</real>
+ <real>0.5</real>
+ </array>
+ </map>
+ <key>MeshPreviewDegenerateEdgeWidth</key>
+ <map>
+ <key>Comment</key>
+ <string>line thickness used when display Degenerate is selected in mesh preview</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>3.0</real>
+ </map>
+ <key>MeshPreviewDegeneratePointSize</key>
+ <map>
+ <key>Comment</key>
+ <string>Large point size used to highlight degenerate triangle vertices in Mesh preview</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>8.0</real>
+ </map>
+ <key>MeshPreviewZoomLimit</key>
+ <map>
+ <key>Comment</key>
+ <string>Maximum Zoom level in preview</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>10.0</real>
+ </map>
<key>MigrateCacheDirectory</key>
- <map>
+ <map>
<key>Comment</key>
<string>Check for old version of disk cache to migrate to current location</string>
<key>Persist</key>
@@ -7868,7 +8050,17 @@
<key>Value</key>
<integer>13</integer>
</map>
-
+ <key>PreviewRenderSize</key>
+ <map>
+ <key>Comment</key>
+ <string>Resolution of the image rendered for the mesh upload preview</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>1024</integer>
+ </map>
<key>PreviewAmbientColor</key>
<map>
<key>Comment</key>
@@ -7885,8 +8077,6 @@
<real>1.0</real>
</array>
</map>
-
-
<key>PreviewDiffuse0</key>
<map>
<key>Comment</key>
@@ -16291,3 +16481,4 @@
</map>
</llsd>
+
diff --git a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
index 7f3f84398b..de2ea2a065 100644
--- a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
@@ -91,8 +91,8 @@ void main()
// Collect normal lights (need to be divided by two, as we later multiply by 2)
col.rgb += light_diffuse[1].rgb * calcDirectionalLight(norm, light_position[1].xyz);
- col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].z);
- col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].z);
-
+ col.rgb += light_diffuse[2].rgb * calcDirectionalLight(norm, light_position[2].xyz);
+ col.rgb += light_diffuse[3].rgb * calcDirectionalLight(norm, light_position[3].xyz);
+ col /= 2.0;
vertex_color = col*color;
}
diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp
index d3fd5813a0..0f02c23cb0 100644
--- a/indra/newview/llcontrolavatar.cpp
+++ b/indra/newview/llcontrolavatar.cpp
@@ -60,6 +60,8 @@ LLControlAvatar::LLControlAvatar(const LLUUID& id, const LLPCode pcode, LLViewer
// virtual
LLControlAvatar::~LLControlAvatar()
{
+ // Should already have been unlinked before destruction
+ llassert(!mRootVolp);
}
// virtual
diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index fa9a0712fa..e180d91461 100644
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -125,11 +125,11 @@ BOOL LLViewerDynamicTexture::render()
//-----------------------------------------------------------------------------
void LLViewerDynamicTexture::preRender(BOOL clear_depth)
{
- //only images up to 512x512 are supported
- llassert(mFullHeight <= 512);
- llassert(mFullWidth <= 512);
+ gPipeline.allocatePhysicsBuffer();
+ llassert(mFullWidth <= static_cast<S32>(gPipeline.mPhysicsDisplay.getWidth()));
+ llassert(mFullHeight <= static_cast<S32>(gPipeline.mPhysicsDisplay.getHeight()));
- if (gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI)
+ if (gGLManager.mHasFramebufferObject && gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsATI)
{ //using offscreen render target, just use the bottom left corner
mOrigin.set(0, 0);
}
@@ -216,11 +216,10 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
return TRUE;
}
- bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI;
-
+ bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsATI;
if (use_fbo)
{
- gPipeline.mWaterDis.bindTarget();
+ gPipeline.mPhysicsDisplay.bindTarget();
}
LLGLSLShader::bindNoShader();
@@ -258,7 +257,7 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
if (use_fbo)
{
- gPipeline.mWaterDis.flush();
+ gPipeline.mPhysicsDisplay.flush();
}
return ret;
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 818d364c3e..c86eed2192 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -427,8 +427,8 @@ void LLFloaterModelPreview::initModelPreview()
{
delete mModelPreview;
}
-
- mModelPreview = new LLModelPreview(512, 512, this );
+ auto size = gSavedSettings.getS32("PreviewRenderSize");
+ mModelPreview = new LLModelPreview(size, size, this );
mModelPreview->setPreviewTarget(16.f);
mModelPreview->setDetailsCallback(boost::bind(&LLFloaterModelPreview::setDetails, this, _1, _2, _3, _4, _5));
mModelPreview->setModelUpdatedCallback(boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this, _1));
@@ -438,8 +438,14 @@ void LLFloaterModelPreview::onViewOptionChecked(LLUICtrl* ctrl)
{
if (mModelPreview)
{
- mModelPreview->mViewOption[ctrl->getName()] = !mModelPreview->mViewOption[ctrl->getName()];
-
+ auto name = ctrl->getName();
+ mModelPreview->mViewOption[name] = !mModelPreview->mViewOption[name];
+ if (name == "show_physics")
+ {
+ auto enabled = mModelPreview->mViewOption[name];
+ childSetEnabled("physics_explode", enabled);
+ childSetVisible("physics_explode", enabled);
+ }
mModelPreview->refresh();
}
}
@@ -653,6 +659,42 @@ void LLFloaterModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit)
}
}
+void LLFloaterModelPreview::draw3dPreview()
+{
+ gGL.color3f(1.f, 1.f, 1.f);
+
+ gGL.getTexUnit(0)->bind(mModelPreview);
+
+
+ LLView* preview_panel = getChild<LLView>("preview_panel");
+
+ if (!preview_panel)
+ {
+ LL_WARNS() << "preview_panel not found in floater definition" << LL_ENDL;
+ }
+ LLRect rect = preview_panel->getRect();
+
+ if (rect != mPreviewRect)
+ {
+ mModelPreview->refresh();
+ mPreviewRect = preview_panel->getRect();
+ }
+
+ gGL.begin( LLRender::QUADS );
+ {
+ gGL.texCoord2f(0.f, 1.f);
+ gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mTop-1);
+ gGL.texCoord2f(0.f, 0.f);
+ gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mBottom);
+ gGL.texCoord2f(1.f, 0.f);
+ gGL.vertex2i(mPreviewRect.mRight-1, mPreviewRect.mBottom);
+ gGL.texCoord2f(1.f, 1.f);
+ gGL.vertex2i(mPreviewRect.mRight-1, mPreviewRect.mTop-1);
+ }
+ gGL.end();
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+}
//-----------------------------------------------------------------------------
// draw()
@@ -1218,6 +1260,7 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp)
, mResetJoints( false )
, mModelNoErrors( true )
, mLastJointUpdate( false )
+, mHasDegenerate( false )
{
mNeedsUpdate = TRUE;
mCameraDistance = 0.f;
@@ -2707,8 +2750,20 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim
void LLModelPreview::updateStatusMessages()
{
+// bit mask values for physics errors. used to prevent overwrite of single line status
+// TODO: use this to provied multiline status
+ enum PhysicsError
+ {
+ NONE=0,
+ NOHAVOK=1,
+ DEGENERATE=2,
+ TOOMANYHULLS=4,
+ TOOMANYVERTSINHULL=8
+ };
+
assert_main_thread();
+ U32 has_physics_error{ PhysicsError::NONE }; // physics error bitmap
//triangle/vertex/submesh count for each mesh asset for each lod
std::vector<S32> tris[LLModel::NUM_LODS];
std::vector<S32> verts[LLModel::NUM_LODS];
@@ -2798,43 +2853,57 @@ void LLModelPreview::updateStatusMessages()
mMaxTriangleLimit = total_tris[LLModel::LOD_HIGH];
}
- bool has_degenerate = false;
-
+ mHasDegenerate = false;
{//check for degenerate triangles in physics mesh
U32 lod = LLModel::LOD_PHYSICS;
const LLVector4a scale(0.5f);
- for (U32 i = 0; i < mModel[lod].size() && !has_degenerate; ++i)
+ for (U32 i = 0; i < mModel[lod].size() && !mHasDegenerate; ++i)
{ //for each model in the lod
if (mModel[lod][i] && mModel[lod][i]->mPhysics.mHull.empty())
{ //no decomp exists
S32 cur_submeshes = mModel[lod][i]->getNumVolumeFaces();
- for (S32 j = 0; j < cur_submeshes && !has_degenerate; ++j)
+ for (S32 j = 0; j < cur_submeshes && !mHasDegenerate; ++j)
{ //for each submesh (face), add triangles and vertices to current total
LLVolumeFace& face = mModel[lod][i]->getVolumeFace(j);
- for (S32 k = 0; (k < face.mNumIndices) && !has_degenerate; )
+ for (S32 k = 0; (k < face.mNumIndices) && !mHasDegenerate; )
{
- U16 index_a = face.mIndices[k+0];
- U16 index_b = face.mIndices[k+1];
- U16 index_c = face.mIndices[k+2];
-
- LLVector4a v1; v1.setMul(face.mPositions[index_a], scale);
- LLVector4a v2; v2.setMul(face.mPositions[index_b], scale);
- LLVector4a v3; v3.setMul(face.mPositions[index_c], scale);
+ U16 index_a = face.mIndices[k + 0];
+ U16 index_b = face.mIndices[k + 1];
+ U16 index_c = face.mIndices[k + 2];
- if (ll_is_degenerate(v1,v2,v3))
+ if (index_c == 0 && index_b == 0 && index_a == 0) // test in reverse as 3rd index is less likely to be 0 in a normal case
{
- has_degenerate = true;
+ LL_DEBUGS("MeshValidation") << "Empty placeholder triangle (3 identical index 0 verts) ignored" << LL_ENDL;
}
else
{
- k += 3;
+ LLVector4a v1; v1.setMul(face.mPositions[index_a], scale);
+ LLVector4a v2; v2.setMul(face.mPositions[index_b], scale);
+ LLVector4a v3; v3.setMul(face.mPositions[index_c], scale);
+ if (ll_is_degenerate(v1, v2, v3))
+ {
+ mHasDegenerate = true;
+ }
}
+ k += 3;
}
}
}
}
}
+ // flag degenerates here rather than deferring to a MAV error later
+ mFMP->childSetVisible("physics_status_message_text", mHasDegenerate); //display or clear
+ auto degenerateIcon = mFMP->getChild<LLIconCtrl>("physics_status_message_icon");
+ degenerateIcon->setVisible(mHasDegenerate);
+ if (mHasDegenerate)
+ {
+ has_physics_error |= PhysicsError::DEGENERATE;
+ mFMP->childSetValue("physics_status_message_text", mFMP->getString("phys_status_degenerate_triangles"));
+ LLUIImagePtr img = LLUI::getUIImage("ModelImport_Status_Error");
+ degenerateIcon->setImage(img);
+ }
+
mFMP->childSetTextArg("submeshes_info", "[SUBMESHES]", llformat("%d", total_submeshes[LLModel::LOD_HIGH]));
std::string mesh_status_na = mFMP->getString("mesh_status_na");
@@ -2959,14 +3028,22 @@ void LLModelPreview::updateStatusMessages()
}
}
}
- mFMP->childSetVisible("physics_status_message_text", physExceededVertexLimit);
- LLIconCtrl* physStatusIcon = mFMP->getChild<LLIconCtrl>("physics_status_message_icon");
- physStatusIcon->setVisible(physExceededVertexLimit);
+
if (physExceededVertexLimit)
{
- mFMP->childSetValue("physics_status_message_text", mFMP->getString("phys_status_vertex_limit_exceeded"));
- LLUIImagePtr img = LLUI::getUIImage("ModelImport_Status_Warning");
- physStatusIcon->setImage(img);
+ has_physics_error |= PhysicsError::TOOMANYVERTSINHULL;
+ }
+
+ if (!(has_physics_error & PhysicsError::DEGENERATE)){ // only update this field (incluides clearing it) if it is not already in use.
+ mFMP->childSetVisible("physics_status_message_text", physExceededVertexLimit);
+ LLIconCtrl* physStatusIcon = mFMP->getChild<LLIconCtrl>("physics_status_message_icon");
+ physStatusIcon->setVisible(physExceededVertexLimit);
+ if (physExceededVertexLimit)
+ {
+ mFMP->childSetValue("physics_status_message_text", mFMP->getString("phys_status_vertex_limit_exceeded"));
+ LLUIImagePtr img = LLUI::getUIImage("ModelImport_Status_Warning");
+ physStatusIcon->setImage(img);
+ }
}
if (getLoadState() >= LLModelLoader::ERROR_PARSING)
@@ -2996,11 +3073,15 @@ void LLModelPreview::updateStatusMessages()
}
}
- // Todo: investigate use of has_degenerate and include into mModelNoErrors upload blocking mechanics
- // current use of has_degenerate won't block upload permanently - later checks will restore the button
- if (!mModelNoErrors || has_degenerate)
+ if (!mModelNoErrors || mHasDegenerate)
{
mFMP->childDisable("ok_btn");
+ mFMP->childDisable("calculate_btn");
+ }
+ else
+ {
+ mFMP->childEnable("ok_btn");
+ mFMP->childEnable("calculate_btn");
}
//add up physics triangles etc
@@ -3616,11 +3697,26 @@ BOOL LLModelPreview::render()
bool textures = mViewOption["show_textures"];
bool physics = mViewOption["show_physics"];
+ // Extra configurability, to be exposed later as controls?
+ static LLCachedControl<LLColor4> canvas_col(gSavedSettings, "MeshPreviewCanvasColor");
+ static LLCachedControl<LLColor4> edge_col(gSavedSettings, "MeshPreviewEdgeColor");
+ static LLCachedControl<LLColor4> base_col(gSavedSettings, "MeshPreviewBaseColor");
+ static LLCachedControl<LLColor3> brightness(gSavedSettings, "MeshPreviewBrightnessColor");
+ static LLCachedControl<F32> edge_width(gSavedSettings, "MeshPreviewEdgeWidth");
+ static LLCachedControl<LLColor4> phys_edge_col(gSavedSettings, "MeshPreviewPhysicsEdgeColor");
+ static LLCachedControl<LLColor4> phys_fill_col(gSavedSettings, "MeshPreviewPhysicsFillColor");
+ static LLCachedControl<F32> phys_edge_width(gSavedSettings, "MeshPreviewPhysicsEdgeWidth");
+ static LLCachedControl<LLColor4> deg_edge_col(gSavedSettings, "MeshPreviewDegenerateEdgeColor");
+ static LLCachedControl<LLColor4> deg_fill_col(gSavedSettings, "MeshPreviewDegenerateFillColor");
+ static LLCachedControl<F32> deg_edge_width(gSavedSettings, "MeshPreviewDegenerateEdgeWidth");
+ static LLCachedControl<F32> deg_point_size(gSavedSettings, "MeshPreviewDegeneratePointSize");
+
S32 width = getWidth();
S32 height = getHeight();
LLGLSUIDefault def;
LLGLDisable no_blend(GL_BLEND);
+
LLGLEnable cull(GL_CULL_FACE);
LLGLDepthTest depth(GL_TRUE);
LLGLDisable fog(GL_FOG);
@@ -3640,8 +3736,7 @@ BOOL LLModelPreview::render()
gGL.pushMatrix();
gGL.loadIdentity();
- gGL.color4f(0.169f, 0.169f, 0.169f, 1.f);
-
+ gGL.color4fv(static_cast<LLColor4>(canvas_col).mV);
gl_rect_2d_simple( width, height );
gGL.matrixMode(LLRender::MM_PROJECTION);
@@ -3789,8 +3884,7 @@ BOOL LLModelPreview::render()
stop_glerror();
gGL.pushMatrix();
- const F32 BRIGHTNESS = 0.9f;
- gGL.color3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS);
+ gGL.color4fv(edge_col().mV);
const U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0;
@@ -3875,16 +3969,15 @@ BOOL LLModelPreview::render()
}
else
{
- gGL.diffuseColor4f(1,1,1,1);
+ gGL.diffuseColor4fv(static_cast<LLColor4>(base_col).mV);
}
buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.diffuseColor3f(0.4f, 0.4f, 0.4f);
-
+ gGL.diffuseColor4fv(static_cast<LLColor4>(edge_col).mV);
if (edges)
{
- glLineWidth(3.f);
+ glLineWidth(edge_width);
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);
@@ -3897,10 +3990,9 @@ BOOL LLModelPreview::render()
if (physics)
{
glClear(GL_DEPTH_BUFFER_BIT);
-
- for (U32 i = 0; i < 2; i++)
+ for (U32 pass = 0; pass < 2; pass++)
{
- if (i == 0)
+ if (pass == 0)
{ //depth only pass
gGL.setColorMask(false, false);
}
@@ -3910,8 +4002,8 @@ BOOL LLModelPreview::render()
}
//enable alpha blending on second pass but not first pass
- LLGLState blend(GL_BLEND, i);
-
+ LLGLState blend(GL_BLEND, pass);
+
gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
@@ -3920,175 +4012,187 @@ BOOL LLModelPreview::render()
LLModel* model = instance.mLOD[LLModel::LOD_PHYSICS];
- if (!model)
- {
- continue;
- }
+ if (!model)
+ {
+ continue;
+ }
- gGL.pushMatrix();
- LLMatrix4 mat = instance.mTransform;
+ gGL.pushMatrix();
+ LLMatrix4 mat = instance.mTransform;
- gGL.multMatrix((GLfloat*) mat.mMatrix);
+ gGL.multMatrix((GLfloat*)mat.mMatrix);
- bool render_mesh = true;
+ bool render_mesh = true;
+ LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread;
+ if (decomp)
+ {
+ LLMutexLock(decomp->mMutex);
- LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread;
- if (decomp)
- {
- LLMutexLock(decomp->mMutex);
+ LLModel::Decomposition& physics = model->mPhysics;
- LLModel::Decomposition& physics = model->mPhysics;
+ if (!physics.mHull.empty())
+ {
+ render_mesh = false;
- if (!physics.mHull.empty())
- {
- render_mesh = false;
+ if (physics.mMesh.empty())
+ { //build vertex buffer for physics mesh
+ gMeshRepo.buildPhysicsMesh(physics);
+ }
- if (physics.mMesh.empty())
- { //build vertex buffer for physics mesh
- gMeshRepo.buildPhysicsMesh(physics);
- }
-
- if (!physics.mMesh.empty())
- { //render hull instead of mesh
- for (U32 i = 0; i < physics.mMesh.size(); ++i)
+ if (!physics.mMesh.empty())
+ { //render hull instead of mesh
+ for (U32 i = 0; i < physics.mMesh.size(); ++i)
+ {
+ if (explode > 0.f)
{
- if (explode > 0.f)
- {
- gGL.pushMatrix();
+ gGL.pushMatrix();
- LLVector3 offset = model->mHullCenter[i]-model->mCenterOfHullCenters;
- offset *= explode;
+ LLVector3 offset = model->mHullCenter[i] - model->mCenterOfHullCenters;
+ offset *= explode;
- gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]);
- }
+ gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]);
+ }
- static std::vector<LLColor4U> hull_colors;
+ 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, 128));
- }
+ if (i + 1 >= hull_colors.size())
+ {
+ hull_colors.push_back(LLColor4U(rand() % 128 + 127, rand() % 128 + 127, rand() % 128 + 127, 128));
+ }
- gGL.diffuseColor4ubv(hull_colors[i].mV);
- LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions, physics.mMesh[i].mNormals);
+ gGL.diffuseColor4ubv(hull_colors[i].mV);
+ LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions, physics.mMesh[i].mNormals);
- if (explode > 0.f)
- {
- gGL.popMatrix();
- }
+ if (explode > 0.f)
+ {
+ gGL.popMatrix();
}
}
}
}
-
- if (render_mesh)
+ }
+
+ if (render_mesh)
+ {
+ if (mVertexBuffer[LLModel::LOD_PHYSICS].empty())
{
- if (mVertexBuffer[LLModel::LOD_PHYSICS].empty())
- {
- genBuffers(LLModel::LOD_PHYSICS, false);
- }
+ genBuffers(LLModel::LOD_PHYSICS, false);
+ }
- U32 num_models = mVertexBuffer[LLModel::LOD_PHYSICS][model].size();
+ U32 num_models = mVertexBuffer[LLModel::LOD_PHYSICS][model].size();
+ if (pass > 0){
for (U32 i = 0; i < num_models; ++i)
{
LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i];
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.diffuseColor4f(0.4f, 0.4f, 0.0f, 0.4f);
+ gGL.diffuseColor4fv(phys_fill_col().mV);
buffer->setBuffer(type_mask & buffer->getTypeMask());
- buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
-
- gGL.diffuseColor3f(1.f, 1.f, 0.f);
+ buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts() - 1, buffer->getNumIndices(), 0);
- glLineWidth(2.f);
+ gGL.diffuseColor4fv(phys_edge_col().mV);
+ glLineWidth(phys_edge_width);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
+ buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts() - 1, buffer->getNumIndices(), 0);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glLineWidth(1.f);
}
}
-
- gGL.popMatrix();
}
- glLineWidth(3.f);
- glPointSize(8.f);
- gPipeline.enableLightsFullbright(LLColor4::white);
- //show degenerate triangles
- LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
- LLGLDisable cull(GL_CULL_FACE);
- gGL.diffuseColor4f(1.f,0.f,0.f,1.f);
- const LLVector4a scale(0.5f);
+ gGL.popMatrix();
+ }
- for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
+ // only do this if mDegenerate was set in the preceding mesh checks [Check this if the ordering ever breaks]
+ if (pass > 0 && mHasDegenerate)
{
- LLModelInstance& instance = *iter;
-
- LLModel* model = instance.mLOD[LLModel::LOD_PHYSICS];
-
- if (!model)
+ glLineWidth(deg_edge_width);
+ glPointSize(deg_point_size);
+ //show degenerate triangles
+ LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
+ LLGLDisable cull(GL_CULL_FACE);
+ const LLVector4a scale(0.5f);
+
+ for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
{
- continue;
- }
+ LLModelInstance& instance = *iter;
- gGL.pushMatrix();
- LLMatrix4 mat = instance.mTransform;
+ LLModel* model = instance.mLOD[LLModel::LOD_PHYSICS];
- gGL.multMatrix((GLfloat*) mat.mMatrix);
+ if (!model)
+ {
+ continue;
+ }
+ gGL.pushMatrix();
+ LLMatrix4 mat = instance.mTransform;
- LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread;
- if (decomp)
- {
- LLMutexLock(decomp->mMutex);
+ gGL.multMatrix((GLfloat*)mat.mMatrix);
- LLModel::Decomposition& physics = model->mPhysics;
- if (physics.mHull.empty())
+ LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread;
+ if (decomp)
{
- 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];
+ LLMutexLock(decomp->mMutex);
- buffer->setBuffer(type_mask & buffer->getTypeMask());
+ LLModel::Decomposition& physics = model->mPhysics;
- LLStrider<LLVector3> pos_strider;
- buffer->getVertexStrider(pos_strider, 0);
- LLVector4a* pos = (LLVector4a*) pos_strider.get();
-
- LLStrider<U16> idx;
- buffer->getIndexStrider(idx, 0);
+ if (physics.mHull.empty())
+ {
+ if (mVertexBuffer[LLModel::LOD_PHYSICS].empty())
+ {
+ genBuffers(LLModel::LOD_PHYSICS, false);
+ }
- for (U32 i = 0; i < buffer->getNumIndices(); i += 3)
+ auto num_degenerate = 0;
+ auto num_models = mVertexBuffer[LLModel::LOD_PHYSICS][model].size();
+ for (U32 v = 0; v < num_models; ++v)
{
- LLVector4a v1; v1.setMul(pos[*idx++], scale);
- LLVector4a v2; v2.setMul(pos[*idx++], scale);
- LLVector4a v3; v3.setMul(pos[*idx++], scale);
+ LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][v];
+ if(buffer->getNumVerts() < 3)continue;
+
+ buffer->setBuffer(type_mask & buffer->getTypeMask());
- if (ll_is_degenerate(v1,v2,v3))
+ LLStrider<LLVector3> pos_strider;
+ buffer->getVertexStrider(pos_strider, 0);
+ LLVector4a* pos = (LLVector4a*)pos_strider.get();
+
+ LLStrider<U16> idx;
+ buffer->getIndexStrider(idx, 0);
+
+ LLVector4a v1, v2, v3;
+ for (U32 indices_offset = 0; indices_offset < buffer->getNumIndices(); indices_offset += 3)
{
- buffer->draw(LLRender::LINE_LOOP, 3, i);
- buffer->draw(LLRender::POINTS, 3, i);
+ v1.setMul(pos[*idx++], scale);
+ v2.setMul(pos[*idx++], scale);
+ v3.setMul(pos[*idx++], scale);
+
+ if (ll_is_degenerate(v1, v2, v3))
+ {
+ num_degenerate++;
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ gGL.diffuseColor3fv(deg_edge_col().mV);
+ buffer->drawRange(LLRender::TRIANGLES, 0, 2, 3, indices_offset);
+ buffer->drawRange(LLRender::POINTS, 0, 2, 3, indices_offset);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ gGL.diffuseColor3fv(deg_fill_col().mV);
+ buffer->drawRange(LLRender::TRIANGLES, 0, 2, 3, indices_offset);
+ }
}
}
}
}
- }
- gGL.popMatrix();
+ gGL.popMatrix();
+ }
+ glLineWidth(1.f);
+ glPointSize(1.f);
+ gPipeline.enableLightsPreview();
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
}
- glLineWidth(1.f);
- glPointSize(1.f);
- gPipeline.enableLightsPreview();
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
}
}
}
@@ -4170,11 +4274,11 @@ BOOL LLModelPreview::render()
}
buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0);
- gGL.diffuseColor3f(0.4f, 0.4f, 0.4f);
if (edges)
{
- glLineWidth(3.f);
+ gGL.diffuseColor4fv(edge_col().mV);
+ glLineWidth(edge_width);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
@@ -4237,8 +4341,9 @@ void LLModelPreview::rotate(F32 yaw_radians, F32 pitch_radians)
void LLModelPreview::zoom(F32 zoom_amt)
{
F32 new_zoom = mCameraZoom+zoom_amt;
-
- mCameraZoom = llclamp(new_zoom, 1.f, 10.f);
+ // TODO: stop clamping in render
+ static LLCachedControl<F32> zoom_limit(gSavedSettings, "MeshPreviewZoomLimit");
+ mCameraZoom = llclamp(new_zoom, 1.f, zoom_limit());
}
void LLModelPreview::pan(F32 right, F32 up)
@@ -4444,11 +4549,15 @@ void LLFloaterModelPreview::toggleCalculateButton(bool visible)
childSetTextArg("server_weight", "[SIM]", tbd);
childSetTextArg("physics_weight", "[PH]", tbd);
childSetTextArg("upload_fee", "[FEE]", tbd);
- childSetTextArg("price_breakdown", "[STREAMING]", tbd);
- childSetTextArg("price_breakdown", "[PHYSICS]", tbd);
- childSetTextArg("price_breakdown", "[INSTANCES]", tbd);
- childSetTextArg("price_breakdown", "[TEXTURES]", tbd);
- childSetTextArg("price_breakdown", "[MODEL]", tbd);
+ std::string dashes = hasString("--") ? getString("--") : "--";
+ childSetTextArg("price_breakdown", "[STREAMING]", dashes);
+ childSetTextArg("price_breakdown", "[PHYSICS]", dashes);
+ childSetTextArg("price_breakdown", "[INSTANCES]", dashes);
+ childSetTextArg("price_breakdown", "[TEXTURES]", dashes);
+ childSetTextArg("price_breakdown", "[MODEL]", dashes);
+ childSetTextArg("physics_breakdown", "[PCH]", dashes);
+ childSetTextArg("physics_breakdown", "[PM]", dashes);
+ childSetTextArg("physics_breakdown", "[PHU]", dashes);
}
}
@@ -4498,6 +4607,16 @@ void LLFloaterModelPreview::handleModelPhysicsFeeReceived()
childSetTextArg("price_breakdown", "[INSTANCES]", llformat("%d", result["upload_price_breakdown"]["mesh_instance"].asInteger()));
childSetTextArg("price_breakdown", "[TEXTURES]", llformat("%d", result["upload_price_breakdown"]["texture"].asInteger()));
childSetTextArg("price_breakdown", "[MODEL]", llformat("%d", result["upload_price_breakdown"]["model"].asInteger()));
+
+ childSetTextArg("physics_breakdown", "[PCH]", llformat("%0.3f", result["model_physics_cost"]["hull"].asReal()));
+ childSetTextArg("physics_breakdown", "[PM]", llformat("%0.3f", result["model_physics_cost"]["mesh"].asReal()));
+ childSetTextArg("physics_breakdown", "[PHU]", llformat("%0.3f", result["model_physics_cost"]["decomposition"].asReal()));
+ childSetTextArg("streaming_breakdown", "[STR_TOTAL]", llformat("%d", result["streaming_cost"].asInteger()));
+ childSetTextArg("streaming_breakdown", "[STR_HIGH]", llformat("%d", result["streaming_params"]["high_lod"].asInteger()));
+ childSetTextArg("streaming_breakdown", "[STR_MED]", llformat("%d", result["streaming_params"]["medium_lod"].asInteger()));
+ childSetTextArg("streaming_breakdown", "[STR_LOW]", llformat("%d", result["streaming_params"]["low_lod"].asInteger()));
+ childSetTextArg("streaming_breakdown", "[STR_LOWEST]", llformat("%d", result["streaming_params"]["lowest_lod"].asInteger()));
+
childSetVisible("upload_fee", true);
childSetVisible("price_breakdown", true);
mUploadBtn->setEnabled(isModelUploadAllowed());
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index 7ec6a58ac7..564f4c39de 100644
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -152,6 +152,7 @@ protected:
static void onAutoFillCommit(LLUICtrl*,void*);
void onLODParamCommit(S32 lod, bool enforce_tri_limit);
+ void draw3dPreview();
static void onExplodeCommit(LLUICtrl*, void*);
@@ -310,6 +311,7 @@ public:
static bool sIgnoreLoadedCallback;
std::vector<S32> mLodsQuery;
std::vector<S32> mLodsWithParsingError;
+ bool mHasDegenerate;
protected:
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index ac751a785d..c3dea73c05 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -117,6 +117,8 @@
#include "llfeaturemanager.h"
#include "llviewertexturelist.h"
+#include "llsearchableui.h"
+
const F32 BANDWIDTH_UPDATER_TIMEOUT = 0.5f;
char const* const VISIBILITY_DEFAULT = "default";
char const* const VISIBILITY_HIDDEN = "hidden";
@@ -393,6 +395,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
mCommitCallbackRegistrar.add("Pref.ClearLog", boost::bind(&LLConversationLog::onClearLog, &LLConversationLog::instance()));
mCommitCallbackRegistrar.add("Pref.DeleteTranscripts", boost::bind(&LLFloaterPreference::onDeleteTranscripts, this));
+ mCommitCallbackRegistrar.add("UpdateFilter", boost::bind(&LLFloaterPreference::onUpdateFilterTerm, this, false)); // <FS:ND/> Hook up for filtering
}
void LLFloaterPreference::processProperties( void* pData, EAvatarProcessorType type )
@@ -506,7 +509,10 @@ BOOL LLFloaterPreference::postBuild()
LLSliderCtrl* fov_slider = getChild<LLSliderCtrl>("camera_fov");
fov_slider->setMinValue(LLViewerCamera::getInstance()->getMinView());
fov_slider->setMaxValue(LLViewerCamera::getInstance()->getMaxView());
-
+
+ // Hook up and init for filtering
+ mFilterEdit = getChild<LLSearchEditor>("search_prefs_edit");
+ mFilterEdit->setKeystrokeCallback(boost::bind(&LLFloaterPreference::onUpdateFilterTerm, this, false));
return TRUE;
}
@@ -786,6 +792,13 @@ void LLFloaterPreference::onOpen(const LLSD& key)
save_btn->setEnabled(started);
delete_btn->setEnabled(started);
exceptions_btn->setEnabled(started);
+
+ collectSearchableItems();
+ if (!mFilterEdit->getText().empty())
+ {
+ mFilterEdit->setText(LLStringExplicit(""));
+ onUpdateFilterTerm(true);
+ }
}
void LLFloaterPreference::onVertexShaderEnable()
@@ -2985,3 +2998,109 @@ void LLFloaterPreferenceProxy::onChangeSocksSettings()
}
+void LLFloaterPreference::onUpdateFilterTerm(bool force)
+{
+ LLWString seachValue = utf8str_to_wstring( mFilterEdit->getValue() );
+ LLWStringUtil::toLower( seachValue );
+
+ if( !mSearchData || (mSearchData->mLastFilter == seachValue && !force))
+ return;
+
+ mSearchData->mLastFilter = seachValue;
+
+ if( !mSearchData->mRootTab )
+ return;
+
+ mSearchData->mRootTab->hightlightAndHide( seachValue );
+ LLTabContainer *pRoot = getChild< LLTabContainer >( "pref core" );
+ if( pRoot )
+ pRoot->selectFirstTab();
+}
+
+void collectChildren( LLView const *aView, ll::prefs::PanelDataPtr aParentPanel, ll::prefs::TabContainerDataPtr aParentTabContainer )
+{
+ if( !aView )
+ return;
+
+ llassert_always( aParentPanel || aParentTabContainer );
+
+ LLView::child_list_const_iter_t itr = aView->beginChild();
+ LLView::child_list_const_iter_t itrEnd = aView->endChild();
+
+ while( itr != itrEnd )
+ {
+ LLView *pView = *itr;
+ ll::prefs::PanelDataPtr pCurPanelData = aParentPanel;
+ ll::prefs::TabContainerDataPtr pCurTabContainer = aParentTabContainer;
+ if( !pView )
+ continue;
+ LLPanel const *pPanel = dynamic_cast< LLPanel const *>( pView );
+ LLTabContainer const *pTabContainer = dynamic_cast< LLTabContainer const *>( pView );
+ ll::ui::SearchableControl const *pSCtrl = dynamic_cast< ll::ui::SearchableControl const *>( pView );
+
+ if( pTabContainer )
+ {
+ pCurPanelData.reset();
+
+ pCurTabContainer = ll::prefs::TabContainerDataPtr( new ll::prefs::TabContainerData );
+ pCurTabContainer->mTabContainer = const_cast< LLTabContainer *>( pTabContainer );
+ pCurTabContainer->mLabel = pTabContainer->getLabel();
+ pCurTabContainer->mPanel = 0;
+
+ if( aParentPanel )
+ aParentPanel->mChildPanel.push_back( pCurTabContainer );
+ if( aParentTabContainer )
+ aParentTabContainer->mChildPanel.push_back( pCurTabContainer );
+ }
+ else if( pPanel )
+ {
+ pCurTabContainer.reset();
+
+ pCurPanelData = ll::prefs::PanelDataPtr( new ll::prefs::PanelData );
+ pCurPanelData->mPanel = pPanel;
+ pCurPanelData->mLabel = pPanel->getLabel();
+
+ llassert_always( aParentPanel || aParentTabContainer );
+
+ if( aParentTabContainer )
+ aParentTabContainer->mChildPanel.push_back( pCurPanelData );
+ else if( aParentPanel )
+ aParentPanel->mChildPanel.push_back( pCurPanelData );
+ }
+ else if( pSCtrl && pSCtrl->getSearchText().size() )
+ {
+ ll::prefs::SearchableItemPtr item = ll::prefs::SearchableItemPtr( new ll::prefs::SearchableItem() );
+ item->mView = pView;
+ item->mCtrl = pSCtrl;
+
+ item->mLabel = utf8str_to_wstring( pSCtrl->getSearchText() );
+ LLWStringUtil::toLower( item->mLabel );
+
+ llassert_always( aParentPanel || aParentTabContainer );
+
+ if( aParentPanel )
+ aParentPanel->mChildren.push_back( item );
+ if( aParentTabContainer )
+ aParentTabContainer->mChildren.push_back( item );
+ }
+ collectChildren( pView, pCurPanelData, pCurTabContainer );
+ ++itr;
+ }
+}
+
+void LLFloaterPreference::collectSearchableItems()
+{
+ mSearchData.reset( nullptr );
+ LLTabContainer *pRoot = getChild< LLTabContainer >( "pref core" );
+ if( mFilterEdit && pRoot )
+ {
+ mSearchData.reset(new ll::prefs::SearchData() );
+
+ ll::prefs::TabContainerDataPtr pRootTabcontainer = ll::prefs::TabContainerDataPtr( new ll::prefs::TabContainerData );
+ pRootTabcontainer->mTabContainer = pRoot;
+ pRootTabcontainer->mLabel = pRoot->getLabel();
+ mSearchData->mRootTab = pRootTabcontainer;
+
+ collectChildren( this, ll::prefs::PanelDataPtr(), pRootTabcontainer );
+ }
+}
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 4e51137df5..d609c42ebe 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -36,6 +36,7 @@
#include "llfloater.h"
#include "llavatarpropertiesprocessor.h"
#include "llconversationlog.h"
+#include "llsearcheditor.h"
class LLConversationLogObserver;
class LLPanelPreference;
@@ -47,6 +48,14 @@ class LLSliderCtrl;
class LLSD;
class LLTextBox;
+namespace ll
+{
+ namespace prefs
+ {
+ struct SearchData;
+ }
+}
+
typedef std::map<std::string, std::string> notifications_map;
typedef enum
@@ -205,6 +214,12 @@ private:
LLAvatarData mAvatarProperties;
std::string mSavedGraphicsPreset;
LOG_CLASS(LLFloaterPreference);
+
+ LLSearchEditor *mFilterEdit;
+ std::unique_ptr< ll::prefs::SearchData > mSearchData;
+
+ void onUpdateFilterTerm( bool force = false );
+ void collectSearchableItems();
};
class LLPanelPreference : public LLPanel
diff --git a/indra/newview/llsearchableui.cpp b/indra/newview/llsearchableui.cpp
new file mode 100644
index 0000000000..de90896548
--- /dev/null
+++ b/indra/newview/llsearchableui.cpp
@@ -0,0 +1,159 @@
+/**
+* @file llsearchableui.cpp
+*
+* $LicenseInfo:firstyear=2019&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2019, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+
+#include "llviewerprecompiledheaders.h"
+#include "llsearchableui.h"
+
+#include "llview.h"
+#include "lltabcontainer.h"
+#include "llmenugl.h"
+
+ll::prefs::SearchableItem::~SearchableItem()
+{}
+
+void ll::prefs::SearchableItem::setNotHighlighted()
+{
+ mCtrl->setHighlighted( false );
+}
+
+bool ll::prefs::SearchableItem::hightlightAndHide( LLWString const &aFilter )
+{
+ if( mCtrl->getHighlighted() )
+ return true;
+
+ LLView const *pView = dynamic_cast< LLView const* >( mCtrl );
+ if( pView && !pView->getVisible() )
+ return false;
+
+ if( aFilter.empty() )
+ {
+ mCtrl->setHighlighted( false );
+ return true;
+ }
+
+ if( mLabel.find( aFilter ) != LLWString::npos )
+ {
+ mCtrl->setHighlighted( true );
+ return true;
+ }
+
+ return false;
+}
+
+ll::prefs::PanelData::~PanelData()
+{}
+
+bool ll::prefs::PanelData::hightlightAndHide( LLWString const &aFilter )
+{
+ for( tSearchableItemList::iterator itr = mChildren.begin(); itr != mChildren.end(); ++itr )
+ (*itr)->setNotHighlighted( );
+
+ if (aFilter.empty())
+ {
+ return true;
+ }
+
+ bool bVisible(false);
+ for( tSearchableItemList::iterator itr = mChildren.begin(); itr != mChildren.end(); ++itr )
+ bVisible |= (*itr)->hightlightAndHide( aFilter );
+
+ for( tPanelDataList::iterator itr = mChildPanel.begin(); itr != mChildPanel.end(); ++itr )
+ bVisible |= (*itr)->hightlightAndHide( aFilter );
+
+ return bVisible;
+}
+
+bool ll::prefs::TabContainerData::hightlightAndHide( LLWString const &aFilter )
+{
+ for( tSearchableItemList::iterator itr = mChildren.begin(); itr != mChildren.end(); ++itr )
+ (*itr)->setNotHighlighted( );
+
+ bool bVisible(false);
+ for( tSearchableItemList::iterator itr = mChildren.begin(); itr != mChildren.end(); ++itr )
+ bVisible |= (*itr)->hightlightAndHide( aFilter );
+
+ for( tPanelDataList::iterator itr = mChildPanel.begin(); itr != mChildPanel.end(); ++itr )
+ {
+ bool bPanelVisible = (*itr)->hightlightAndHide( aFilter );
+ if( (*itr)->mPanel )
+ mTabContainer->setTabVisibility( (*itr)->mPanel, bPanelVisible );
+ bVisible |= bPanelVisible;
+ }
+
+ return bVisible;
+}
+
+ll::statusbar::SearchableItem::SearchableItem()
+ : mMenu(0)
+ , mCtrl(0)
+ , mWasHiddenBySearch( false )
+{ }
+
+void ll::statusbar::SearchableItem::setNotHighlighted( )
+{
+ for( tSearchableItemList::iterator itr = mChildren.begin(); itr != mChildren.end(); ++itr )
+ (*itr)->setNotHighlighted( );
+
+ if( mCtrl )
+ {
+ mCtrl->setHighlighted( false );
+
+ if( mWasHiddenBySearch )
+ mMenu->setVisible( TRUE );
+ }
+}
+
+bool ll::statusbar::SearchableItem::hightlightAndHide( LLWString const &aFilter )
+{
+ if( mMenu && !mMenu->getVisible() && !mWasHiddenBySearch )
+ return false;
+
+ setNotHighlighted( );
+
+ bool bVisible(false);
+ for( tSearchableItemList::iterator itr = mChildren.begin(); itr != mChildren.end(); ++itr )
+ bVisible |= (*itr)->hightlightAndHide( aFilter );
+
+ if( aFilter.empty() )
+ {
+ if( mCtrl )
+ mCtrl->setHighlighted( false );
+ return true;
+ }
+
+ if( mLabel.find( aFilter ) != LLWString::npos )
+ {
+ if( mCtrl )
+ mCtrl->setHighlighted( true );
+ return true;
+ }
+
+ if( mCtrl && !bVisible )
+ {
+ mWasHiddenBySearch = true;
+ mMenu->setVisible(FALSE);
+ }
+ return bVisible;
+}
diff --git a/indra/newview/llsearchableui.h b/indra/newview/llsearchableui.h
new file mode 100644
index 0000000000..42b2866fb6
--- /dev/null
+++ b/indra/newview/llsearchableui.h
@@ -0,0 +1,121 @@
+/**
+* @file llsearchableui.h
+*
+* $LicenseInfo:firstyear=2019&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2019, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+
+#ifndef LL_SEARCHABLE_UI_H
+#define LL_SEARCHABLE_UI_H
+
+class LLMenuItemGL;
+class LLView;
+class LLPanel;
+class LLTabContainer;
+
+#include "llsearchablecontrol.h"
+
+namespace ll
+{
+ namespace prefs
+ {
+ struct SearchableItem;
+ struct PanelData;
+ struct TabContainerData;
+
+ typedef boost::shared_ptr< SearchableItem > SearchableItemPtr;
+ typedef boost::shared_ptr< PanelData > PanelDataPtr;
+ typedef boost::shared_ptr< TabContainerData > TabContainerDataPtr;
+
+ typedef std::vector< TabContainerData > tTabContainerDataList;
+ typedef std::vector< SearchableItemPtr > tSearchableItemList;
+ typedef std::vector< PanelDataPtr > tPanelDataList;
+
+ struct SearchableItem
+ {
+ LLWString mLabel;
+ LLView const *mView;
+ ll::ui::SearchableControl const *mCtrl;
+
+ std::vector< boost::shared_ptr< SearchableItem > > mChildren;
+
+ virtual ~SearchableItem();
+
+ void setNotHighlighted();
+ virtual bool hightlightAndHide( LLWString const &aFilter );
+ };
+
+ struct PanelData
+ {
+ LLPanel const *mPanel;
+ std::string mLabel;
+
+ std::vector< boost::shared_ptr< SearchableItem > > mChildren;
+ std::vector< boost::shared_ptr< PanelData > > mChildPanel;
+
+ virtual ~PanelData();
+
+ virtual bool hightlightAndHide( LLWString const &aFilter );
+ };
+
+ struct TabContainerData: public PanelData
+ {
+ LLTabContainer *mTabContainer;
+ virtual bool hightlightAndHide( LLWString const &aFilter );
+ };
+
+ struct SearchData
+ {
+ TabContainerDataPtr mRootTab;
+ LLWString mLastFilter;
+ };
+ }
+ namespace statusbar
+ {
+ struct SearchableItem;
+
+ typedef boost::shared_ptr< SearchableItem > SearchableItemPtr;
+
+ typedef std::vector< SearchableItemPtr > tSearchableItemList;
+
+ struct SearchableItem
+ {
+ LLWString mLabel;
+ LLMenuItemGL *mMenu;
+ tSearchableItemList mChildren;
+ ll::ui::SearchableControl const *mCtrl;
+ bool mWasHiddenBySearch;
+
+ SearchableItem();
+
+ void setNotHighlighted( );
+ bool hightlightAndHide( LLWString const &aFilter );
+ };
+
+ struct SearchData
+ {
+ SearchableItemPtr mRootMenu;
+ LLWString mLastFilter;
+ };
+ }
+}
+
+#endif
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index 43c0fbd53a..b893e4a058 100644
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -81,6 +81,8 @@
#include "llparcel.h"
#include "llstring.h"
#include "message.h"
+#include "llsearchableui.h"
+#include "llsearcheditor.h"
// system includes
#include <iomanip>
@@ -113,7 +115,9 @@ LLStatusBar::LLStatusBar(const LLRect& rect)
mBalance(0),
mHealth(100),
mSquareMetersCredit(0),
- mSquareMetersCommitted(0)
+ mSquareMetersCommitted(0),
+ mFilterEdit(NULL), // Edit for filtering
+ mSearchPanel(NULL) // Panel for filtering
{
setRect(rect);
@@ -239,6 +243,16 @@ BOOL LLStatusBar::postBuild()
mPanelNearByMedia->setFollows(FOLLOWS_TOP|FOLLOWS_RIGHT);
mPanelNearByMedia->setVisible(FALSE);
+ // Hook up and init for filtering
+ mFilterEdit = getChild<LLSearchEditor>( "search_menu_edit" );
+ mSearchPanel = getChild<LLPanel>( "menu_search_panel" );
+
+ //mSearchPanel->setVisible(gSavedSettings.getBOOL("MenuSearch"));
+ mFilterEdit->setKeystrokeCallback(boost::bind(&LLStatusBar::onUpdateFilterTerm, this));
+ mFilterEdit->setCommitCallback(boost::bind(&LLStatusBar::onUpdateFilterTerm, this));
+ collectSearchableItems();
+ //gSavedSettings.getControl("MenuSearch")->getCommitSignal()->connect(boost::bind(&LLStatusBar::updateMenuSearchVisibility, this, _2));
+
return TRUE;
}
@@ -318,6 +332,7 @@ void LLStatusBar::setVisibleForMouselook(bool visible)
mMediaToggle->setVisible(visible);
mSGBandwidth->setVisible(visible);
mSGPacketLoss->setVisible(visible);
+ mSearchPanel->setVisible(visible && gSavedSettings.getBOOL("MenuSearch"));
setBackgroundVisible(visible);
mIconPresets->setVisible(visible);
}
@@ -358,6 +373,12 @@ void LLStatusBar::setBalance(S32 balance)
balance_bg_view->setShape(balance_bg_rect);
}
+ // If the search panel is shown, move this according to the new balance width. Parcel text will reshape itself in setParcelInfoText
+ if (mSearchPanel && mSearchPanel->getVisible())
+ {
+ updateMenuSearchPosition();
+ }
+
if (mBalance && (fabs((F32)(mBalance - balance)) > gSavedSettings.getF32("UISndMoneyChangeThreshold")))
{
if (mBalance > balance)
@@ -570,6 +591,75 @@ void LLStatusBar::onVolumeChanged(const LLSD& newvalue)
refresh();
}
+void LLStatusBar::onUpdateFilterTerm()
+{
+ LLWString searchValue = utf8str_to_wstring( mFilterEdit->getValue() );
+ LLWStringUtil::toLower( searchValue );
+
+ if( !mSearchData || mSearchData->mLastFilter == searchValue )
+ return;
+
+ mSearchData->mLastFilter = searchValue;
+
+ mSearchData->mRootMenu->hightlightAndHide( searchValue );
+ gMenuBarView->needsArrange();
+}
+
+void collectChildren( LLMenuGL *aMenu, ll::statusbar::SearchableItemPtr aParentMenu )
+{
+ for( U32 i = 0; i < aMenu->getItemCount(); ++i )
+ {
+ LLMenuItemGL *pMenu = aMenu->getItem( i );
+
+ ll::statusbar::SearchableItemPtr pItem( new ll::statusbar::SearchableItem );
+ pItem->mCtrl = pMenu;
+ pItem->mMenu = pMenu;
+ pItem->mLabel = utf8str_to_wstring( pMenu->ll::ui::SearchableControl::getSearchText() );
+ LLWStringUtil::toLower( pItem->mLabel );
+ aParentMenu->mChildren.push_back( pItem );
+
+ LLMenuItemBranchGL *pBranch = dynamic_cast< LLMenuItemBranchGL* >( pMenu );
+ if( pBranch )
+ collectChildren( pBranch->getBranch(), pItem );
+ }
+
+}
+
+void LLStatusBar::collectSearchableItems()
+{
+ mSearchData.reset( new ll::statusbar::SearchData );
+ ll::statusbar::SearchableItemPtr pItem( new ll::statusbar::SearchableItem );
+ mSearchData->mRootMenu = pItem;
+ collectChildren( gMenuBarView, pItem );
+}
+
+void LLStatusBar::updateMenuSearchVisibility(const LLSD& data)
+{
+ bool visible = data.asBoolean();
+ mSearchPanel->setVisible(visible);
+ if (!visible)
+ {
+ mFilterEdit->setText(LLStringUtil::null);
+ onUpdateFilterTerm();
+ }
+ else
+ {
+ updateMenuSearchPosition();
+ }
+}
+
+void LLStatusBar::updateMenuSearchPosition()
+{
+ const S32 HPAD = 12;
+ LLRect balanceRect = getChildView("balance_bg")->getRect();
+ LLRect searchRect = mSearchPanel->getRect();
+ S32 w = searchRect.getWidth();
+ searchRect.mLeft = balanceRect.mLeft - w - HPAD;
+ searchRect.mRight = searchRect.mLeft + w;
+ mSearchPanel->setShape( searchRect );
+}
+
+
// Implements secondlife:///app/balance/request to request a L$ balance
// update via UDP message system. JC
class LLBalanceHandler : public LLCommandHandler
diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h
index a3326e752a..403d590aca 100644
--- a/indra/newview/llstatusbar.h
+++ b/indra/newview/llstatusbar.h
@@ -45,7 +45,15 @@ class LLPanelPresetsPulldown;
class LLPanelVolumePulldown;
class LLPanelNearByMedia;
class LLIconCtrl;
+class LLSearchEditor;
+namespace ll
+{
+ namespace statusbar
+ {
+ struct SearchData;
+ }
+}
class LLStatusBar
: public LLPanel
{
@@ -99,6 +107,15 @@ private:
static void onClickMediaToggle(void* data);
static void onClickBalance(void* data);
+ LLSearchEditor *mFilterEdit;
+ LLPanel *mSearchPanel;
+ void onUpdateFilterTerm();
+
+ std::unique_ptr< ll::statusbar::SearchData > mSearchData;
+ void collectSearchableItems();
+ void updateMenuSearchVisibility( const LLSD& data );
+ void updateMenuSearchPosition();
+
private:
LLTextBox *mTextTime;
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 1a2a10f721..1396a8546d 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -1096,6 +1096,10 @@ void LLTextureCtrl::setVisible( BOOL visible )
void LLTextureCtrl::setEnabled( BOOL enabled )
{
LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
+ if( floaterp )
+ {
+ floaterp->setActive(enabled);
+ }
if( enabled )
{
std::string tooltip;
@@ -1110,11 +1114,6 @@ void LLTextureCtrl::setEnabled( BOOL enabled )
closeDependentFloater();
}
- if( floaterp )
- {
- floaterp->setActive(enabled);
- }
-
mCaption->setEnabled( enabled );
LLView::setEnabled( enabled );
@@ -1215,9 +1214,10 @@ void LLTextureCtrl::showPicker(BOOL take_focus)
void LLTextureCtrl::closeDependentFloater()
{
LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
- if( floaterp )
+ if( floaterp && floaterp->isInVisibleChain())
{
floaterp->setOwner(NULL);
+ floaterp->setVisible(FALSE);
floaterp->closeFloater();
}
}
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 007adf2a72..ec1095813b 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -3100,6 +3100,7 @@ void LLViewerObject::unlinkControlAvatar()
if (mControlAvatar)
{
mControlAvatar->markForDeath();
+ mControlAvatar->mRootVolp = NULL;
mControlAvatar = NULL;
}
}
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 321f774210..2682c5b698 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -5992,7 +5992,7 @@ void LLVOAvatar::rebuildAttachmentOverrides()
LLViewerObject *vo = *at_it;
// Attached animated objects affect joints in their control
// avs, not the avs to which they are attached.
- if (!vo->isAnimatedObject())
+ if (vo && !vo->isAnimatedObject())
{
addAttachmentOverridesForObject(vo);
}
@@ -6043,7 +6043,7 @@ void LLVOAvatar::updateAttachmentOverrides()
LLViewerObject *vo = *at_it;
// Attached animated objects affect joints in their control
// avs, not the avs to which they are attached.
- if (!vo->isAnimatedObject())
+ if (vo && !vo->isAnimatedObject())
{
addAttachmentOverridesForObject(vo, &meshes_seen);
}
diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index b88631a71b..f1c23bdb2d 100644
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -465,7 +465,11 @@ void LLWorldMapView::draw()
mesg, 0,
llfloor(left + 3), llfloor(bottom + 2),
LLColor4::white,
- LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW);
+ LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW,
+ S32_MAX, //max_chars
+ sMapScale, //max_pixels
+ NULL,
+ TRUE); //use ellipses
}
}
}
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 40d6d325ba..c7626304ed 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -6582,7 +6582,7 @@ void LLPipeline::enableLightsPreview()
light->enable();
light->setPosition(light_pos);
light->setDiffuse(diffuse0);
- light->setAmbient(LLColor4::black);
+ light->setAmbient(ambient);
light->setSpecular(specular0);
light->setSpotExponent(0.f);
light->setSpotCutoff(180.f);
@@ -6593,7 +6593,7 @@ void LLPipeline::enableLightsPreview()
light->enable();
light->setPosition(light_pos);
light->setDiffuse(diffuse1);
- light->setAmbient(LLColor4::black);
+ light->setAmbient(ambient);
light->setSpecular(specular1);
light->setSpotExponent(0.f);
light->setSpotCutoff(180.f);
@@ -6603,7 +6603,7 @@ void LLPipeline::enableLightsPreview()
light->enable();
light->setPosition(light_pos);
light->setDiffuse(diffuse2);
- light->setAmbient(LLColor4::black);
+ light->setAmbient(ambient);
light->setSpecular(specular2);
light->setSpotExponent(0.f);
light->setSpotCutoff(180.f);
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 5a86eb06fb..a07fe99aef 100644
--- a/indra/newview/skins/default/xui/en/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml
@@ -2,12 +2,12 @@
<floater
can_close="true"
can_drag_on_left="false"
- can_minimize="false"
- can_resize="false"
- height="480"
- min_height="480"
- width="980"
- min_width="980"
+ can_minimize="true"
+ can_resize="true"
+ height="600"
+ min_height="600"
+ width="1024"
+ min_width="1024"
name="Model Preview"
title="UPLOAD MODEL"
help_topic="upload_model" >
@@ -33,19 +33,20 @@
<string name="mesh_status_missing_lod">Missing required level of detail.</string>
<string name="mesh_status_invalid_material_list">LOD materials are not a subset of reference model.</string>
<string name="phys_status_vertex_limit_exceeded">Some physical hulls exceed vertex limitations.</string>
+ <string name="phys_status_degenerate_triangles">The physics mesh too dense remove the small thin triangles (see preview)</string>
<string name="layer_all">All</string> <!-- Text to display in physics layer combo box for "all layers" -->
<string name="decomposing">Analyzing...</string>
<string name="simplifying">Simplifying...</string>
<string name="tbd">TBD</string>
-<panel
- follows="top|left"
- height="455"
- layout="topleft"
- left="3"
- name="left_panel"
- top_pad="10"
- width="630">
+ <panel
+ follows="top|left"
+ height="580"
+ layout="topleft"
+ left="3"
+ name="left_panel"
+ top_pad="0"
+ width="630">
<panel
follows="all"
height="50"
@@ -755,8 +756,9 @@
name="first_step_name"
text_color="White"
top_pad="0"
- width="210">
- Step 1: Level of Detail
+ width="210"
+ valign="center">
+ Step 1: Pick a physics model :
</text>
<combo_box
follows="left|top"
@@ -798,7 +800,7 @@
layout="topleft"
left="18"
name="physics_tab_border"
- top_pad="15"
+ top_pad="10"
width="589"/>
<panel
bg_alpha_color="0 0 0 0"
@@ -807,7 +809,7 @@
follows="top|left"
left="18"
name="physics analysis"
- top_pad="15"
+ top_pad="10"
visible="true"
width="589">
<text
@@ -819,7 +821,7 @@
name="method_label"
text_color="White"
top_pad="0">
- Step 2: Analyze
+ Step 2: Convert to hulls (optional)
</text>
<text
follows="top|left"
@@ -905,7 +907,7 @@
layout="topleft"
left="18"
name="physics_tab_border"
- top_pad="15"
+ top_pad="10"
width="589"/>
<panel
bg_alpha_color="0 0 0 0"
@@ -914,7 +916,7 @@
height="66"
left="18"
name="physics simplification"
- top_pad="15"
+ top_pad="10"
width="589">
<text
text_color="White"
@@ -1013,7 +1015,7 @@
layout="topleft"
left="18"
name="physics_tab_border"
- top_pad="15"
+ top_pad="10"
width="589"/>
<panel
bg_alpha_color="0 0 0 0"
@@ -1075,10 +1077,9 @@
follows="left|top"
height="19"
layout="topleft"
- left_pad="5"
- top_delta="0"
+ top_pad="5"
name="physics message"
- width="270">
+ width="589">
<icon
follows="left|top"
height="16"
@@ -1093,7 +1094,7 @@
layout="topleft"
left_pad="2"
name="physics_status_message_text"
- width="252"
+ width="573"
top_delta="3"/>
</panel>
</panel>
@@ -1219,13 +1220,14 @@
</panel>
</tab_container>
<panel
- follows="top|left"
- height="80"
- layout="top|left"
- left="0"
+ follows="top|left|bottom"
+ layout="topleft"
+ height="197"
+ left="4"
+ border="true"
name="weights_and_warning_panel"
top_pad="3"
- width="625">
+ width="629">
<button
follows="top|left"
label="Calculate weights &amp; fee"
@@ -1265,10 +1267,10 @@
label_color="White"
layout="topleft"
name="reset_btn"
- right="-2"
+ right="-5"
top="3"
height="20"
- width="275"/>
+ width="265"/>
<!-- ========== WEIGHTS ==========-->
<text
follows="top|left"
@@ -1287,7 +1289,7 @@
left_pad="0"
name="prim_weight"
top_delta="0"
- width="120"
+ width="130"
word_wrap="true">
Land impact: [EQ]
</text>
@@ -1297,7 +1299,7 @@
left_pad="0"
name="download_weight"
top_delta="0"
- width="100"
+ width="130"
word_wrap="true">
Download: [ST]
</text>
@@ -1307,7 +1309,7 @@
layout="topleft"
left_pad="0"
name="physics_weight"
- width="90"
+ width="130"
word_wrap="true">
Physics: [PH]
</text>
@@ -1317,17 +1319,148 @@
layout="topleft"
left_pad="0"
name="server_weight"
- width="83"
+ width="130"
word_wrap="true">
Server: [SIM]
</text>
- <!-- ========== NOTE MESSAGE ========== -->
+ <!-- =========== Cost breakdown ======== -->
+ <panel
+ border="true"
+ top_pad="5"
+ layout="topleft"
+ left="6"
+ name="price_breakdown_panel"
+ width="120"
+ height="100">
+ <text
+ layout="topleft"
+ left="3">
+ Price Breakdown
+ </text>
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="0"
+ layout="topleft"
+ left="3"
+ name="price_breakdown_border"
+ top_pad="5"
+ width="110"/>
+ <text
+ height="80"
+ top_pad="5"
+ layout="topleft"
+ left="3"
+ name="price_breakdown_labels"
+ width="70"
+ word_wrap="false">
+Download:
+Physics:
+Instances:
+Textures:
+Model:
+ </text>
+ <text
+ height="80"
+ top_delta="0"
+ layout="topleft"
+ halign="right"
+ left_pad="0"
+ name="price_breakdown"
+ width="40"
+ word_wrap="false">
+[STREAMING]
+[PHYSICS]
+[INSTANCES]
+[TEXTURES]
+[MODEL]
+ </text>
+ </panel>
+ <!--
+ Streaming breakdown numbers are available but not fully understood
+ uncommenting the following sections will display the numbers for debugging purposes
+ <text
+ height="80"
+ top_delta="0"
+ layout="topleft"
+ left="130"
+ name="streaming_breakdown_labels"
+ width="65"
+ word_wrap="true">
+Streaming/Download:
+High:
+Medium:
+Low:
+Lowest:
+ </text>
<text
+ height="80"
+ top_delta="0"
+ layout="topleft"
+ left_pad="0"
+ name="streaming_breakdown"
+ width="95"
+ word_wrap="true">
+[STR_TOTAL]
+[STR_HIGH]
+[STR_MED]
+[STR_LOW]
+[STR_LOWEST]
+ </text>-->
+ <panel
+ border="true"
+ layout="topleft"
+ left_pad="265"
+ name="physics_costs_panel"
+ width="120"
+ height="100">
+ <text
+ layout="topleft"
+ left="3">
+ Physics Costs
+ </text>
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="0"
+ layout="topleft"
+ left="3"
+ name="price_breakdown_border"
+ top_pad="5"
+ width="110"/>
+ <text
+ height="80"
+ top_pad="5"
+ layout="topleft"
+ left="5"
+ name="physics_breakdown_labels"
+ width="65">
+Base Hull:
+Mesh:
+Analysed:
+ </text>
+ <text
+ height="80"
+ top_delta="0"
+ layout="topleft"
+ left_pad="0"
+ name="physics_breakdown"
+ width="40"
+ halign="right"
+ word_wrap="false"
+ visible="true">
+[PCH]
+[PM]
+[PHU]
+ </text>-->
+ </panel>
+ <!-- ========== NOTE MESSAGE ========== -->
+ <text
font="SansSerif"
layout="topleft"
left="6"
name="warning_title"
- top_pad="10"
+ top_pad="5"
text_color="DrYellow"
visible="false"
width="40">
@@ -1346,104 +1479,110 @@
visible="false">
You dont have rights to upload mesh models. [[VURL] Find out how] to get certified.
</text>
- <text text_color="Yellow" layout="topleft" top_delta="20" left="6" name="status">[STATUS]</text>
-
+ <text text_color="Yellow" layout="topleft" top_pad="-1" left="6" name="status">
+[STATUS]
+ </text>
</panel>
-</panel>
-
-<text
- follows="left|top"
- layout="topleft"
- left="640"
- name="lod_label"
- text_color="White"
- top="13"
- height="15"
- width="290">
- Preview:
- </text>
-<panel
- border="true"
- bevel_style="none"
- follows="top|left"
- name="preview_panel"
- top_pad="4"
- width="290"
- height="290"/>
-
-<panel
- follows="all"
- height="130"
- layout="topleft"
- name="right_panel"
- top_pad="5"
- width="340">
- <combo_box
- top_pad="3"
+ </panel>
+ <panel
+ follows="top|left|bottom|right"
+ can_resize="true"
+ name="right_panel"
+ top="0"
+ left="640"
+ background_visible="true"
+ width="375">
+ <text
follows="left|top"
- height="18"
layout="topleft"
- name="preview_lod_combo"
- width="150"
- tool_tip="LOD to view in preview render">
+ left="0"
+ name="lod_label"
+ text_color="White"
+ top="13"
+ height="15"
+ width="290">
+ Preview:
+ </text>
+ <panel
+ can_resize="false"
+ follows="top|left"
+ height="20"
+ name="right_upper_panel"
+ top="8"
+ left="60"
+ background_visible="true"
+ width="315">
+ <combo_box
+ top_pad="3"
+ can_resize="false"
+ follows="top|left"
+ height="18"
+ layout="topleft"
+ name="preview_lod_combo"
+ width="75"
+ tool_tip="LOD to view in preview render">
<combo_item name="high"> High </combo_item>
<combo_item name="medium"> Medium </combo_item>
<combo_item name="low"> Low </combo_item>
<combo_item name="lowest"> Lowest </combo_item>
- </combo_box>
- <text
- follows="top|left"
- layout="topleft"
- text_color="White"
- top="5"
- left_pad="20"
- name="label_display"
- width="50">
- Display...
- </text>
- <check_box
- follows="top|left"
- label="Edges"
+ </combo_box>
+ </panel>
+ </panel>
+ <panel
+ border="true"
+ bevel_style="none"
+ follows="top|left|right|bottom"
+ layout="topleft"
+ name="preview_panel"
+ top="30"
+ width="375"
+ height="525"/>
+
+ <panel
+ follows="left|right|bottom"
+ layout="topleft"
+ height="40"
+ name="lower_right_panel"
+ top_pad="5"
+ width="375">
+ <check_box
+ follows="right|bottom"
+ label="Edges"
label_text.text_color="White"
layout="topleft"
- left_delta="0"
name="show_edges"
- top_pad="8">
- </check_box>
+ width="70"
+ left="0"
+ top_pad="8"/>
<check_box
- follows="top|left"
+ follows="right|bottom"
+ left_pad="8"
label="Physics"
label_text.text_color="White"
- layout="topleft"
- name="show_physics"
- top_pad="8">
- </check_box>
+ name="show_physics"/>
<check_box
- follows="top|left"
+ follows="right|bottom"
label="Textures"
label_text.text_color="White"
layout="topleft"
name="show_textures"
- top_pad="8">
- </check_box>
+ left_pad="0"/>
<check_box
- follows="top|left"
- label="Skin weights"
+ follows="right|bottom"
+ label="Weights"
label_text.text_color="White"
layout="topleft"
name="show_skin_weight"
- top_pad="8">
- </check_box>
+ left_pad="0"/>
<check_box
- follows="top|left"
+ follows="right|bottom"
label="Joints"
label_text.text_color="White"
layout="topleft"
name="show_joint_positions"
- top_pad="8">
- </check_box>
+ left_pad="0"/>
<text
- follows="top|left"
+ follows="right|bottom"
layout="topleft"
left="2"
name="physics_explode_label"
@@ -1453,12 +1592,13 @@
</text>
<slider
name="physics_explode"
- follows="top|left"
- top="100"
- left="0"
+ follows="right|bottom"
+ valign="center"
+ top="15"
+ left="80"
min_val="0.0"
max_val="3.0"
height="20"
- width="150"/>
-</panel>
+ width="120"/>
+ </panel>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_preferences.xml b/indra/newview/skins/default/xui/en/floater_preferences.xml
index 845c1efe4d..0e62d50072 100644
--- a/indra/newview/skins/default/xui/en/floater_preferences.xml
+++ b/indra/newview/skins/default/xui/en/floater_preferences.xml
@@ -3,7 +3,7 @@
legacy_header_height="18"
positioning="centered"
default_tab_group="1"
- height="512"
+ height="530"
layout="topleft"
name="Preferences"
help_topic="preferences"
@@ -25,7 +25,7 @@ https://accounts.secondlife.com/change_email/
layout="topleft"
right="-105"
name="OK"
- top="473"
+ top="492"
width="90">
<button.commit_callback
function="Pref.OK" />
@@ -43,6 +43,42 @@ https://accounts.secondlife.com/change_email/
<button.commit_callback
function="Pref.Cancel" />
</button>
+
+ <panel
+ name="search_panel"
+ layout="topleft"
+ follows="left|top|right"
+ left="4"
+ right="-4"
+ top="21"
+ height="18"
+ tab_group="2">
+ <search_editor
+ clear_button_visible="true"
+ follows="left|top|right"
+ height="18"
+ label="Search Settings"
+ layout="topleft"
+ left="0"
+ max_length_bytes="255"
+ name="search_prefs_edit"
+ right="-1"
+ text_pad_left="6"
+ tool_tip="Type the search term you are interested in here. Results will be displayed for partial fulltext matches within the setting's name or comment."
+ top="0">
+ <search_editor.commit_callback
+ function="UpdateFilter" />
+ <search_editor.clear_button
+ rect.height="18"
+ rect.width="18"
+ rect.bottom="-1" />
+ <search_editor.search_button
+ rect.height="12"
+ rect.width="12"
+ rect.bottom="-1" />
+ </search_editor>
+ </panel>
+
<tab_container
follows="all"
halign="left"
@@ -54,7 +90,7 @@ https://accounts.secondlife.com/change_email/
tab_position="left"
tab_width="140"
tab_padding_right="0"
- top="21"
+ top="40"
width="658">
<panel
class="panel_preference"
diff --git a/indra/newview/skins/default/xui/en/panel_status_bar.xml b/indra/newview/skins/default/xui/en/panel_status_bar.xml
index 998f1ce599..52bcce01f7 100644
--- a/indra/newview/skins/default/xui/en/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml
@@ -34,6 +34,46 @@
L$ [AMT]
</panel.string>
<panel
+ height="18"
+ left="-458"
+ top="0"
+ width="120"
+ follows="right|top"
+ name="menu_search_panel"
+ background_opaque="true"
+ background_visible="true"
+ bg_opaque_color="MouseGray">
+ <search_editor
+ clear_button_visible="true"
+ follows="left|top"
+ height="18"
+ label="Search Menus"
+ layout="topleft"
+ left="0"
+ max_length_bytes="255"
+ name="search_menu_edit"
+ right="-1"
+ text_pad_left="6"
+ tool_tip="Type the search term you are interested in here. Results will be displayed for partial fulltext matches within the menu."
+ top="0">
+ <search_button
+ top_pad="4"
+ left_pad="4"
+ width="12"
+ height="12"
+ image_unselected="Search"
+ image_selected="Search"/>
+ <clear_button
+ bottom="2"
+ height="12"
+ image_unselected="Icon_Close_Foreground"
+ image_selected="Icon_Close_Press"
+ pad_right="4"
+ pad_left="4"
+ width="12"/>
+ </search_editor>
+ </panel>
+ <panel
height="18"
left="-416"
width="185"