summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/app_settings/settings.xml11
-rw-r--r--indra/newview/llaccountingcostmanager.cpp66
-rw-r--r--indra/newview/llaccountingcostmanager.h20
-rwxr-xr-xindra/newview/llfloatermodelpreview.cpp33
-rw-r--r--indra/newview/llfloaterobjectweights.cpp245
-rw-r--r--indra/newview/llfloaterobjectweights.h29
-rw-r--r--indra/newview/llfloatertools.cpp54
-rw-r--r--indra/newview/llfloatertools.h1
-rw-r--r--indra/newview/llpanelobject.cpp13
-rw-r--r--indra/newview/llselectmgr.cpp34
-rw-r--r--indra/newview/llviewerobject.cpp14
-rw-r--r--indra/newview/llviewerobject.h4
-rw-r--r--indra/newview/llviewerparceloverlay.cpp59
-rw-r--r--indra/newview/llviewerparceloverlay.h1
-rw-r--r--indra/newview/llviewerregion.cpp5
-rw-r--r--indra/newview/llviewerregion.h1
-rwxr-xr-xindra/newview/skins/default/xui/en/floater_model_preview.xml29
-rw-r--r--indra/newview/skins/default/xui/en/floater_object_weights.xml38
-rw-r--r--indra/newview/skins/default/xui/en/floater_tools.xml12
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml8
20 files changed, 513 insertions, 164 deletions
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 33541b559b..28064030be 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -9481,17 +9481,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>ShowAdvancedBuilderOptions</key>
- <map>
- <key>Comment</key>
- <string>Shows physics and display weight</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>ShowAdvancedGraphicsSettings</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/llaccountingcostmanager.cpp b/indra/newview/llaccountingcostmanager.cpp
index 5059efbeec..0669bdfffa 100644
--- a/indra/newview/llaccountingcostmanager.cpp
+++ b/indra/newview/llaccountingcostmanager.cpp
@@ -29,7 +29,6 @@
#include "llagent.h"
#include "llcurl.h"
#include "llhttpclient.h"
-
//===============================================================================
LLAccountingCostManager::LLAccountingCostManager()
{
@@ -38,8 +37,9 @@ LLAccountingCostManager::LLAccountingCostManager()
class LLAccountingCostResponder : public LLCurl::Responder
{
public:
- LLAccountingCostResponder( const LLSD& objectIDs )
- : mObjectIDs( objectIDs )
+ LLAccountingCostResponder( const LLSD& objectIDs, const LLHandle<LLAccountingCostObserver>& observer_handle )
+ : mObjectIDs( objectIDs ),
+ mObserverHandle( observer_handle )
{
}
@@ -55,6 +55,12 @@ public:
{
llwarns << "Transport error "<<reason<<llendl;
clearPendingRequests();
+
+ LLAccountingCostObserver* observer = mObserverHandle.get();
+ if (observer)
+ {
+ observer->setErrorStatus(statusNum, reason);
+ }
}
void result( const LLSD& content )
@@ -63,43 +69,43 @@ public:
if ( !content.isMap() || content.has("error") )
{
llwarns << "Error on fetched data"<< llendl;
- clearPendingRequests();
- return;
}
-
- bool containsSelection = content.has("selected");
- if ( containsSelection )
+ else if (content.has("selected"))
{
- S32 dataCount = content["selected"].size();
-
- for(S32 i = 0; i < dataCount; i++)
- {
+ F32 physicsCost = 0.0f;
+ F32 networkCost = 0.0f;
+ F32 simulationCost = 0.0f;
+
+ //LLTransactionID transactionID;
- F32 physicsCost = 0.0f;
- F32 networkCost = 0.0f;
- F32 simulationCost = 0.0f;
-
- //LLTransactionID transactionID;
-
- //transactionID = content["selected"][i]["local_id"].asUUID();
- physicsCost = content["selected"][i]["physics"].asReal();
- networkCost = content["selected"][i]["streaming"].asReal();
- simulationCost = content["selected"][i]["simulation"].asReal();
-
- SelectionCost selectionCost( /*transactionID,*/ physicsCost, networkCost, simulationCost );
-
- //How do you want to handle the updating of the invoking object/ui element?
+ //transactionID = content["selected"][i]["local_id"].asUUID();
+ physicsCost = content["selected"]["physics"].asReal();
+ networkCost = content["selected"]["streaming"].asReal();
+ simulationCost = content["selected"]["simulation"].asReal();
+ SelectionCost selectionCost( /*transactionID,*/ physicsCost, networkCost, simulationCost );
+
+ LLAccountingCostObserver* observer = mObserverHandle.get();
+ if (observer)
+ {
+ observer->onWeightsUpdate(selectionCost);
}
}
+
+ clearPendingRequests();
}
private:
//List of posted objects
LLSD mObjectIDs;
+
+ // Cost update observer handle
+ LLHandle<LLAccountingCostObserver> mObserverHandle;
};
//===============================================================================
-void LLAccountingCostManager::fetchCosts( eSelectionType selectionType, const std::string& url )
+void LLAccountingCostManager::fetchCosts( eSelectionType selectionType,
+ const std::string& url,
+ const LLHandle<LLAccountingCostObserver>& observer_handle )
{
// Invoking system must have already determined capability availability
if ( !url.empty() )
@@ -115,7 +121,7 @@ void LLAccountingCostManager::fetchCosts( eSelectionType selectionType, const st
// Check to see if a request for this object has already been made.
if ( mPendingObjectQuota.find( *IDIter ) == mPendingObjectQuota.end() )
{
- mObjectList.insert( *IDIter );
+ mPendingObjectQuota.insert( *IDIter );
objectList[objectIndex++] = *IDIter;
}
}
@@ -133,7 +139,7 @@ void LLAccountingCostManager::fetchCosts( eSelectionType selectionType, const st
else
if ( selectionType == Prims )
{
- keystr="prim_roots";
+ keystr="selected_prims";
}
else
{
@@ -146,7 +152,7 @@ void LLAccountingCostManager::fetchCosts( eSelectionType selectionType, const st
LLSD dataToPost = LLSD::emptyMap();
dataToPost[keystr.c_str()] = objectList;
- LLHTTPClient::post( url, dataToPost, new LLAccountingCostResponder( objectList ));
+ LLHTTPClient::post( url, dataToPost, new LLAccountingCostResponder( objectList, observer_handle ));
}
}
else
diff --git a/indra/newview/llaccountingcostmanager.h b/indra/newview/llaccountingcostmanager.h
index 8ae696a98d..cccdc2e2d9 100644
--- a/indra/newview/llaccountingcostmanager.h
+++ b/indra/newview/llaccountingcostmanager.h
@@ -27,8 +27,24 @@
#ifndef LL_ACCOUNTINGQUOTAMANAGER_H
#define LL_ACCOUNTINGQUOTAMANAGER_H
//===============================================================================
+#include "llhandle.h"
+
#include "llaccountingcost.h"
//===============================================================================
+// An interface class for panels which display the parcel accounting information.
+class LLAccountingCostObserver
+{
+public:
+ LLAccountingCostObserver() { mObserverHandle.bind(this); }
+ virtual ~LLAccountingCostObserver() {}
+ virtual void onWeightsUpdate(const SelectionCost& selection_cost) = 0;
+ virtual void setErrorStatus(U32 status, const std::string& reason) = 0;
+ const LLHandle<LLAccountingCostObserver>& getObserverHandle() const { return mObserverHandle; }
+
+protected:
+ LLRootHandle<LLAccountingCostObserver> mObserverHandle;
+};
+//===============================================================================
class LLAccountingCostManager : public LLSingleton<LLAccountingCostManager>
{
public:
@@ -37,7 +53,8 @@ public:
//Store an object that will be eventually fetched
void addObject( const LLUUID& objectID );
//Request quotas for object list
- void fetchCosts( eSelectionType selectionType, const std::string& url );
+ void fetchCosts( eSelectionType selectionType, const std::string& url,
+ const LLHandle<LLAccountingCostObserver>& observer_handle );
//Delete a specific object from the pending list
void removePendingObject( const LLUUID& objectID );
@@ -52,4 +69,3 @@ private:
//===============================================================================
#endif // LLACCOUNTINGCOSTMANAGER
-
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index d55849d2fb..b1b5e69968 100755
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -96,6 +96,7 @@
#include "llsliderctrl.h"
#include "llspinctrl.h"
#include "lltoggleablemenu.h"
+#include "lltrans.h"
#include "llvfile.h"
#include "llvfs.h"
#include "llcallbacklist.h"
@@ -436,8 +437,6 @@ BOOL LLFloaterModelPreview::postBuild()
childDisable("upload_skin");
childDisable("upload_joints");
-
- childDisable("ok_btn");
mViewOptionMenuButton = getChild<LLMenuButton>("options_gear_btn");
@@ -783,8 +782,6 @@ void LLFloaterModelPreview::draw()
}
}
- childSetEnabled("ok_btn", mHasUploadPerm && !mUploadModelUrl.empty());
-
childSetTextArg("prim_cost", "[PRIM_COST]", llformat("%d", mModelPreview->mResourceCost));
childSetTextArg("description_label", "[TEXTURES]", llformat("%d", mModelPreview->mTextureSet.size()));
@@ -1158,7 +1155,11 @@ void LLFloaterModelPreview::initDecompControls()
//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,
+ std::string name(param[i].mDetails.mEnumValues.mEnumsArray[k].mName);
+ std::string localized_name;
+ bool is_localized = LLTrans::findString(localized_name, name);
+
+ combo_box->add(is_localized ? localized_name : name,
LLSD::Integer(param[i].mDetails.mEnumValues.mEnumsArray[k].mValue));
}
combo_box->setValue(param[i].mDefault.mIntOrEnumValue);
@@ -3055,14 +3056,6 @@ U32 LLModelPreview::calcResourceCost()
rebuildUploadData();
- if (mFMP && mModelLoader)
- {
- if ( getLoadState() < LLModelLoader::ERROR_PARSING)
- {
- mFMP->childEnable("ok_btn");
- }
- }
-
//Upload skin is selected BUT check to see if the joints coming in from the asset were malformed.
if ( mFMP && mFMP->childGetValue("upload_skin").asBoolean() )
{
@@ -3186,11 +3179,6 @@ void LLModelPreview::rebuildUploadData()
F32 max_scale = 0.f;
- if ( mBaseScene.size() > 0)
- {
- mFMP->childEnable("ok_btn");
- }
-
//reorder materials to match mBaseModel
for (U32 i = 0; i < LLModel::NUM_LODS; i++)
{
@@ -4302,11 +4290,7 @@ void LLModelPreview::updateStatusMessages()
}
}
- if ( upload_ok && !errorStateFromLoader && skinAndRigOk && !has_degenerate)
- {
- mFMP->childEnable("ok_btn");
- }
- else
+ if (!upload_ok || errorStateFromLoader || !skinAndRigOk || has_degenerate)
{
mFMP->childDisable("ok_btn");
}
@@ -5495,6 +5479,8 @@ void LLFloaterModelPreview::onUpload(void* user_data)
LLFloaterModelPreview* mp = (LLFloaterModelPreview*) user_data;
+ mp->mUploadBtn->setEnabled(false);
+
mp->mModelPreview->rebuildUploadData();
bool upload_skinweights = mp->childGetValue("upload_skin").asBoolean();
@@ -5643,6 +5629,7 @@ void LLFloaterModelPreview::onModelUploadFailure()
{
assert_main_thread();
toggleCalculateButton(true);
+ mUploadBtn->setEnabled(true);
}
S32 LLFloaterModelPreview::DecompRequest::statusCallback(const char* status, S32 p1, S32 p2)
diff --git a/indra/newview/llfloaterobjectweights.cpp b/indra/newview/llfloaterobjectweights.cpp
index 93aa8dcf08..7ad34431fb 100644
--- a/indra/newview/llfloaterobjectweights.cpp
+++ b/indra/newview/llfloaterobjectweights.cpp
@@ -27,8 +27,75 @@
#include "llfloaterobjectweights.h"
+#include "llparcel.h"
+
+#include "llfloaterreg.h"
#include "lltextbox.h"
+#include "llagent.h"
+#include "llselectmgr.h"
+#include "llviewerparcelmgr.h"
+#include "llviewerregion.h"
+
+/**
+ * struct LLCrossParcelFunctor
+ *
+ * A functor that checks whether a bounding box for all
+ * selected objects crosses a region or parcel bounds.
+ */
+struct LLCrossParcelFunctor : public LLSelectedObjectFunctor
+{
+ /*virtual*/ bool apply(LLViewerObject* obj)
+ {
+ // Add the root object box.
+ mBoundingBox.addBBoxAgent(LLBBox(obj->getPositionRegion(), obj->getRotationRegion(), obj->getScale() * -0.5f, obj->getScale() * 0.5f).getAxisAligned());
+
+ // Extend the bounding box across all the children.
+ LLViewerObject::const_child_list_t children = obj->getChildren();
+ for (LLViewerObject::const_child_list_t::const_iterator iter = children.begin();
+ iter != children.end(); iter++)
+ {
+ LLViewerObject* child = *iter;
+ mBoundingBox.addBBoxAgent(LLBBox(child->getPositionRegion(), child->getRotationRegion(), child->getScale() * -0.5f, child->getScale() * 0.5f).getAxisAligned());
+ }
+
+ bool result = false;
+
+ LLViewerRegion* region = obj->getRegion();
+ if (region)
+ {
+ std::vector<LLBBox> boxes;
+ boxes.push_back(mBoundingBox);
+ result = region->objectsCrossParcel(boxes);
+ }
+
+ return result;
+ }
+
+private:
+ LLBBox mBoundingBox;
+};
+
+/**
+ * Class LLLandImpactsObserver
+ *
+ * An observer class to monitor parcel selection and update
+ * the land impacts data from a parcel containing the selected object.
+ */
+class LLLandImpactsObserver : public LLParcelObserver
+{
+public:
+ virtual void changed()
+ {
+ LLFloaterObjectWeights* object_weights_floater = LLFloaterReg::getTypedInstance<LLFloaterObjectWeights>("object_weights");
+ if(object_weights_floater)
+ {
+ object_weights_floater->updateLandImpacts();
+ }
+ }
+};
+
+
LLFloaterObjectWeights::LLFloaterObjectWeights(const LLSD& key)
: LLFloater(key),
mSelectedObjects(NULL),
@@ -40,12 +107,22 @@ LLFloaterObjectWeights::LLFloaterObjectWeights(const LLSD& key)
mSelectedOnLand(NULL),
mRezzedOnLand(NULL),
mRemainingCapacity(NULL),
- mTotalCapacity(NULL)
+ mTotalCapacity(NULL),
+ mLandImpactsObserver(NULL)
{
+ mLandImpactsObserver = new LLLandImpactsObserver();
+ LLViewerParcelMgr::getInstance()->addObserver(mLandImpactsObserver);
}
LLFloaterObjectWeights::~LLFloaterObjectWeights()
{
+ mObjectSelection = NULL;
+ mParcelSelection = NULL;
+
+ mSelectMgrConnection.disconnect();
+
+ LLViewerParcelMgr::getInstance()->removeObserver(mLandImpactsObserver);
+ delete mLandImpactsObserver;
}
// virtual
@@ -59,10 +136,10 @@ BOOL LLFloaterObjectWeights::postBuild()
mSelectedServerWeight = getChild<LLTextBox>("server");
mSelectedDisplayWeight = getChild<LLTextBox>("display");
- mSelectedOnLand = getChild<LLTextBox>("used_download_weight");
- mRezzedOnLand = getChild<LLTextBox>("used_download_weight");
- mRemainingCapacity = getChild<LLTextBox>("used_download_weight");
- mTotalCapacity = getChild<LLTextBox>("used_download_weight");
+ mSelectedOnLand = getChild<LLTextBox>("selected");
+ mRezzedOnLand = getChild<LLTextBox>("rezzed_on_land");
+ mRemainingCapacity = getChild<LLTextBox>("remaining_capacity");
+ mTotalCapacity = getChild<LLTextBox>("total_capacity");
return TRUE;
}
@@ -70,15 +147,163 @@ BOOL LLFloaterObjectWeights::postBuild()
// virtual
void LLFloaterObjectWeights::onOpen(const LLSD& key)
{
- updateIfNothingSelected();
+ mSelectMgrConnection = LLSelectMgr::instance().mUpdateSignal.connect(boost::bind(&LLFloaterObjectWeights::refresh, this));
+
+ mObjectSelection = LLSelectMgr::getInstance()->getEditSelection();
+ mParcelSelection = LLViewerParcelMgr::getInstance()->getFloatingParcelSelection();
+
+ refresh();
+}
+
+// virtual
+void LLFloaterObjectWeights::onClose(bool app_quitting)
+{
+ mSelectMgrConnection.disconnect();
+
+ mObjectSelection = NULL;
+ mParcelSelection = NULL;
+}
+
+// virtual
+void LLFloaterObjectWeights::onWeightsUpdate(const SelectionCost& selection_cost)
+{
+ mSelectedDownloadWeight->setText(llformat("%.1f", selection_cost.mNetworkCost));
+ mSelectedPhysicsWeight->setText(llformat("%.1f", selection_cost.mPhysicsCost));
+ mSelectedServerWeight->setText(llformat("%.1f", selection_cost.mSimulationCost));
+
+ S32 render_cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectRenderCost();
+ mSelectedDisplayWeight->setText(llformat("%d", render_cost));
+
+ toggleWeightsLoadingIndicators(false);
+}
+
+//virtual
+void LLFloaterObjectWeights::setErrorStatus(U32 status, const std::string& reason)
+{
+ const std::string text = getString("nothing_selected");
+
+ mSelectedDownloadWeight->setText(text);
+ mSelectedPhysicsWeight->setText(text);
+ mSelectedServerWeight->setText(text);
+ mSelectedDisplayWeight->setText(text);
+
+ toggleWeightsLoadingIndicators(false);
+}
+
+void LLFloaterObjectWeights::updateLandImpacts()
+{
+ LLParcel *parcel = mParcelSelection->getParcel();
+ if (!parcel || LLSelectMgr::getInstance()->getSelection()->isEmpty())
+ {
+ updateIfNothingSelected();
+ }
+ else
+ {
+ S32 rezzed_prims = parcel->getSimWidePrimCount();
+ S32 total_capacity = parcel->getSimWideMaxPrimCapacity();
+
+ mRezzedOnLand->setText(llformat("%d", rezzed_prims));
+ mRemainingCapacity->setText(llformat("%d", total_capacity - rezzed_prims));
+ mTotalCapacity->setText(llformat("%d", total_capacity));
+
+ toggleLandImpactsLoadingIndicators(false);
+ }
+}
+
+void LLFloaterObjectWeights::refresh()
+{
+ LLSelectMgr* sel_mgr = LLSelectMgr::getInstance();
+
+ if (sel_mgr->getSelection()->isEmpty())
+ {
+ updateIfNothingSelected();
+ }
+ else
+ {
+ S32 prim_count = sel_mgr->getSelection()->getObjectCount();
+ S32 link_count = sel_mgr->getSelection()->getRootObjectCount();
+ F32 prim_equiv = sel_mgr->getSelection()->getSelectedLinksetCost();
+
+ mSelectedObjects->setText(llformat("%d", link_count));
+ mSelectedPrims->setText(llformat("%d", prim_count));
+ mSelectedOnLand->setText(llformat("%.1d", (S32)prim_equiv));
+
+ LLCrossParcelFunctor func;
+ if (sel_mgr->getSelection()->applyToRootObjects(&func, true))
+ {
+ // Some of the selected objects cross parcel bounds.
+ // We don't display object weights and land impacts in this case.
+ const std::string text = getString("nothing_selected");
+
+ mRezzedOnLand->setText(text);
+ mRemainingCapacity->setText(text);
+ mTotalCapacity->setText(text);
+
+ toggleLandImpactsLoadingIndicators(false);
+ }
+ else
+ {
+ LLViewerObject* selected_object = mObjectSelection->getFirstObject();
+ if (selected_object)
+ {
+ // Select a parcel at the currently selected object's position.
+ LLViewerParcelMgr::getInstance()->selectParcelAt(selected_object->getPositionGlobal());
+
+ toggleLandImpactsLoadingIndicators(true);
+ }
+ else
+ {
+ llwarns << "Failed to get selected object" << llendl;
+ }
+ }
+
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region && region->capabilitiesReceived())
+ {
+ for (LLObjectSelection::valid_root_iterator iter = sel_mgr->getSelection()->valid_root_begin();
+ iter != sel_mgr->getSelection()->valid_root_end(); ++iter)
+ {
+ LLAccountingCostManager::getInstance()->addObject((*iter)->getObject()->getID());
+ }
+
+ std::string url = region->getCapability("ResourceCostSelected");
+ if (!url.empty())
+ {
+ LLAccountingCostManager::getInstance()->fetchCosts(Roots, url, getObserverHandle());
+ toggleWeightsLoadingIndicators(true);
+ }
+ }
+ else
+ {
+ llwarns << "Failed to get region capabilities" << llendl;
+ }
+ }
}
-void LLFloaterObjectWeights::toggleLoadingIndicators(bool visible)
+void LLFloaterObjectWeights::toggleWeightsLoadingIndicators(bool visible)
{
childSetVisible("download_loading_indicator", visible);
childSetVisible("physics_loading_indicator", visible);
childSetVisible("server_loading_indicator", visible);
childSetVisible("display_loading_indicator", visible);
+
+ mSelectedDownloadWeight->setVisible(!visible);
+ mSelectedPhysicsWeight->setVisible(!visible);
+ mSelectedServerWeight->setVisible(!visible);
+ mSelectedDisplayWeight->setVisible(!visible);
+}
+
+void LLFloaterObjectWeights::toggleLandImpactsLoadingIndicators(bool visible)
+{
+ childSetVisible("selected_loading_indicator", visible);
+ childSetVisible("rezzed_on_land_loading_indicator", visible);
+ childSetVisible("remaining_capacity_loading_indicator", visible);
+ childSetVisible("total_capacity_loading_indicator", visible);
+
+ mSelectedOnLand->setVisible(!visible);
+ mRezzedOnLand->setVisible(!visible);
+ mRemainingCapacity->setVisible(!visible);
+ mTotalCapacity->setVisible(!visible);
}
void LLFloaterObjectWeights::updateIfNothingSelected()
@@ -94,6 +319,10 @@ void LLFloaterObjectWeights::updateIfNothingSelected()
mSelectedDisplayWeight->setText(text);
mSelectedOnLand->setText(text);
+ mRezzedOnLand->setText(text);
+ mRemainingCapacity->setText(text);
+ mTotalCapacity->setText(text);
- toggleLoadingIndicators(false);
+ toggleWeightsLoadingIndicators(false);
+ toggleLandImpactsLoadingIndicators(false);
}
diff --git a/indra/newview/llfloaterobjectweights.h b/indra/newview/llfloaterobjectweights.h
index 10e35ad7a7..50d028909e 100644
--- a/indra/newview/llfloaterobjectweights.h
+++ b/indra/newview/llfloaterobjectweights.h
@@ -29,22 +29,40 @@
#include "llfloater.h"
+#include "llaccountingcostmanager.h"
+
+class LLLandImpactsObserver;
+class LLObjectSelection;
+class LLParcelSelection;
class LLTextBox;
-class LLFloaterObjectWeights : public LLFloater
+class LLFloaterObjectWeights : public LLFloater, LLAccountingCostObserver
{
public:
LOG_CLASS(LLFloaterObjectWeights);
+ typedef LLSafeHandle<LLObjectSelection> LLObjectSelectionHandle;
+ typedef LLSafeHandle<LLParcelSelection> LLParcelSelectionHandle;
+
LLFloaterObjectWeights(const LLSD& key);
~LLFloaterObjectWeights();
/*virtual*/ BOOL postBuild();
/*virtual*/ void onOpen(const LLSD& key);
+ /*virtual*/ void onClose(bool app_quitting);
+
+ /*virtual*/ void onWeightsUpdate(const SelectionCost& selection_cost);
+ /*virtual*/ void setErrorStatus(U32 status, const std::string& reason);
+
+ void updateLandImpacts();
private:
- void toggleLoadingIndicators(bool visible);
+ void refresh();
+
+ void toggleWeightsLoadingIndicators(bool visible);
+ void toggleLandImpactsLoadingIndicators(bool visible);
+
void updateIfNothingSelected();
LLTextBox *mSelectedObjects;
@@ -59,6 +77,13 @@ private:
LLTextBox *mRezzedOnLand;
LLTextBox *mRemainingCapacity;
LLTextBox *mTotalCapacity;
+
+ LLLandImpactsObserver *mLandImpactsObserver;
+
+ LLObjectSelectionHandle mObjectSelection;
+ LLParcelSelectionHandle mParcelSelection;
+
+ boost::signals2::connection mSelectMgrConnection;
};
#endif //LL_LLFLOATEROBJECTWEIGHTS_H
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index 00a0da3cde..48aeeafcfd 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -435,7 +435,8 @@ void LLFloaterTools::refresh()
if (sShowObjectCost)
{
std::string prim_cost_string;
- LLResMgr::getInstance()->getIntegerString(prim_cost_string, calcRenderCost());
+ S32 render_cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectRenderCost();
+ LLResMgr::getInstance()->getIntegerString(prim_cost_string, render_cost);
getChild<LLUICtrl>("RenderingCost")->setTextArg("[COUNT]", prim_cost_string);
}
@@ -459,7 +460,6 @@ void LLFloaterTools::refresh()
std::ostringstream selection_info;
- bool show_adv_weight = gSavedSettings.getBOOL("ShowAdvancedBuilderOptions");
bool show_mesh_cost = gMeshRepo.meshRezEnabled();
if (show_mesh_cost)
@@ -475,22 +475,19 @@ void LLFloaterTools::refresh()
selection_info << getString("status_selectcount", selection_args);
- if (show_adv_weight)
- {
- selection_info << ",";
- childSetTextArg("selection_weight", "[PHYS_WEIGHT]", llformat("%.1f", link_phys_cost));
- childSetTextArg("selection_weight", "[DISP_WEIGHT]", llformat("%.1d", calcRenderCost()));
- }
- else
- {
- selection_info<<".";
- }
+ selection_info << ",";
+
+ S32 render_cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectRenderCost();
+
+ childSetTextArg("selection_weight", "[PHYS_WEIGHT]", llformat("%.1f", link_phys_cost));
+ childSetTextArg("selection_weight", "[DISP_WEIGHT]", llformat("%.1d", render_cost));
+
getChild<LLTextBox>("selection_count")->setText(selection_info.str());
bool have_selection = !LLSelectMgr::getInstance()->getSelection()->isEmpty();
childSetVisible("selection_count", have_selection);
- childSetVisible("selection_weight", have_selection && show_adv_weight);
+ childSetVisible("selection_weight", have_selection);
childSetVisible("selection_empty", !have_selection);
}
@@ -761,7 +758,7 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
bool have_selection = !LLSelectMgr::getInstance()->getSelection()->isEmpty();
getChildView("selection_count")->setVisible(!land_visible && have_selection);
- getChildView("selection_weight")->setVisible(!land_visible && have_selection && gSavedSettings.getBOOL("ShowAdvancedBuilderOptions"));
+ getChildView("selection_weight")->setVisible(!land_visible && have_selection);
getChildView("selection_empty")->setVisible(!land_visible && !have_selection);
mTab->setVisible(!land_visible);
@@ -1014,35 +1011,6 @@ void LLFloaterTools::onClickGridOptions()
//floaterp->addDependentFloater(LLFloaterBuildOptions::getInstance(), FALSE);
}
-S32 LLFloaterTools::calcRenderCost()
-{
- S32 cost = 0;
- std::set<LLUUID> textures;
-
- for (LLObjectSelection::iterator selection_iter = LLSelectMgr::getInstance()->getSelection()->begin();
- selection_iter != LLSelectMgr::getInstance()->getSelection()->end();
- ++selection_iter)
- {
- LLSelectNode *select_node = *selection_iter;
- if (select_node)
- {
- LLViewerObject *vobj = select_node->getObject();
- if (vobj->getVolume())
- {
- LLVOVolume* volume = (LLVOVolume*) vobj;
-
- cost += volume->getRenderCost(textures);
- cost += textures.size() * LLVOVolume::ARC_TEXTURE_COST;
- textures.clear();
- }
- }
- }
-
-
- return cost;
-}
-
-
// static
void LLFloaterTools::setEditTool(void* tool_pointer)
{
diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h
index 69636190fc..8c4cb721d3 100644
--- a/indra/newview/llfloatertools.h
+++ b/indra/newview/llfloatertools.h
@@ -113,7 +113,6 @@ private:
static bool multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response);
static void setObjectType( LLPCode pcode );
void onClickGridOptions();
- S32 calcRenderCost();
public:
LLButton *mBtnFocus;
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index c222bbb191..e4b2396bc6 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -1112,7 +1112,16 @@ void LLPanelObject::getState( )
if (mCtrlSculptType)
{
- mCtrlSculptType->setCurrentByIndex(sculpt_stitching);
+ if (sculpt_stitching == LL_SCULPT_TYPE_NONE)
+ {
+ // since 'None' is no longer an option in the combo box
+ // use 'Plane' as an equivalent sculpt type
+ mCtrlSculptType->setCurrentByID(LLSD(LL_SCULPT_TYPE_PLANE));
+ }
+ else
+ {
+ mCtrlSculptType->setCurrentByID(LLSD(sculpt_stitching));
+ }
mCtrlSculptType->setEnabled(editable && !isMesh);
}
@@ -1749,7 +1758,7 @@ void LLPanelObject::sendSculpt()
U8 sculpt_type = 0;
if (mCtrlSculptType)
- sculpt_type |= mCtrlSculptType->getCurrentIndex();
+ sculpt_type |= mCtrlSculptType->getValue().asInteger();
bool enabled = sculpt_type != LL_SCULPT_TYPE_MESH;
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 8fa4065fa6..7ff58f5d34 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -6522,32 +6522,32 @@ U32 LLObjectSelection::getSelectedObjectTriangleCount()
return count;
}
-/*S32 LLObjectSelection::getSelectedObjectRenderCost()
+S32 LLObjectSelection::getSelectedObjectRenderCost()
{
S32 cost = 0;
- LLVOVolume::texture_cost_t textures;
- for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter)
- {
- LLSelectNode* node = *iter;
- LLVOVolume* object = (LLVOVolume*)node->getObject();
-
- if (object)
- {
- cost += object->getRenderCost(textures);
- }
+ std::set<LLUUID> textures;
- for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter)
+ for (list_t::iterator selection_iter = mList.begin(); selection_iter != mList.end();
+ ++selection_iter)
+ {
+ LLSelectNode *select_node = *selection_iter;
+ if (select_node)
{
- // add the cost of each individual texture in the linkset
- cost += iter->second;
+ LLViewerObject *vobj = select_node->getObject();
+ if (vobj->getVolume())
+ {
+ LLVOVolume* volume = (LLVOVolume*) vobj;
+
+ cost += volume->getRenderCost(textures);
+ cost += textures.size() * LLVOVolume::ARC_TEXTURE_COST;
+ textures.clear();
+ }
}
- textures.clear();
}
return cost;
-}*/
-
+}
//-----------------------------------------------------------------------------
// getTECount()
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index bb7062085c..d20b6641d3 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -627,6 +627,20 @@ void LLViewerObject::constructAndAddReturnable( std::vector<PotentialReturnableO
}
}
+bool LLViewerObject::crossesParcelBounds()
+{
+ std::vector<LLBBox> boxes;
+ boxes.push_back(LLBBox(getPositionRegion(), getRotationRegion(), getScale() * -0.5f, getScale() * 0.5f).getAxisAligned());
+ for (child_list_t::iterator iter = mChildList.begin();
+ iter != mChildList.end(); iter++)
+ {
+ LLViewerObject* child = *iter;
+ boxes.push_back(LLBBox(child->getPositionRegion(), child->getRotationRegion(), child->getScale() * -0.5f, child->getScale() * 0.5f).getAxisAligned());
+ }
+
+ return mRegionp && mRegionp->objectsCrossParcel(boxes);
+}
+
BOOL LLViewerObject::setParent(LLViewerObject* parent)
{
if(mParent != parent)
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index af96bd8fde..53e951e483 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -243,6 +243,10 @@ public:
void buildReturnablesForChildrenVO( std::vector<PotentialReturnableObject>& returnables, LLViewerObject* pChild, LLViewerRegion* pTargetRegion );
void constructAndAddReturnable( std::vector<PotentialReturnableObject>& returnables, LLViewerObject* pChild, LLViewerRegion* pTargetRegion );
+ // This method returns true if the object crosses
+ // any parcel bounds in the region.
+ bool crossesParcelBounds();
+
/*
// This method will scan through this object, and then query the
// selection manager to see if the local agent probably has the
diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp
index eff16b6a6e..e619b89f9b 100644
--- a/indra/newview/llviewerparceloverlay.cpp
+++ b/indra/newview/llviewerparceloverlay.cpp
@@ -201,6 +201,65 @@ bool LLViewerParcelOverlay::encroachesOnUnowned(const std::vector<LLBBox>& boxes
return false;
}
+bool LLViewerParcelOverlay::encroachesOnNearbyParcel(const std::vector<LLBBox>& boxes) const
+{
+ // boxes are expected to already be axis aligned
+ for (U32 i = 0; i < boxes.size(); ++i)
+ {
+ LLVector3 min = boxes[i].getMinAgent();
+ LLVector3 max = boxes[i].getMaxAgent();
+
+ // If an object crosses region borders it crosses a parcel
+ if ( min.mV[VX] < 0
+ || min.mV[VY] < 0
+ || max.mV[VX] > REGION_WIDTH_METERS
+ || max.mV[VY] > REGION_WIDTH_METERS)
+ {
+ return true;
+ }
+
+ S32 left = S32(llclamp((min.mV[VX] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1));
+ S32 right = S32(llclamp((max.mV[VX] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1));
+ S32 bottom = S32(llclamp((min.mV[VY] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1));
+ S32 top = S32(llclamp((max.mV[VY] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1));
+
+ const S32 GRIDS_PER_EDGE = mParcelGridsPerEdge;
+
+ for (S32 row = bottom; row <= top; row++)
+ {
+ for (S32 col = left; col <= right; col++)
+ {
+ // This is not the rightmost column
+ if (col < GRIDS_PER_EDGE-1)
+ {
+ U8 east_overlay = mOwnership[row*GRIDS_PER_EDGE+col+1];
+ // If the column to the east of the current one marks
+ // the other parcel's west edge and the box extends
+ // to the west it crosses the parcel border.
+ if ((east_overlay & PARCEL_WEST_LINE) && col < right)
+ {
+ return true;
+ }
+ }
+
+ // This is not the topmost column
+ if (row < GRIDS_PER_EDGE-1)
+ {
+ U8 north_overlay = mOwnership[(row+1)*GRIDS_PER_EDGE+col];
+ // If the row to the north of the current one marks
+ // the other parcel's south edge and the box extends
+ // to the south it crosses the parcel border.
+ if ((north_overlay & PARCEL_SOUTH_LINE) && row < top)
+ {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+}
+
BOOL LLViewerParcelOverlay::isSoundLocal(const LLVector3& pos) const
{
S32 row = S32(pos.mV[VY] / PARCEL_GRID_STEP_METERS);
diff --git a/indra/newview/llviewerparceloverlay.h b/indra/newview/llviewerparceloverlay.h
index 3c6794e7d0..7445d5bf1d 100644
--- a/indra/newview/llviewerparceloverlay.h
+++ b/indra/newview/llviewerparceloverlay.h
@@ -61,6 +61,7 @@ public:
// bounding boxes which isn't perfect, but is close
bool encroachesOwned(const std::vector<LLBBox>& boxes) const;
bool encroachesOnUnowned(const std::vector<LLBBox>& boxes) const;
+ bool encroachesOnNearbyParcel(const std::vector<LLBBox>& boxes) const;
BOOL isSoundLocal(const LLVector3& pos) const;
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index a7fac0e29d..ad188a4075 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1783,6 +1783,11 @@ bool LLViewerRegion::childrenObjectReturnable( const std::vector<LLBBox>& boxes
return result;
}
+bool LLViewerRegion::objectsCrossParcel(const std::vector<LLBBox>& boxes) const
+{
+ return mParcelOverlay && mParcelOverlay->encroachesOnNearbyParcel(boxes);
+}
+
void LLViewerRegion::getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions )
{
mImpl->mLandp->getNeighboringRegions( uniqueRegions );
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index ef1a6d285c..c483c6ef52 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -322,6 +322,7 @@ public:
bool objectIsReturnable(const LLVector3& pos, const std::vector<LLBBox>& boxes) const;
bool childrenObjectReturnable( const std::vector<LLBBox>& boxes ) const;
+ bool objectsCrossParcel(const std::vector<LLBBox>& boxes) const;
void getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions );
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 c52f48cfaf..7c6896becf 100755
--- a/indra/newview/skins/default/xui/en/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml
@@ -40,6 +40,7 @@
name="model_category_combo" width="200">
<combo_box.drop_down_button
label_color="White"/>
+ <combo_item name="Choose one" label="Choose One..." value="MUT_Unspecified"/>
<combo_item name="Avatar shape" label="Avatar shape" value="MUT_AvatarShape"/>
<combo_item name="Avatar attachment" label="Avatar attachment" value="MUT_AvatarAttachment"/>
<combo_item name="Building Component" label="Building Component" value="MUT_BuildingComponent"/>
@@ -220,9 +221,9 @@ L$ [MODEL]
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" bottom_delta="16" left="75" name="triangles" width="65" height="18" follows="left|top" value="Triangles"/>
+ <text valign="center" halign="center" bg_visible="true" left_pad="0" width="65" name="vertices" height="18" follows="left|top" value="Vertices"/>
+ <text valign="center" halign="center" left_pad="0" name="status" 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"/>
@@ -268,7 +269,7 @@ L$ [MODEL]
border="true"
bevel_style="none" bg_alpha_color="0 0 0 0" bg_opaque_color="0 0 0 0.3">
- <text top_pad="5" left="10" height="15" follows="left|top">
+ <text top_pad="5" left="10" name="mesh_label" height="15" follows="left|top">
Mesh
</text>
@@ -350,7 +351,7 @@ L$ [MODEL]
border="true"
bevel_style="none" bg_alpha_color="0 0 0 0" bg_opaque_color="0 0 0 0.3">
- <text left="10" top_pad="5" follows="top|left" width="240" height="15">
+ <text left="10" name="gen_normals_label" top_pad="5" follows="top|left" width="240" height="15">
Generate Normals
</text>
<text left="35" top_pad="5" follows="top|left" width="100" height="15" name="crease_label">
@@ -422,15 +423,15 @@ L$ [MODEL]
border="true"
bevel_style="none" bg_alpha_color="0 0 0 0" bg_opaque_color="0 0 0 0.3">
- <text follows="left|top" bottom="40" height="30" left="10" font="SansSerifBig">
+ <text follows="left|top" bottom="40" height="30" left="10" name="method_label" font="SansSerifBig">
Step 1: Analysis
</text>
- <text top_pad="5" width="50" follows="top|left" height="15">
+ <text name="analysis_method_label" top_pad="5" width="50" follows="top|left" height="15">
Method:
</text>
<combo_box name="Method" follows="top|left" left_pad="5" bottom_delta="2" height="20" width="80"/>
- <text left="160" bottom_delta="-2" width="50" follows="top|left" height="15">
+ <text left="160" name="quality_label" bottom_delta="-2" width="50" follows="top|left" height="15">
Quality:
</text>
<combo_box name="Decompose Quality" bottom_delta="2" follows="top|left" left_pad="5" height="20" width="80"/>
@@ -456,11 +457,11 @@ L$ [MODEL]
border="true"
bevel_style="none" bg_alpha_color="0 0 0 0" bg_opaque_color="0 0 0 0.3">
- <text follows="left|top" bottom="40" height="30" left="10" font="SansSerifBig">
+ <text follows="left|top" bottom="40" height="30" left="10" name="second_step_label" font="SansSerifBig">
Step 2: Simplification
</text>
- <text left="10" top_pad="5" height="15" width="140" follows="top|left">
+ <text left="10" name="simp_method_header" top_pad="5" height="15" width="140" follows="top|left">
Method:
</text>
@@ -509,10 +510,10 @@ L$ [MODEL]
name="modifiers_panel"
help_topic="upload_model_modifiers">
- <text left="10" width="90" bottom="30" follows="top|left" height="15">
+ <text left="10" name="scale_label" width="90" bottom="30" follows="top|left" height="15">
Scale:
</text>
- <text left_pad="5" width="140" follows="top|left" height="15">
+ <text left_pad="5" name="dimensions_label" width="140" follows="top|left" height="15">
Dimensions:
</text>
@@ -522,7 +523,7 @@ L$ [MODEL]
[X] x [Y] x [Z] m
</text>
- <text left="10" top_pad="20" follows="top|left" height="15">
+ <text left="10" name="include_label" top_pad="20" follows="top|left" height="15">
Include:
</text>
@@ -530,7 +531,7 @@ L$ [MODEL]
<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"/>
- <text left="10" top_pad="4" width="90" bottom="30" follows="top|left" height="15">
+ <text left="10" name="pelvis_offset_label" top_pad="4" width="90" bottom="30" follows="top|left" height="15">
Pelvis Z Offset:
</text>
diff --git a/indra/newview/skins/default/xui/en/floater_object_weights.xml b/indra/newview/skins/default/xui/en/floater_object_weights.xml
index f377386679..a73db3af32 100644
--- a/indra/newview/skins/default/xui/en/floater_object_weights.xml
+++ b/indra/newview/skins/default/xui/en/floater_object_weights.xml
@@ -222,6 +222,14 @@
top_pad="3"
value="--"
width="40" />
+ <loading_indicator
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="34"
+ name="selected_loading_indicator"
+ top_delta="0"
+ width="16" />
<text
follows="left|top"
height="16"
@@ -241,6 +249,14 @@
top_pad="3"
value="--"
width="40" />
+ <loading_indicator
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="34"
+ name="rezzed_on_land_loading_indicator"
+ top_delta="0"
+ width="16" />
<text
follows="left|top"
height="16"
@@ -260,12 +276,20 @@
top_pad="3"
value="--"
width="40" />
+ <loading_indicator
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="34"
+ name="remaining_capacity_loading_indicator"
+ top_delta="0"
+ width="16" />
<text
follows="left|top"
height="16"
layout="topleft"
left_pad="10"
- name="remaining_capacity"
+ name="remaining_capacity_label"
top_delta="0"
value="Remaining capacity"
width="130" />
@@ -279,12 +303,20 @@
top_pad="3"
value="--"
width="40" />
+ <loading_indicator
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="34"
+ name="total_capacity_loading_indicator"
+ top_delta="0"
+ width="16" />
<text
follows="left|top"
height="16"
layout="topleft"
left_pad="10"
- name="total_capacity"
+ name="total_capacity_label"
top_delta="0"
value="Total capacity"
width="130" />
@@ -303,7 +335,7 @@
height="16"
layout="topleft"
left="10"
- name="total_capacity"
+ name="help_SLURL"
top_pad="10"
value="[secondlife:///www.secondlife.com What is all this?...]"
width="180" />
diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
index e794a7067d..03d6c84266 100644
--- a/indra/newview/skins/default/xui/en/floater_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -2000,25 +2000,21 @@ even though the user gets a free copy.
visible="false"
width="150">
<combo_box.item
- label="(none)"
- name="None"
- value="None" />
- <combo_box.item
label="Sphere"
name="Sphere"
- value="Sphere" />
+ value="1" />
<combo_box.item
label="Torus"
name="Torus"
- value="Torus" />
+ value="2" />
<combo_box.item
label="Plane"
name="Plane"
- value="Plane" />
+ value="3" />
<combo_box.item
label="Cylinder"
name="Cylinder"
- value="Cylinder" />
+ value="4" />
</combo_box>
</panel>
<panel
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index f049f857f0..72b412efe2 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -3625,5 +3625,13 @@ Try enclosing path to the editor with double quotes.
<string name="BeaconSound">Viewing sound beacons (yellow)</string>
<string name="BeaconMedia">Viewing media beacons (white)</string>
<string name="ParticleHiding">Hiding Particles</string>
+
+ <!-- Mesh UI terms -->
+ <string name="Retain%">Retain%</string>
+ <string name="Detail">Detail</string>
+ <string name="Better Detail">Better Detail</string>
+ <string name="Surface">Surface</string>
+ <string name="Solid">Solid</string>
+ <string name="Wrap">Wrap</string>
</strings>