summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/newview/CMakeLists.txt4
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatermodelpreview.cpp154
-rw-r--r--indra/newview/llfloatermodelpreview.h27
-rw-r--r--indra/newview/llfloatermodeluploadbase.cpp58
-rw-r--r--indra/newview/llfloatermodeluploadbase.h61
-rw-r--r--indra/newview/llfloatermodelwizard.cpp292
-rw-r--r--indra/newview/llfloatermodelwizard.h37
-rw-r--r--indra/newview/llmeshrepository.cpp188
-rw-r--r--indra/newview/llmeshrepository.h18
-rw-r--r--indra/newview/lluploadfloaterobservers.cpp56
-rw-r--r--indra/newview/lluploadfloaterobservers.h97
-rw-r--r--indra/newview/llviewerregion.cpp1
-rw-r--r--indra/newview/skins/default/xui/en/floater_model_preview.xml75
-rw-r--r--indra/newview/skins/default/xui/en/floater_model_wizard.xml774
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml14
15 files changed, 1163 insertions, 693 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 523ea8a394..c4018cd79c 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -204,6 +204,7 @@ set(viewer_SOURCE_FILES
llfloatermediasettings.cpp
llfloatermemleak.cpp
llfloatermodelpreview.cpp
+ llfloatermodeluploadbase.cpp
llfloatermodelwizard.cpp
llfloaternamedesc.cpp
llfloaternotificationsconsole.cpp
@@ -496,6 +497,7 @@ set(viewer_SOURCE_FILES
lltranslate.cpp
lluilistener.cpp
lluploaddialog.cpp
+ lluploadfloaterobservers.cpp
llurl.cpp
llurldispatcher.cpp
llurldispatcherlistener.cpp
@@ -758,6 +760,7 @@ set(viewer_HEADER_FILES
llfloatermediasettings.h
llfloatermemleak.h
llfloatermodelpreview.h
+ llfloatermodeluploadbase.h
llfloatermodelwizard.h
llfloaternamedesc.h
llfloaternotificationsconsole.h
@@ -1047,6 +1050,7 @@ set(viewer_HEADER_FILES
lluiconstants.h
lluilistener.h
lluploaddialog.h
+ lluploadfloaterobservers.h
llurl.h
llurldispatcher.h
llurldispatcherlistener.h
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 67841620ea..9ce4b47e19 100644..100755
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -71,6 +71,7 @@
#include "llmatrix4a.h"
#include "llmenubutton.h"
#include "llmeshrepository.h"
+#include "llnotificationsutil.h"
#include "llsdutil_math.h"
#include "lltextbox.h"
#include "lltoolmgr.h"
@@ -353,7 +354,9 @@ void LLMeshFilePicker::notify(const std::string& filename)
// LLFloaterModelPreview()
//-----------------------------------------------------------------------------
LLFloaterModelPreview::LLFloaterModelPreview(const LLSD& key) :
-LLFloater(key)
+LLFloaterModelUploadBase(key),
+mUploadBtn(NULL),
+mCalculateBtn(NULL)
{
sInstance = this;
mLastMouseX = 0;
@@ -394,6 +397,10 @@ BOOL LLFloaterModelPreview::postBuild()
childSetCommitCallback("border_mode", onLODParamCommit, this);
childSetCommitCallback("share_tolerance", onLODParamCommit, this);
+ childSetCommitCallback("upload_skin", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL);
+ childSetCommitCallback("upload_joints", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL);
+ childSetCommitCallback("upload_textures", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL);
+
childSetTextArg("status", "[STATUS]", getString("status_idle"));
//childSetLabelArg("ok_btn", "[AMOUNT]", llformat("%d",sUploadAmount));
@@ -422,8 +429,6 @@ BOOL LLFloaterModelPreview::postBuild()
childDisable("ok_btn");
- childSetCommitCallback("confirm_checkbox", refresh, this);
-
mViewOptionMenuButton = getChild<LLMenuButton>("options_gear_btn");
mCommitCallbackRegistrar.add("ModelImport.ViewOption.Action", boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _2));
@@ -444,6 +449,7 @@ BOOL LLFloaterModelPreview::postBuild()
mModelPreview = new LLModelPreview(512, 512, 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));
//set callbacks for left click on line editor rows
for (U32 i = 0; i <= LLModel::LOD_HIGH; i++)
@@ -473,6 +479,13 @@ BOOL LLFloaterModelPreview::postBuild()
}
}
+ mUploadBtn = getChild<LLButton>("ok_btn");
+ mCalculateBtn = getChild<LLButton>("calculate_btn");
+
+ mCalculateBtn->setClickedCallback(boost::bind(&LLFloaterModelPreview::onClickCalculateBtn, this));
+
+ toggleCalculateButton(true);
+
return TRUE;
}
@@ -544,6 +557,32 @@ void LLFloaterModelPreview::loadModel(S32 lod)
(new LLMeshFilePicker(mModelPreview, lod))->getFile();
}
+void LLFloaterModelPreview::loadModel(S32 lod, const std::string& file_name)
+{
+ mModelPreview->mLoading = true;
+
+ mModelPreview->loadModel(file_name, lod);
+}
+
+void LLFloaterModelPreview::onClickCalculateBtn()
+{
+ mModelPreview->rebuildUploadData();
+
+ bool upload_skinweights = childGetValue("upload_skin").asBoolean();
+ bool upload_joint_positions = childGetValue("upload_joints").asBoolean();
+
+ mUploadModelUrl.clear();
+ LLMeshUploadThread* thread = new LLMeshUploadThread(mModelPreview->mUploadData, mModelPreview->mPreviewScale,
+ childGetValue("upload_textures").asBoolean(), upload_skinweights, upload_joint_positions, mUploadModelUrl, false);
+
+ thread->setFeeObserverHandle(getWholeModelFeeObserverHandle());
+
+ gMeshRepo.mUploadWaitList.push_back(thread);
+
+ toggleCalculateButton(false);
+ mUploadBtn->setEnabled(false);
+}
+
//static
void LLFloaterModelPreview::onImportScaleCommit(LLUICtrl*,void* userdata)
{
@@ -554,7 +593,8 @@ void LLFloaterModelPreview::onImportScaleCommit(LLUICtrl*,void* userdata)
return;
}
- fp->mModelPreview->calcResourceCost();
+ fp->toggleCalculateButton(true);
+
fp->mModelPreview->refresh();
}
//static
@@ -566,7 +606,9 @@ void LLFloaterModelPreview::onPelvisOffsetCommit( LLUICtrl*, void* userdata )
{
return;
}
- fp->mModelPreview->calcResourceCost();
+
+ fp->toggleCalculateButton(true);
+
fp->mModelPreview->refresh();
}
@@ -615,8 +657,6 @@ void LLFloaterModelPreview::onUploadSkinCommit(LLUICtrl*,void* userdata)
{
return;
}
-
- fp->mModelPreview->calcResourceCost();
fp->mModelPreview->refresh();
fp->mModelPreview->resetPreviewTarget();
fp->mModelPreview->clearBuffers();
@@ -669,6 +709,7 @@ void LLFloaterModelPreview::onAutoFillCommit(LLUICtrl* ctrl, void* userdata)
void LLFloaterModelPreview::onLODParamCommit(LLUICtrl* ctrl, void* userdata)
{
LLFloaterModelPreview* fp = (LLFloaterModelPreview*) userdata;
+
fp->mModelPreview->onLODParamCommit(false);
}
@@ -707,6 +748,8 @@ 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()));
@@ -864,6 +907,12 @@ BOOL LLFloaterModelPreview::handleScrollWheel(S32 x, S32 y, S32 clicks)
return TRUE;
}
+/*virtual*/
+void LLFloaterModelPreview::onOpen(const LLSD& key)
+{
+ requestAgentUploadPermissions();
+}
+
//static
void LLFloaterModelPreview::onPhysicsParamCommit(LLUICtrl* ctrl, void* data)
{
@@ -2921,8 +2970,7 @@ U32 LLModelPreview::calcResourceCost()
if (mFMP && mModelLoader)
{
- const BOOL confirmed_checkbox = mFMP->getChild<LLCheckBoxCtrl>("confirm_checkbox")->getValue().asBoolean();
- if ( getLoadState() < LLModelLoader::ERROR_PARSING && confirmed_checkbox )
+ if ( getLoadState() < LLModelLoader::ERROR_PARSING)
{
mFMP->childEnable("ok_btn");
}
@@ -3033,8 +3081,6 @@ void LLFloaterModelPreview::setDetails(F32 x, F32 y, F32 z, F32 streaming_cost,
childSetTextArg("import_dimensions", "[X]", llformat("%.3f", x));
childSetTextArg("import_dimensions", "[Y]", llformat("%.3f", y));
childSetTextArg("import_dimensions", "[Z]", llformat("%.3f", z));
- childSetTextArg("streaming cost", "[COST]", llformat("%.3f", streaming_cost));
- childSetTextArg("physics cost", "[COST]", llformat("%.3f", physics_cost));
}
@@ -3064,8 +3110,7 @@ void LLModelPreview::rebuildUploadData()
F32 max_scale = 0.f;
- const BOOL confirmed_checkbox = mFMP->getChild<LLCheckBoxCtrl>("confirm_checkbox")->getValue().asBoolean();
- if ( mBaseScene.size() > 0 && confirmed_checkbox )
+ if ( mBaseScene.size() > 0)
{
mFMP->childEnable("ok_btn");
}
@@ -3471,8 +3516,7 @@ void LLModelPreview::loadModelCallback(S32 lod)
}
mLoading = false;
- if (mFMP)
- mFMP->getChild<LLCheckBoxCtrl>("confirm_checkbox")->set(FALSE);
+
refresh();
mModelLoadedSignal();
@@ -4180,8 +4224,7 @@ void LLModelPreview::updateStatusMessages()
}
}
- const BOOL confirmed_checkbox = mFMP->getChild<LLCheckBoxCtrl>("confirm_checkbox")->getValue().asBoolean();
- if ( upload_ok && !errorStateFromLoader && skinAndRigOk && !has_degenerate && confirmed_checkbox)
+ if ( upload_ok && !errorStateFromLoader && skinAndRigOk && !has_degenerate)
{
mFMP->childEnable("ok_btn");
}
@@ -4429,6 +4472,8 @@ void LLModelPreview::updateStatusMessages()
crease->forceSetValue(mRequestedCreaseAngle[mPreviewLOD]);
}
+ mModelUpdatedSignal(true);
+
}
void LLModelPreview::setPreviewTarget(F32 distance)
@@ -4753,7 +4798,18 @@ BOOL LLModelPreview::render()
glClear(GL_DEPTH_BUFFER_BIT);
- LLRect preview_rect = mFMP->getChildView("preview_panel")->getRect();
+ LLRect preview_rect;
+
+ LLFloaterModelWizard* floater_wizard = dynamic_cast<LLFloaterModelWizard*>(mFMP);
+ if (floater_wizard)
+ {
+ preview_rect = floater_wizard->getPreviewRect();
+ }
+ else
+ {
+ preview_rect = mFMP->getChildView("preview_panel")->getRect();
+ }
+
F32 aspect = (F32) preview_rect.getWidth()/preview_rect.getHeight();
LLViewerCamera::getInstance()->setAspect(aspect);
@@ -5298,7 +5354,7 @@ void LLFloaterModelPreview::onUpload(void* user_data)
mp->mModelPreview->saveUploadData(upload_skinweights, upload_joint_positions);
gMeshRepo.uploadModel(mp->mModelPreview->mUploadData, mp->mModelPreview->mPreviewScale,
- mp->childGetValue("upload_textures").asBoolean(), upload_skinweights, upload_joint_positions);
+ mp->childGetValue("upload_textures").asBoolean(), upload_skinweights, upload_joint_positions, mp->mUploadModelUrl);
mp->closeFloater(false);
}
@@ -5314,6 +5370,7 @@ void LLFloaterModelPreview::onClearMaterials(void* user_data)
//static
void LLFloaterModelPreview::refresh(LLUICtrl* ctrl, void* user_data)
{
+ sInstance->toggleCalculateButton(true);
sInstance->mModelPreview->mDirty = true;
}
@@ -5366,6 +5423,43 @@ void LLFloaterModelPreview::setStatusMessage(const std::string& msg)
mStatusMessage = msg;
}
+void LLFloaterModelPreview::toggleCalculateButton()
+{
+ toggleCalculateButton(true);
+}
+
+void LLFloaterModelPreview::toggleCalculateButton(bool visible)
+{
+ mCalculateBtn->setVisible(visible);
+ mUploadBtn->setVisible(!visible);
+ //mUploadBtn->setEnabled(mHasUploadPerm);
+ mUploadBtn->setEnabled(mHasUploadPerm && !mUploadModelUrl.empty());
+
+ if (visible)
+ {
+ std::string tbd = getString("tbd");
+ childSetTextArg("weights", "[EQ]", tbd);
+ childSetTextArg("weights", "[PH]", tbd);
+ childSetTextArg("weights", "[FEE]", tbd);
+ }
+}
+
+void LLFloaterModelPreview::onModelPhysicsFeeReceived(F64 physics, S32 fee, std::string upload_url)
+{
+ mUploadModelUrl = upload_url;
+ childSetTextArg("weights", "[EQ]", llformat("%d", mModelPreview->mResourceCost));
+ childSetTextArg("weights", "[PH]", llformat("%.3f", physics));
+ childSetTextArg("weights", "[FEE]", llformat("%d", fee));
+ childSetVisible("weights", true);
+ mUploadBtn->setEnabled(mHasUploadPerm && !mUploadModelUrl.empty());
+}
+
+void LLFloaterModelPreview::setModelPhysicsFeeErrorStatus(U32 status, const std::string& reason)
+{
+ toggleCalculateButton(true);
+ llwarns << "LLFloaterModelPreview::setModelPhysicsFeeErrorStatus(" << status << " : " << reason << ")" << llendl;
+}
+
S32 LLFloaterModelPreview::DecompRequest::statusCallback(const char* status, S32 p1, S32 p2)
{
if (mContinue)
@@ -5405,3 +5499,25 @@ void LLFloaterModelPreview::DecompRequest::completed()
llassert(sInstance->mCurRequest.find(this) == sInstance->mCurRequest.end());
}
}
+
+void dump_llsd_to_file(const LLSD& content, std::string filename);
+
+void LLFloaterModelPreview::onPermissionsReceived(const LLSD& result)
+{
+ dump_llsd_to_file(result,"perm_received.xml");
+ std::string upload_status = result["mesh_upload_status"].asString();
+ // BAP HACK: handle "" for case that MeshUploadFlag cap is broken.
+ mHasUploadPerm = (("" == upload_status) || ("valid" == upload_status));
+
+ //mUploadBtn->setEnabled(mHasUploadPerm);
+ mUploadBtn->setEnabled(mHasUploadPerm && !mUploadModelUrl.empty());
+ getChild<LLTextBox>("warning_title")->setVisible(!mHasUploadPerm);
+ getChild<LLTextBox>("warning_message")->setVisible(!mHasUploadPerm);
+}
+
+void LLFloaterModelPreview::setPermissonsErrorStatus(U32 status, const std::string& reason)
+{
+ llwarns << "LLFloaterModelPreview::setPermissonsErrorStatus(" << status << " : " << reason << ")" << llendl;
+
+ LLNotificationsUtil::add("MeshUploadPermError");
+}
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index d4f6b4d293..eccc9ce1b6 100644
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -140,7 +140,7 @@ private:
static bool isAlive(LLModelLoader* loader) ;
};
-class LLFloaterModelPreview : public LLFloater
+class LLFloaterModelPreview : public LLFloaterModelUploadBase
{
public:
@@ -167,6 +167,8 @@ public:
BOOL handleHover(S32 x, S32 y, MASK mask);
BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
+ /*virtual*/ void onOpen(const LLSD& key);
+
static void onMouseCaptureLostModelPreview(LLMouseHandler*);
static void setUploadAmount(S32 amount) { sUploadAmount = amount; }
@@ -185,6 +187,7 @@ public:
void updateResourceCost();
void loadModel(S32 lod);
+ void loadModel(S32 lod, const std::string& file_name);
void onViewOptionChecked(const LLSD& userdata);
bool isViewOptionChecked(const LLSD& userdata);
@@ -193,6 +196,16 @@ public:
void enableViewOption(const std::string& option);
void disableViewOption(const std::string& option);
+ // shows warning message if agent has no permissions to upload model
+ /*virtual*/ void onPermissionsReceived(const LLSD& result);
+
+ // called when error occurs during permissions request
+ /*virtual*/ void setPermissonsErrorStatus(U32 status, const std::string& reason);
+
+ /*virtual*/ void onModelPhysicsFeeReceived(F64 physics, S32 fee, std::string upload_url);
+
+ /*virtual*/ void setModelPhysicsFeeErrorStatus(U32 status, const std::string& reason);
+
protected:
friend class LLModelPreview;
friend class LLMeshFilePicker;
@@ -258,6 +271,15 @@ protected:
LLToggleableMenu* mViewOptionMenu;
LLMutex* mStatusLock;
+private:
+ void onClickCalculateBtn();
+ void toggleCalculateButton();
+
+ // Toggles between "Calculate weights & fee" and "Upload" buttons.
+ void toggleCalculateButton(bool visible);
+
+ LLButton* mUploadBtn;
+ LLButton* mCalculateBtn;
};
class LLMeshFilePicker : public LLFilePickerThread
@@ -276,6 +298,7 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex
{
typedef boost::signals2::signal<void (F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost)> details_signal_t;
typedef boost::signals2::signal<void (void)> model_loaded_signal_t;
+ typedef boost::signals2::signal<void (bool)> model_updated_signal_t;
public:
LLModelPreview(S32 width, S32 height, LLFloater* fmp);
@@ -335,6 +358,7 @@ public:
boost::signals2::connection setDetailsCallback( const details_signal_t::slot_type& cb ){ return mDetailsSignal.connect(cb); }
boost::signals2::connection setModelLoadedCallback( const model_loaded_signal_t::slot_type& cb ){ return mModelLoadedSignal.connect(cb); }
+ boost::signals2::connection setModelUpdatedCallback( const model_updated_signal_t::slot_type& cb ){ return mModelUpdatedSignal.connect(cb); }
void setLoadState( U32 state ) { mLoadState = state; }
U32 getLoadState() { return mLoadState; }
@@ -420,6 +444,7 @@ private:
details_signal_t mDetailsSignal;
model_loaded_signal_t mModelLoadedSignal;
+ model_updated_signal_t mModelUpdatedSignal;
LLVector3 mModelPivot;
bool mHasPivot;
diff --git a/indra/newview/llfloatermodeluploadbase.cpp b/indra/newview/llfloatermodeluploadbase.cpp
new file mode 100644
index 0000000000..6d3800bfa4
--- /dev/null
+++ b/indra/newview/llfloatermodeluploadbase.cpp
@@ -0,0 +1,58 @@
+/**
+ * @file llfloatermodeluploadbase.cpp
+ * @brief LLFloaterUploadModelBase class definition
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, 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 "llfloatermodeluploadbase.h"
+#include "llagent.h"
+#include "llviewerregion.h"
+#include "llnotificationsutil.h"
+
+LLFloaterModelUploadBase::LLFloaterModelUploadBase(const LLSD& key)
+:LLFloater(key),
+ mHasUploadPerm(false)
+{
+}
+
+void LLFloaterModelUploadBase::requestAgentUploadPermissions()
+{
+ std::string capability = "MeshUploadFlag";
+ std::string url = gAgent.getRegion()->getCapability(capability);
+
+ if (!url.empty())
+ {
+ llinfos<< typeid(*this).name() <<"::requestAgentUploadPermissions() requesting for upload model permissions from: "<< url <<llendl;
+ LLHTTPClient::get(url, new LLUploadModelPremissionsResponder(getPermObserverHandle()));
+ }
+ else
+ {
+ LLSD args;
+ args["CAPABILITY"] = capability;
+ LLNotificationsUtil::add("RegionCapabilityRequestError", args);
+ // BAP HACK avoid being blocked by broken server side stuff
+ mHasUploadPerm = true;
+ }
+}
diff --git a/indra/newview/llfloatermodeluploadbase.h b/indra/newview/llfloatermodeluploadbase.h
new file mode 100644
index 0000000000..6d1282dbd6
--- /dev/null
+++ b/indra/newview/llfloatermodeluploadbase.h
@@ -0,0 +1,61 @@
+/**
+ * @file llfloatermodeluploadbase.h
+ * @brief LLFloaterUploadModelBase class declaration
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, 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_LLFLOATERMODELUPLOADBASE_H
+#define LL_LLFLOATERMODELUPLOADBASE_H
+
+#include "lluploadfloaterobservers.h"
+
+class LLFloaterModelUploadBase : public LLFloater, public LLUploadPermissionsObserver, public LLWholeModelFeeObserver, public LLWholeModelUploadObserver
+{
+public:
+
+ LLFloaterModelUploadBase(const LLSD& key);
+
+ virtual ~LLFloaterModelUploadBase(){};
+
+ virtual void setPermissonsErrorStatus(U32 status, const std::string& reason) = 0;
+
+ virtual void onPermissionsReceived(const LLSD& result) = 0;
+
+ virtual void onModelPhysicsFeeReceived(F64 physics, S32 fee, std::string upload_url) = 0;
+
+ virtual void setModelPhysicsFeeErrorStatus(U32 status, const std::string& reason) = 0;
+
+ virtual void onModelUploadSuccess() {};
+
+ virtual void onModelUploadFailure() {};
+
+protected:
+
+ // requests agent's permissions to upload model
+ void requestAgentUploadPermissions();
+
+ std::string mUploadModelUrl;
+ bool mHasUploadPerm;
+};
+
+#endif /* LL_LLFLOATERMODELUPLOADBASE_H */
diff --git a/indra/newview/llfloatermodelwizard.cpp b/indra/newview/llfloatermodelwizard.cpp
index 707c8288df..71baa0fa76 100644
--- a/indra/newview/llfloatermodelwizard.cpp
+++ b/indra/newview/llfloatermodelwizard.cpp
@@ -46,12 +46,21 @@ static const std::string stateNames[]={
"choose_file",
"optimize",
"physics",
- "physics2",
"review",
"upload"};
+static void swap_controls(LLUICtrl* first_ctrl, LLUICtrl* second_ctrl, bool first_ctr_visible);
+
LLFloaterModelWizard::LLFloaterModelWizard(const LLSD& key)
- : LLFloater(key)
+ : LLFloaterModelUploadBase(key)
+ ,mRecalculateGeometryBtn(NULL)
+ ,mRecalculatePhysicsBtn(NULL)
+ ,mRecalculatingPhysicsBtn(NULL)
+ ,mCalculateWeightsBtn(NULL)
+ ,mCalculatingWeightsBtn(NULL)
+ ,mChooseFilePreviewPanel(NULL)
+ ,mOptimizePreviewPanel(NULL)
+ ,mPhysicsPreviewPanel(NULL)
{
mLastEnabledState = CHOOSE_FILE;
sInstance = this;
@@ -59,7 +68,6 @@ LLFloaterModelWizard::LLFloaterModelWizard(const LLSD& key)
mCommitCallbackRegistrar.add("Wizard.Choose", boost::bind(&LLFloaterModelWizard::setState, this, CHOOSE_FILE));
mCommitCallbackRegistrar.add("Wizard.Optimize", boost::bind(&LLFloaterModelWizard::setState, this, OPTIMIZE));
mCommitCallbackRegistrar.add("Wizard.Physics", boost::bind(&LLFloaterModelWizard::setState, this, PHYSICS));
- mCommitCallbackRegistrar.add("Wizard.Physics2", boost::bind(&LLFloaterModelWizard::setState, this, PHYSICS2));
mCommitCallbackRegistrar.add("Wizard.Review", boost::bind(&LLFloaterModelWizard::setState, this, REVIEW));
mCommitCallbackRegistrar.add("Wizard.Upload", boost::bind(&LLFloaterModelWizard::setState, this, UPLOAD));
}
@@ -81,16 +89,22 @@ void LLFloaterModelWizard::setState(int state)
}
}
+ LLView* current_preview_panel = NULL;
+
if (state == CHOOSE_FILE)
{
mModelPreview->mViewOption["show_physics"] = false;
+ current_preview_panel = mChooseFilePreviewPanel;
+
getChildView("close")->setVisible(false);
getChildView("back")->setVisible(true);
getChildView("back")->setEnabled(false);
getChildView("next")->setVisible(true);
getChildView("upload")->setVisible(false);
getChildView("cancel")->setVisible(true);
+ mCalculateWeightsBtn->setVisible(false);
+ mCalculatingWeightsBtn->setVisible(false);
}
if (state == OPTIMIZE)
@@ -102,12 +116,16 @@ void LLFloaterModelWizard::setState(int state)
mModelPreview->mViewOption["show_physics"] = false;
+ current_preview_panel = mOptimizePreviewPanel;
+
getChildView("back")->setVisible(true);
getChildView("back")->setEnabled(true);
getChildView("close")->setVisible(false);
getChildView("next")->setVisible(true);
getChildView("upload")->setVisible(false);
getChildView("cancel")->setVisible(true);
+ mCalculateWeightsBtn->setVisible(false);
+ mCalculatingWeightsBtn->setVisible(false);
}
if (state == PHYSICS)
@@ -119,30 +137,16 @@ void LLFloaterModelWizard::setState(int state)
mModelPreview->mViewOption["show_physics"] = true;
- getChildView("next")->setVisible(true);
- getChildView("upload")->setVisible(false);
- getChildView("close")->setVisible(false);
- getChildView("back")->setVisible(true);
- getChildView("back")->setEnabled(true);
- getChildView("cancel")->setVisible(true);
- }
-
- if (state == PHYSICS2)
- {
- if (mLastEnabledState < state)
- {
- executePhysicsStage("Decompose");
- }
+ current_preview_panel = mPhysicsPreviewPanel;
- mModelPreview->mViewOption["show_physics"] = true;
-
- getChildView("next")->setVisible(true);
- getChildView("next")->setEnabled(true);
+ getChildView("next")->setVisible(false);
getChildView("upload")->setVisible(false);
getChildView("close")->setVisible(false);
getChildView("back")->setVisible(true);
getChildView("back")->setEnabled(true);
getChildView("cancel")->setVisible(true);
+ mCalculateWeightsBtn->setVisible(true);
+ mCalculatingWeightsBtn->setVisible(false);
}
if (state == REVIEW)
@@ -156,6 +160,8 @@ void LLFloaterModelWizard::setState(int state)
getChildView("back")->setEnabled(true);
getChildView("upload")->setVisible(true);
getChildView("cancel")->setVisible(true);
+ mCalculateWeightsBtn->setVisible(false);
+ mCalculatingWeightsBtn->setVisible(false);
}
if (state == UPLOAD)
@@ -165,8 +171,24 @@ void LLFloaterModelWizard::setState(int state)
getChildView("back")->setVisible(false);
getChildView("upload")->setVisible(false);
getChildView("cancel")->setVisible(false);
+ mCalculateWeightsBtn->setVisible(false);
+ mCalculatingWeightsBtn->setVisible(false);
}
+ if (current_preview_panel)
+ {
+ LLRect rect;
+ current_preview_panel->localRectToOtherView(current_preview_panel->getLocalRect(), &rect, this);
+
+ // Reduce the preview rect by 1 px to fit the borders
+ rect.stretch(-1);
+
+ if (rect != mPreviewRect)
+ {
+ mPreviewRect = rect;
+ mModelPreview->refresh();
+ }
+ }
updateButtons();
}
@@ -198,18 +220,63 @@ void LLFloaterModelWizard::updateButtons()
button->setEnabled(FALSE);
}
}
+}
- LLButton *physics_button = getChild<LLButton>(stateNames[PHYSICS]+"_btn");
-
- if (mState == PHYSICS2)
+void LLFloaterModelWizard::onClickSwitchToAdvanced()
+{
+ LLFloaterModelPreview* floater_preview = LLFloaterReg::getTypedInstance<LLFloaterModelPreview>("upload_model");
+ if (!floater_preview)
{
- physics_button->setVisible(false);
+ llwarns << "FLoater model preview not found." << llendl;
+ return;
}
- else
+
+ // Open floater model preview
+ floater_preview->openFloater();
+
+ // Close the wizard
+ closeFloater();
+
+ std::string filename = getChild<LLUICtrl>("lod_file")->getValue().asString();
+ if (!filename.empty())
{
- physics_button->setVisible(true);
+ // Re-load the model to the floater model preview if it has been loaded
+ // into the wizard.
+ floater_preview->loadModel(3, filename);
}
+}
+
+void LLFloaterModelWizard::onClickRecalculateGeometry()
+{
+ S32 val = getChild<LLUICtrl>("accuracy_slider")->getValue().asInteger();
+
+ mModelPreview->genLODs(-1, NUM_LOD - val);
+
+ mModelPreview->refresh();
+}
+
+void LLFloaterModelWizard::onClickRecalculatePhysics()
+{
+ // Hide the "Recalculate physics" button and show the "Recalculating..."
+ // button instead.
+ swap_controls(mRecalculatePhysicsBtn, mRecalculatingPhysicsBtn, false);
+ executePhysicsStage("Decompose");
+}
+
+void LLFloaterModelWizard::onClickCalculateUploadFee()
+{
+ swap_controls(mCalculateWeightsBtn, mCalculatingWeightsBtn, false);
+
+ mModelPreview->rebuildUploadData();
+
+ mUploadModelUrl.clear();
+ LLMeshUploadThread* thread = new LLMeshUploadThread(mModelPreview->mUploadData, mModelPreview->mPreviewScale,
+ true, false, false, mUploadModelUrl, false);
+
+ thread->setFeeObserverHandle(getWholeModelFeeObserverHandle());
+
+ gMeshRepo.mUploadWaitList.push_back(thread);
}
void LLFloaterModelWizard::loadModel()
@@ -344,6 +411,7 @@ BOOL LLFloaterModelWizard::handleScrollWheel(S32 x, S32 y, S32 clicks)
return TRUE;
}
+
void LLFloaterModelWizard::initDecompControls()
{
LLSD key;
@@ -401,12 +469,72 @@ void LLFloaterModelWizard::initDecompControls()
mDecompParams["Simplify Method"] = 0; // set it to retain %
}
+/*virtual*/
+void LLFloaterModelWizard::onPermissionsReceived(const LLSD& result)
+{
+ std::string upload_status = result["mesh_upload_status"].asString();
+ // BAP HACK: handle "" for case that MeshUploadFlag cap is broken.
+ mHasUploadPerm = (("" == upload_status) || ("valid" == upload_status));
+
+ getChildView("warning_label")->setVisible(!mHasUploadPerm);
+ getChildView("warning_text")->setVisible(!mHasUploadPerm);
+}
+
+/*virtual*/
+void LLFloaterModelWizard::setPermissonsErrorStatus(U32 status, const std::string& reason)
+{
+ llwarns << "LLFloaterModelWizard::setPermissonsErrorStatus(" << status << " : " << reason << ")" << llendl;
+}
+
+/*virtual*/
+void LLFloaterModelWizard::onModelPhysicsFeeReceived(F64 physics, S32 fee, std::string upload_url)
+{
+ swap_controls(mCalculateWeightsBtn, mCalculatingWeightsBtn, true);
+
+ // Enable the "Upload" buton if we have calculated the upload fee
+ // and have the permission to upload.
+ getChildView("upload")->setEnabled(mHasUploadPerm);
+
+ mUploadModelUrl = upload_url;
+
+ childSetTextArg("review_fee", "[FEE]", llformat("%d", fee));
+ childSetTextArg("charged_fee", "[FEE]", llformat("%d", fee));
+
+ setState(llmin((int) UPLOAD, mState+1));
+}
+
+/*virtual*/
+void LLFloaterModelWizard::setModelPhysicsFeeErrorStatus(U32 status, const std::string& reason)
+{
+ swap_controls(mCalculateWeightsBtn, mCalculatingWeightsBtn, true);
+
+ // Disable the "Review" step if it has been previously enabled.
+ modelChangedCallback();
+
+ llwarns << "LLFloaterModelWizard::setModelPhysicsFeeErrorStatus(" << status << " : " << reason << ")" << llendl;
+}
+
+/*virtual*/
+void LLFloaterModelWizard::onModelUploadSuccess()
+{
+ // success!
+ setState(UPLOAD);
+}
+
+/*virtual*/
+void LLFloaterModelWizard::onModelUploadFailure()
+{
+
+}
+
//static
void LLFloaterModelWizard::executePhysicsStage(std::string stage_name)
{
if (sInstance)
{
- F64 physics_accuracy = sInstance->getChild<LLSliderCtrl>("physics_slider")->getValue().asReal();
+ // Invert the slider value so that "performance" end is giving the least detailed physics,
+ // and the "accuracy" end is giving the most detailed physics
+ F64 physics_accuracy = 1 - sInstance->getChild<LLSliderCtrl>("physics_slider")->getValue().asReal();
sInstance->mDecompParams["Retain%"] = physics_accuracy;
@@ -471,13 +599,16 @@ void LLFloaterModelWizard::DecompRequest::completed()
{
executePhysicsStage("Simplify");
}
+ else
+ {
+ // Decomp request is complete so we can enable the "Recalculate physics" button again.
+ swap_controls(sInstance->mRecalculatePhysicsBtn, sInstance->mRecalculatingPhysicsBtn, true);
+ }
}
BOOL LLFloaterModelWizard::postBuild()
{
- LLView* preview_panel = getChildView("preview_panel");
-
childSetValue("import_scale", (F32) 0.67335826);
getChild<LLUICtrl>("browse")->setCommitCallback(boost::bind(&LLFloaterModelWizard::loadModel, this));
@@ -488,23 +619,36 @@ BOOL LLFloaterModelWizard::postBuild()
getChild<LLUICtrl>("next")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickNext, this));
getChild<LLUICtrl>("preview_lod_combo")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onPreviewLODCommit, this, _1));
getChild<LLUICtrl>("preview_lod_combo2")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onPreviewLODCommit, this, _1));
- getChild<LLUICtrl>("preview_lod_combo3")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onPreviewLODCommit, this, _1));
- getChild<LLUICtrl>("accuracy_slider")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onAccuracyPerformance, this, _2));
getChild<LLUICtrl>("upload")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onUpload, this));
- getChild<LLUICtrl>("physics_slider")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onPhysicsChanged, this));
+ getChild<LLUICtrl>("switch_to_advanced")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickSwitchToAdvanced, this));
+
+ mRecalculateGeometryBtn = getChild<LLButton>("recalculate_geometry_btn");
+ mRecalculateGeometryBtn->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickRecalculateGeometry, this));
+
+ mRecalculatePhysicsBtn = getChild<LLButton>("recalculate_physics_btn");
+ mRecalculatePhysicsBtn->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickRecalculatePhysics, this));
+
+ mRecalculatingPhysicsBtn = getChild<LLButton>("recalculating_physics_btn");
+
+ mCalculateWeightsBtn = getChild<LLButton>("calculate");
+ mCalculateWeightsBtn->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickCalculateUploadFee, this));
+
+ mCalculatingWeightsBtn = getChild<LLButton>("calculating");
+
+ mChooseFilePreviewPanel = getChild<LLView>("choose_file_preview_panel");
+ mOptimizePreviewPanel = getChild<LLView>("optimize_preview_panel");
+ mPhysicsPreviewPanel = getChild<LLView>("physics_preview_panel");
LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
enable_registrar.add("Next.OnEnable", boost::bind(&LLFloaterModelWizard::onEnableNext, this));
enable_registrar.add("Back.OnEnable", boost::bind(&LLFloaterModelWizard::onEnableBack, this));
-
-
- mPreviewRect = preview_panel->getRect();
mModelPreview = new LLModelPreview(512, 512, this);
mModelPreview->setPreviewTarget(16.f);
mModelPreview->setDetailsCallback(boost::bind(&LLFloaterModelWizard::setDetails, this, _1, _2, _3, _4, _5));
mModelPreview->setModelLoadedCallback(boost::bind(&LLFloaterModelWizard::modelLoadedCallback, this));
+ mModelPreview->setModelUpdatedCallback(boost::bind(&LLFloaterModelWizard::modelChangedCallback, this));
mModelPreview->mViewOption["show_textures"] = true;
center();
@@ -517,6 +661,8 @@ BOOL LLFloaterModelWizard::postBuild()
initDecompControls();
+ requestAgentUploadPermissions();
+
return TRUE;
}
@@ -532,22 +678,29 @@ void LLFloaterModelWizard::setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F
panel->childSetText("dimension_x", llformat("%.1f", x));
panel->childSetText("dimension_y", llformat("%.1f", y));
panel->childSetText("dimension_z", llformat("%.1f", z));
- panel->childSetTextArg("streaming cost", "[COST]", llformat("%.3f", streaming_cost));
- panel->childSetTextArg("physics cost", "[COST]", llformat("%.3f", physics_cost));
}
}
+
+ childSetTextArg("review_prim_equiv", "[EQUIV]", llformat("%d", mModelPreview->mResourceCost));
}
void LLFloaterModelWizard::modelLoadedCallback()
{
mLastEnabledState = CHOOSE_FILE;
- getChild<LLCheckBoxCtrl>("confirm_checkbox")->set(FALSE);
updateButtons();
}
-void LLFloaterModelWizard::onPhysicsChanged()
+void LLFloaterModelWizard::modelChangedCallback()
{
- mLastEnabledState = PHYSICS;
+ // Don't allow to proceed to the "Review" step if the model has changed
+ // but the new upload fee hasn't been calculated yet.
+ if (mLastEnabledState > PHYSICS)
+ {
+ mLastEnabledState = PHYSICS;
+ }
+
+ getChildView("upload")->setEnabled(false);
+
updateButtons();
}
@@ -555,23 +708,14 @@ void LLFloaterModelWizard::onUpload()
{
mModelPreview->rebuildUploadData();
- gMeshRepo.uploadModel(mModelPreview->mUploadData, mModelPreview->mPreviewScale,
- true, false, false);
-
- setState(UPLOAD);
-
-}
+ LLMeshUploadThread* thread = new LLMeshUploadThread(mModelPreview->mUploadData, mModelPreview->mPreviewScale,
+ true, false, false, mUploadModelUrl, true);
-void LLFloaterModelWizard::onAccuracyPerformance(const LLSD& data)
-{
- int val = (int) data.asInteger();
-
- mModelPreview->genLODs(-1, NUM_LOD-val);
+ thread->setUploadObserverHandle(getWholeModelUploadObserverHandle());
- mModelPreview->refresh();
+ gMeshRepo.mUploadWaitList.push_back(thread);
}
-
void LLFloaterModelWizard::onPreviewLODCommit(LLUICtrl* ctrl)
{
if (!mModelPreview)
@@ -601,11 +745,6 @@ void LLFloaterModelWizard::refresh()
getChildView("next")->setEnabled(model_loaded);
}
- if (mState == REVIEW)
- {
- getChildView("upload")->setEnabled(getChild<LLCheckBoxCtrl>("confirm_checkbox")->getValue().asBoolean());
- }
-
}
void LLFloaterModelWizard::draw()
@@ -613,42 +752,35 @@ void LLFloaterModelWizard::draw()
refresh();
LLFloater::draw();
- LLRect r = getRect();
-
- mModelPreview->update();
- if (mModelPreview)
+ if (mModelPreview && mState < REVIEW)
{
+ mModelPreview->update();
+
gGL.color3f(1.f, 1.f, 1.f);
gGL.getTexUnit(0)->bind(mModelPreview);
- LLView *view = getChildView(stateNames[mState]+"_panel");
- LLView* preview_panel = view->getChildView("preview_panel");
-
- LLRect rect = preview_panel->getRect();
- if (rect != mPreviewRect)
- {
- mModelPreview->refresh();
- mPreviewRect = preview_panel->getRect();
- }
-
- LLRect item_rect;
- preview_panel->localRectToOtherView(preview_panel->getLocalRect(), &item_rect, this);
-
gGL.begin( LLRender::QUADS );
{
gGL.texCoord2f(0.f, 1.f);
- gGL.vertex2i(item_rect.mLeft, item_rect.mTop-1);
+ gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mTop);
gGL.texCoord2f(0.f, 0.f);
- gGL.vertex2i(item_rect.mLeft, item_rect.mBottom);
+ gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mBottom);
gGL.texCoord2f(1.f, 0.f);
- gGL.vertex2i(item_rect.mRight-1, item_rect.mBottom);
+ gGL.vertex2i(mPreviewRect.mRight, mPreviewRect.mBottom);
gGL.texCoord2f(1.f, 1.f);
- gGL.vertex2i(item_rect.mRight-1, item_rect.mTop-1);
+ gGL.vertex2i(mPreviewRect.mRight, mPreviewRect.mTop);
}
gGL.end();
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
}
}
+
+// static
+void swap_controls(LLUICtrl* first_ctrl, LLUICtrl* second_ctrl, bool first_ctr_visible)
+{
+ first_ctrl->setVisible(first_ctr_visible);
+ second_ctrl->setVisible(!first_ctr_visible);
+}
diff --git a/indra/newview/llfloatermodelwizard.h b/indra/newview/llfloatermodelwizard.h
index b166d26295..ea60cf5db8 100644
--- a/indra/newview/llfloatermodelwizard.h
+++ b/indra/newview/llfloatermodelwizard.h
@@ -30,12 +30,13 @@
#include "llmeshrepository.h"
#include "llmodel.h"
#include "llthread.h"
+#include "llfloatermodeluploadbase.h"
class LLModelPreview;
-class LLFloaterModelWizard : public LLFloater
+class LLFloaterModelWizard : public LLFloaterModelUploadBase
{
public:
@@ -62,13 +63,29 @@ public:
BOOL handleMouseDown(S32 x, S32 y, MASK mask);
BOOL handleMouseUp(S32 x, S32 y, MASK mask);
BOOL handleHover(S32 x, S32 y, MASK mask);
- BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
+ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
void setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost);
void modelLoadedCallback();
- void onPhysicsChanged();
+ void modelChangedCallback();
void initDecompControls();
+ // shows warning message if agent has no permissions to upload model
+ /*virtual*/ void onPermissionsReceived(const LLSD& result);
+
+ // called when error occurs during permissions request
+ /*virtual*/ void setPermissonsErrorStatus(U32 status, const std::string& reason);
+
+ /*virtual*/ void onModelPhysicsFeeReceived(F64 physics, S32 fee, std::string upload_url);
+
+ /*virtual*/ void setModelPhysicsFeeErrorStatus(U32 status, const std::string& reason);
+
+ /*virtual*/ void onModelUploadSuccess();
+
+ /*virtual*/ void onModelUploadFailure();
+
+ const LLRect& getPreviewRect() const { return mPreviewRect; }
+
LLPhysicsDecomp::decomp_params mDecompParams;
std::set<LLPointer<DecompRequest> > mCurRequest;
std::string mStatusMessage;
@@ -80,13 +97,16 @@ private:
CHOOSE_FILE = 0,
OPTIMIZE,
PHYSICS,
- PHYSICS2,
REVIEW,
UPLOAD
};
void setState(int state);
void updateButtons();
+ void onClickSwitchToAdvanced();
+ void onClickRecalculateGeometry();
+ void onClickRecalculatePhysics();
+ void onClickCalculateUploadFee();
void onClickCancel();
void onClickBack();
void onClickNext();
@@ -94,7 +114,6 @@ private:
bool onEnableBack();
void loadModel();
void onPreviewLODCommit(LLUICtrl*);
- void onAccuracyPerformance(const LLSD& data);
void onUpload();
LLModelPreview* mModelPreview;
@@ -106,7 +125,15 @@ private:
U32 mLastEnabledState;
+ LLButton* mRecalculateGeometryBtn;
+ LLButton* mRecalculatePhysicsBtn;
+ LLButton* mRecalculatingPhysicsBtn;
+ LLButton* mCalculateWeightsBtn;
+ LLButton* mCalculatingWeightsBtn;
+ LLView* mChooseFilePreviewPanel;
+ LLView* mOptimizePreviewPanel;
+ LLView* mPhysicsPreviewPanel;
};
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index be11c53efa..ee899ef613 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -62,6 +62,7 @@
#include "llinventorymodel.h"
#include "llfoldertype.h"
#include "llviewerparcelmgr.h"
+#include "lluploadfloaterobservers.h"
#include "boost/lexical_cast.hpp"
@@ -554,10 +555,12 @@ class LLWholeModelFeeResponder: public LLCurl::Responder
{
LLMeshUploadThread* mThread;
LLSD mModelData;
+ LLHandle<LLWholeModelFeeObserver> mObserverHandle;
public:
- LLWholeModelFeeResponder(LLMeshUploadThread* thread, LLSD& model_data):
+ LLWholeModelFeeResponder(LLMeshUploadThread* thread, LLSD& model_data, LLHandle<LLWholeModelFeeObserver> observer_handle):
mThread(thread),
- mModelData(model_data)
+ mModelData(model_data),
+ mObserverHandle(observer_handle)
{
}
virtual void completed(U32 status,
@@ -573,17 +576,33 @@ public:
llinfos << "completed" << llendl;
mThread->mPendingUploads--;
dump_llsd_to_file(cc,make_dump_name("whole_model_fee_response_",dump_num));
+
+ LLWholeModelFeeObserver* observer = mObserverHandle.get();
+
if (isGoodStatus(status) &&
cc["state"].asString() == "upload")
{
llinfos << "fee request succeeded" << llendl;
- mThread->mWholeModelUploadURL = cc["uploader"].asString();
+ mThread->mWholeModelUploadURL = cc["uploader"].asString();
+
+ if (observer)
+ {
+ S32 fee = cc["upload_price"].asInteger();
+ F64 phys = cc["data"]["physics_cost"].asReal();
+
+ observer->onModelPhysicsFeeReceived(phys, fee, mThread->mWholeModelUploadURL);
+ }
}
else
{
llwarns << "fee request failed" << llendl;
log_upload_error(status,cc,"fee",mModelData["name"]);
mThread->mWholeModelUploadURL = "";
+
+ if (observer)
+ {
+ observer->setModelPhysicsFeeErrorStatus(status, reason);
+ }
}
}
@@ -593,11 +612,13 @@ class LLWholeModelUploadResponder: public LLCurl::Responder
{
LLMeshUploadThread* mThread;
LLSD mModelData;
+ LLHandle<LLWholeModelUploadObserver> mObserverHandle;
public:
- LLWholeModelUploadResponder(LLMeshUploadThread* thread, LLSD& model_data):
+ LLWholeModelUploadResponder(LLMeshUploadThread* thread, LLSD& model_data, LLHandle<LLWholeModelUploadObserver> observer_handle):
mThread(thread),
- mModelData(model_data)
+ mModelData(model_data),
+ mObserverHandle(observer_handle)
{
}
virtual void completed(U32 status,
@@ -614,6 +635,9 @@ public:
mThread->mPendingUploads--;
dump_llsd_to_file(cc,make_dump_name("whole_model_upload_response_",dump_num));
llinfos << "LLWholeModelUploadResponder content: " << cc << llendl;
+
+ LLWholeModelUploadObserver* observer = mObserverHandle.get();
+
// requested "mesh" asset type isn't actually the type
// of the resultant object, fix it up here.
if (isGoodStatus(status) &&
@@ -622,12 +646,22 @@ public:
llinfos << "upload succeeded" << llendl;
mModelData["asset_type"] = "object";
gMeshRepo.updateInventory(LLMeshRepository::inventory_data(mModelData,cc));
+
+ if (observer)
+ {
+ observer->onModelUploadSuccess();
+ }
}
else
{
llwarns << "upload failed" << llendl;
std::string model_name = mModelData["name"].asString();
log_upload_error(status,cc,"upload",model_name);
+
+ if (observer)
+ {
+ observer->onModelUploadFailure();
+ }
}
}
};
@@ -1376,9 +1410,11 @@ bool LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32
}
LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data, LLVector3& scale, bool upload_textures,
- bool upload_skin, bool upload_joints)
+ bool upload_skin, bool upload_joints, std::string upload_url, bool do_upload)
: LLThread("mesh upload"),
- mDiscarded(FALSE)
+ mDiscarded(FALSE),
+ mDoUpload(do_upload),
+ mWholeModelUploadURL(upload_url)
{
mInstanceList = data;
mUploadTextures = upload_textures;
@@ -1456,7 +1492,14 @@ BOOL LLMeshUploadThread::isDiscarded()
void LLMeshUploadThread::run()
{
- doWholeModelUpload();
+ if (mDoUpload)
+ {
+ doWholeModelUpload();
+ }
+ else
+ {
+ requestWholeModelFee();
+ }
}
void dump_llsd_to_file(const LLSD& content, std::string filename)
@@ -1650,69 +1693,54 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
dest = result;
}
-void LLMeshUploadThread::doWholeModelUpload()
+void LLMeshUploadThread::queueUpModels()
{
- dump_num++;
-
- mCurlRequest = new LLCurlRequest();
-
- // Queue up models for hull generation (viewer-side)
for (instance_map::iterator iter = mInstance.begin(); iter != mInstance.end(); ++iter)
- {
- LLMeshUploadData data;
- data.mBaseModel = iter->first;
-
- LLModelInstance& instance = *(iter->second.begin());
-
- for (S32 i = 0; i < 5; i++)
{
- data.mModel[i] = instance.mLOD[i];
- }
+ LLMeshUploadData data;
+ data.mBaseModel = iter->first;
- //queue up models for hull generation
- LLModel* physics = NULL;
+ LLModelInstance& instance = *(iter->second.begin());
- if (data.mModel[LLModel::LOD_PHYSICS].notNull())
- {
- physics = data.mModel[LLModel::LOD_PHYSICS];
- }
- else if (data.mModel[LLModel::LOD_MEDIUM].notNull())
- {
- physics = data.mModel[LLModel::LOD_MEDIUM];
- }
- else
- {
- physics = data.mModel[LLModel::LOD_HIGH];
- }
+ for (S32 i = 0; i < 5; i++)
+ {
+ data.mModel[i] = instance.mLOD[i];
+ }
- llassert(physics != NULL);
-
- DecompRequest* request = new DecompRequest(physics, data.mBaseModel, this);
- if(request->isValid())
- {
- gMeshRepo.mDecompThread->submitRequest(request);
- }
- }
+ //queue up models for hull generation
+ LLModel* physics = NULL;
- while (!mPhysicsComplete)
- {
- apr_sleep(100);
- }
+ if (data.mModel[LLModel::LOD_PHYSICS].notNull())
+ {
+ physics = data.mModel[LLModel::LOD_PHYSICS];
+ }
+ else if (data.mModel[LLModel::LOD_MEDIUM].notNull())
+ {
+ physics = data.mModel[LLModel::LOD_MEDIUM];
+ }
+ else
+ {
+ physics = data.mModel[LLModel::LOD_HIGH];
+ }
- LLSD model_data;
- wholeModelToLLSD(model_data,false);
- dump_llsd_to_file(model_data,make_dump_name("whole_model_fee_request_",dump_num));
+ llassert(physics != NULL);
- mPendingUploads++;
- LLCurlRequest::headers_t headers;
- mCurlRequest->post(mWholeModelFeeCapability, headers, model_data,
- new LLWholeModelFeeResponder(this,model_data), mMeshUploadTimeOut);
+ DecompRequest* request = new DecompRequest(physics, data.mBaseModel, this);
+ if(request->isValid())
+ {
+ gMeshRepo.mDecompThread->submitRequest(request);
+ }
+ }
- do
- {
- mCurlRequest->process();
- } while (mCurlRequest->getQueued() > 0);
+ while (!mPhysicsComplete)
+ {
+ apr_sleep(100);
+ }
+}
+void LLMeshUploadThread::doWholeModelUpload()
+{
+ mCurlRequest = new LLCurlRequest();
if (mWholeModelUploadURL.empty())
{
@@ -1720,12 +1748,15 @@ void LLMeshUploadThread::doWholeModelUpload()
}
else
{
+ queueUpModels();
+
LLSD full_model_data;
wholeModelToLLSD(full_model_data, true);
LLSD body = full_model_data["asset_resources"];
dump_llsd_to_file(body,make_dump_name("whole_model_body_",dump_num));
+ LLCurlRequest::headers_t headers;
mCurlRequest->post(mWholeModelUploadURL, headers, body,
- new LLWholeModelUploadResponder(this, model_data), mMeshUploadTimeOut);
+ new LLWholeModelUploadResponder(this, full_model_data, mUploadObserverHandle), mMeshUploadTimeOut);
do
{
mCurlRequest->process();
@@ -1739,6 +1770,35 @@ void LLMeshUploadThread::doWholeModelUpload()
mFinished = true;
}
+void LLMeshUploadThread::requestWholeModelFee()
+{
+ dump_num++;
+
+ mCurlRequest = new LLCurlRequest();
+
+ queueUpModels();
+
+ LLSD model_data;
+ wholeModelToLLSD(model_data,false);
+ dump_llsd_to_file(model_data,make_dump_name("whole_model_fee_request_",dump_num));
+
+ mPendingUploads++;
+ LLCurlRequest::headers_t headers;
+ mCurlRequest->post(mWholeModelFeeCapability, headers, model_data,
+ new LLWholeModelFeeResponder(this,model_data, mFeeObserverHandle), mMeshUploadTimeOut);
+
+ do
+ {
+ mCurlRequest->process();
+ } while (mCurlRequest->getQueued() > 0);
+
+ delete mCurlRequest;
+ mCurlRequest = NULL;
+
+ // Currently a no-op.
+ mFinished = true;
+}
+
void LLMeshUploadThread::uploadModel(LLMeshUploadData& data)
{ //called from arbitrary thread
{
@@ -2441,7 +2501,7 @@ void LLMeshRepository::notifyLoadedMeshes()
data.mPostData["name"],
data.mPostData["description"],
data.mResponse,
- 0);
+ data.mResponse["upload_price"]);
mInventoryQ.pop();
}
@@ -2836,9 +2896,9 @@ LLSD& LLMeshRepoThread::getMeshHeader(const LLUUID& mesh_id)
void LLMeshRepository::uploadModel(std::vector<LLModelInstance>& data, LLVector3& scale, bool upload_textures,
- bool upload_skin, bool upload_joints)
+ bool upload_skin, bool upload_joints, std::string upload_url, bool do_upload)
{
- LLMeshUploadThread* thread = new LLMeshUploadThread(data, scale, upload_textures, upload_skin, upload_joints);
+ LLMeshUploadThread* thread = new LLMeshUploadThread(data, scale, upload_textures, upload_skin, upload_joints, upload_url, do_upload);
mUploadWaitList.push_back(thread);
}
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index f56734a7de..df342facc0 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -36,6 +36,7 @@
#define LLCONVEXDECOMPINTER_STATIC 1
#include "llconvexdecomposition.h"
+#include "lluploadfloaterobservers.h"
class LLVOVolume;
class LLMeshResponder;
@@ -412,7 +413,7 @@ public:
std::map<LLViewerFetchedTexture*, LLTextureUploadData> mTextureMap;
LLMeshUploadThread(instance_list& data, LLVector3& scale, bool upload_textures,
- bool upload_skin, bool upload_joints);
+ bool upload_skin, bool upload_joints, std::string upload_url, bool do_upload = true);
~LLMeshUploadThread();
void uploadTexture(LLTextureUploadData& data);
@@ -433,7 +434,11 @@ public:
void discard() ;
BOOL isDiscarded();
+ // Queue up models for hull generation (viewer-side)
+ void queueUpModels();
+
void doWholeModelUpload();
+ void requestWholeModelFee();
void wholeModelToLLSD(LLSD& dest, bool include_textures);
@@ -441,6 +446,15 @@ public:
LLVector3& result_pos,
LLQuaternion& result_rot,
LLVector3& result_scale);
+
+ void setFeeObserverHandle(LLHandle<LLWholeModelFeeObserver> observer_handle) { mFeeObserverHandle = observer_handle; }
+ void setUploadObserverHandle(LLHandle<LLWholeModelUploadObserver> observer_handle) { mUploadObserverHandle = observer_handle; }
+
+private:
+ LLHandle<LLWholeModelFeeObserver> mFeeObserverHandle;
+ LLHandle<LLWholeModelUploadObserver> mUploadObserverHandle;
+
+ bool mDoUpload; // if FALSE only model data will be requested, otherwise the model will be uploaded
};
class LLMeshRepository
@@ -491,7 +505,7 @@ public:
LLSD& getMeshHeader(const LLUUID& mesh_id);
void uploadModel(std::vector<LLModelInstance>& data, LLVector3& scale, bool upload_textures,
- bool upload_skin, bool upload_joints);
+ bool upload_skin, bool upload_joints, std::string upload_url, bool do_upload = true);
S32 getMeshSize(const LLUUID& mesh_id, S32 lod);
diff --git a/indra/newview/lluploadfloaterobservers.cpp b/indra/newview/lluploadfloaterobservers.cpp
new file mode 100644
index 0000000000..5a6a17fbca
--- /dev/null
+++ b/indra/newview/lluploadfloaterobservers.cpp
@@ -0,0 +1,56 @@
+/**
+ * @file lluploadfloaterobservers.cpp
+ * @brief LLUploadModelPremissionsResponder definition
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, 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 "lluploadfloaterobservers.h"
+
+LLUploadModelPremissionsResponder::LLUploadModelPremissionsResponder(const LLHandle<LLUploadPermissionsObserver>& observer)
+:mObserverHandle(observer)
+{
+}
+
+void LLUploadModelPremissionsResponder::error(U32 status, const std::string& reason)
+{
+ llwarns << "LLUploadModelPremissionsResponder::error("<< status << ": " << reason << ")" << llendl;
+
+ LLUploadPermissionsObserver* observer = mObserverHandle.get();
+
+ if (observer)
+ {
+ observer->setPermissonsErrorStatus(status, reason);
+ }
+}
+
+void LLUploadModelPremissionsResponder::result(const LLSD& content)
+{
+ LLUploadPermissionsObserver* observer = mObserverHandle.get();
+
+ if (observer)
+ {
+ observer->onPermissionsReceived(content);
+ }
+}
diff --git a/indra/newview/lluploadfloaterobservers.h b/indra/newview/lluploadfloaterobservers.h
new file mode 100644
index 0000000000..c912c9755a
--- /dev/null
+++ b/indra/newview/lluploadfloaterobservers.h
@@ -0,0 +1,97 @@
+/**
+ * @file lluploadfloaterobservers.h
+ * @brief LLUploadModelPremissionsResponder declaration
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, 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_LLUPLOADFLOATEROBSERVERS_H
+#define LL_LLUPLOADFLOATEROBSERVERS_H
+
+#include "llfloater.h"
+#include "llhttpclient.h"
+#include "llhandle.h"
+
+class LLUploadPermissionsObserver
+{
+public:
+
+ LLUploadPermissionsObserver(){mUploadPermObserverHandle.bind(this);}
+ virtual ~LLUploadPermissionsObserver() {}
+
+ virtual void onPermissionsReceived(const LLSD& result) = 0;
+ virtual void setPermissonsErrorStatus(U32 status, const std::string& reason) = 0;
+
+ LLHandle<LLUploadPermissionsObserver> getPermObserverHandle() const {return mUploadPermObserverHandle;}
+
+protected:
+ LLRootHandle<LLUploadPermissionsObserver> mUploadPermObserverHandle;
+};
+
+class LLWholeModelFeeObserver
+{
+public:
+ LLWholeModelFeeObserver() { mWholeModelFeeObserverHandle.bind(this); }
+ virtual ~LLWholeModelFeeObserver() {}
+
+ virtual void onModelPhysicsFeeReceived(F64 physics, S32 fee, std::string upload_url) = 0;
+ virtual void setModelPhysicsFeeErrorStatus(U32 status, const std::string& reason) = 0;
+
+ LLHandle<LLWholeModelFeeObserver> getWholeModelFeeObserverHandle() const { return mWholeModelFeeObserverHandle; }
+
+protected:
+ LLRootHandle<LLWholeModelFeeObserver> mWholeModelFeeObserverHandle;
+};
+
+
+class LLWholeModelUploadObserver
+{
+public:
+ LLWholeModelUploadObserver() { mWholeModelUploadObserverHandle.bind(this); }
+ virtual ~LLWholeModelUploadObserver() {}
+
+ virtual void onModelUploadSuccess() = 0;
+
+ virtual void onModelUploadFailure() = 0;
+
+ LLHandle<LLWholeModelUploadObserver> getWholeModelUploadObserverHandle() const { return mWholeModelUploadObserverHandle; }
+
+protected:
+ LLRootHandle<LLWholeModelUploadObserver> mWholeModelUploadObserverHandle;
+};
+
+
+class LLUploadModelPremissionsResponder : public LLHTTPClient::Responder
+{
+public:
+
+ LLUploadModelPremissionsResponder(const LLHandle<LLUploadPermissionsObserver>& observer);
+
+ void error(U32 status, const std::string& reason);
+
+ void result(const LLSD& content);
+
+private:
+ LLHandle<LLUploadPermissionsObserver> mObserverHandle;
+};
+
+#endif /* LL_LLUPLOADFLOATEROBSERVERS_H */
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 85b4b60bf7..3569035c0d 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1525,6 +1525,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
capabilityNames.append("LandResources");
capabilityNames.append("MapLayer");
capabilityNames.append("MapLayerGod");
+ capabilityNames.append("MeshUploadFlag");
capabilityNames.append("NewFileAgentInventory");
capabilityNames.append("ParcelPropertiesUpdate");
capabilityNames.append("ParcelMediaURLFilterList");
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 07958b762e..7f15de7236 100644
--- a/indra/newview/skins/default/xui/en/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml
@@ -24,6 +24,7 @@
<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>
<text left="15" bottom="25" follows="top|left" height="15" name="name_label">
@@ -71,43 +72,29 @@
width="290"
height="290"
follows="all"/>
-
- <text bottom_delta="25" left="25" width="100" follows="bottom|left">Upload Details</text>
- <panel top_pad="5" border="true" left="15" width="290" height="70" follows="bottom|left"
- bevel_style="none" bg_alpha_color="0 0 0 0" bg_opaque_color="0 0 0 0.3">
- <text left="25" follows="bottom|left" width="140" height="15" name="streaming cost">
- Resource Cost: [COST]
- </text>
- <text left="25" top_pad="5" width="140" follows="bottom|left" height="15" name="physics cost">
- Physics Cost: [COST]
+
+ <text
+ follows="top|left"
+ font="SansSerif"
+ left_delta="0"
+ name="warning_title"
+ text_color="Yellow"
+ top_pad="10"
+ visible="false">
+ WARNING:
</text>
- <text left="25" top_pad="5" follows="bottom|left" height="15" name="upload fee">
- Upload Fee: N/A
+ <text
+ follows="top|left"
+ text_color="White"
+ height="50"
+ left_delta="0"
+ name="warning_message"
+ parse_urls="true"
+ top_pad="5"
+ wrap="true"
+ visible="false">
+ You will not be able to complete the final upload of this model to the Second Life servers. [secondlife:///app/floater/learn_more Find out how] to get certifed for mesh model uploads.
</text>
- </panel>
-
- <check_box
- height="16"
- left_delta="0"
- name="confirm_checkbox"
- top_pad="15"
- follows="bottom|left"
- width="16" />
-
- <text
- height="30"
- width="570"
- word_wrap="true"
- left_delta="25"
- top_delta="0">I confirm that I have the appropriate rights to the material contained in this model. [secondlife:///app/floater/learn_more Learn more]</text>
- <text left="10" bottom="540" width="290" height="15" follows="bottom|left|right" name="status">[STATUS]</text>
-
-
- <button bottom="540" left="300" follows="bottom|right" height="20" label="Defaults"
- width="80" name="reset_btn" tool_tip="Reset to defaults"/>
- <button bottom="540" left="430" follows="bottom|right" height="20" label="Upload"
- width="80" name="ok_btn" tool_tip="Upload to simulator"/>
- <button left_pad="10" follows="right|bottom" height="20" width="80" label="Cancel" name="cancel_btn"/>
<tab_container
follows="right|top|bottom"
@@ -417,6 +404,24 @@
</panel>
</tab_container>
+
+ <text
+ height="16"
+ left="310"
+ name="weights"
+ width="300"
+ word_wrap="true"
+ top_pad="7">
+ Prim equivs: [EQ] Physics: [PH] Upload fee: [FEE] L$
+ </text>
+
+ <button bottom="540" left="10" follows="bottom|left" height="20" label="Set to defaults"
+ width="100" name="reset_btn" tool_tip="Set to defaults"/>
+ <button left="310" follows="bottom|right" height="20" label="Calculate weights &amp; fee"
+ width="150" name="calculate_btn" tool_tip="Calculate weights &amp; fee" top_delta="0"/>
+ <button bottom="540" left="310" follows="bottom|right" height="20" label="Upload"
+ width="80" name="ok_btn" tool_tip="Upload to simulator" visible="false"/>
+ <button right="-10" follows="right|bottom" height="20" width="80" label="Cancel" name="cancel_btn" top_delta="0"/>
<!--
<button bottom_delta="0" left="10" width="120" name="auto fill" label="Generate LOD" tool_tip="Automatically generate levels of detail"/>
diff --git a/indra/newview/skins/default/xui/en/floater_model_wizard.xml b/indra/newview/skins/default/xui/en/floater_model_wizard.xml
index c3f7b70ca7..b5a5ff5342 100644
--- a/indra/newview/skins/default/xui/en/floater_model_wizard.xml
+++ b/indra/newview/skins/default/xui/en/floater_model_wizard.xml
@@ -49,24 +49,6 @@
top="32"
left="210"
height="32"
- name="physics2_btn"
- label="3. Physics"
- tab_stop="false"
- enabled="false"
- border="false"
- image_unselected="BreadCrumbBtn_Middle_Off"
- image_selected="BreadCrumbBtn_Middle_Press"
- image_hover_unselected="BreadCrumbBtn_Middle_Over"
- image_disabled="BreadCrumbBtn_Middle_Disabled"
- image_disabled_selected="BreadCrumbBtn_Middle_Disabled"
- width="110">
- <button.commit_callback
- function="Wizard.Physics2"/>
- </button>
- <button
- top="32"
- left="210"
- height="32"
name="physics_btn"
label="3. Physics"
tab_stop="false"
@@ -140,41 +122,50 @@
height="10"
font="SansSerifBig"
layout="topleft">
- Upload Model
+ Choose model file
</text>
</panel>
- <text
- top_pad="14"
- width="460"
- height="20"
- name="description"
- font="SansSerifSmall"
- layout="topleft"
- word_wrap="true"
- left_delta="5">
- This wizard will help you import mesh models to Second Life. First specify a file containing the model you wish to import. Second Life supports COLLADA (.dae) files.
- </text>
<panel
- top_delta="40"
+ top_pad="14"
left="15"
- height="270"
+ height="310"
width="505"
name="content"
bg_opaque_color="DkGray2"
background_visible="true"
background_opaque="true">
+ <text
+ height="32"
+ left="10"
+ name="advanced_users_text"
+ text_color="White"
+ top="15"
+ width="320"
+ word_wrap="true">
+ Advanced users: If you are familiar with 3D content creation tools you may wish to use the Advanced Uploader.
+ </text>
+ <button
+ follows="left|top"
+ height="20"
+ label="Switch to Advanced"
+ layout="topleft"
+ left_delta="0"
+ name="switch_to_advanced"
+ top_pad="5"
+ width="130">
+ </button>
<text
type="string"
length="1"
text_color="White"
follows="left|top"
- top="10"
+ top_pad="30"
height="10"
layout="topleft"
- left_delta="10"
+ left_delta="0"
name="Cache location"
- width="300">
- Filename:
+ width="320">
+ Choose model file to upload
</text>
<line_editor
border_style="line"
@@ -187,7 +178,7 @@
max_length="4096"
name="lod_file"
top_pad="5"
- width="220" />
+ width="230" />
<button
follows="left|top"
height="23"
@@ -200,23 +191,27 @@
width="85">
</button>
<text
- top_delta="-15"
- width="200"
- height="15"
- font="SansSerifSmall"
+ type="string"
+ length="1"
+ text_color="White"
+ follows="left|top"
+ top_pad="5"
+ height="10"
layout="topleft"
- text_color="White"
- left_pad="19">
- Model Preview:
+ left="10"
+ name="Cache location"
+ width="320">
+ Second Life supports COLLADA (.dae) files
</text>
<!-- Placeholder panel for 3D preview render -->
<panel
- left_delta="0"
- top_pad="0"
- name="preview_panel"
+ top="30"
+ right="-10"
+ name="choose_file_preview_panel"
bevel_style="none"
highlight_light_color="0.09 0.09 0.09 1"
border="true"
+ border_style="line"
height="150"
follows="all"
width="150">
@@ -225,7 +220,7 @@
top_pad="10"
width="130"
height="14"
- left="340"
+ left_delta="0"
text_color="White"
word_wrap="true">
Dimensions (meters):
@@ -238,15 +233,7 @@
text_color="White"
name="dimensions"
left_delta="0">
- X: Y: Z:
- </text>
- <text
- top_delta="0"
- width="160"
- height="15"
- name="dimension_dividers"
- left_delta="41">
- | |
+ X Y Z
</text>
<text
top_delta="0"
@@ -266,23 +253,26 @@
height="15"
name="dimension_z"
left="450"/>
- <text
- top="100"
- width="320"
- height="15"
- left="10"
- text_color="White"
- word_wrap="true">
- Note:
- </text>
- <text
- top_pad="0"
- width="320"
- height="40"
- left="10"
- word_wrap="true">
-Advanced users familiar with 3d content creation tools may prefer to use the [secondlife:///app/openfloater/upload_model Advanced Mesh Import Window] .
- </text>
+ <text
+ height="16"
+ left="10"
+ name="warning_label"
+ text_color="Yellow"
+ top="200"
+ visible="false"
+ width="320">
+ WARNING:
+ </text>
+ <text
+ height="50"
+ left="10"
+ name="warning_text"
+ top_pad="0"
+ visible="false"
+ width="320"
+ word_wrap="true">
+ You will not be able to complete the final step of uploading this model to the Second Life servers. [secondlife:///app/floater/learn_more Find out how] to set up your account for mesh model uploads.
+ </text>
</panel>
</panel>
@@ -291,7 +281,7 @@ Advanced users familiar with 3d content creation tools may prefer to use the [se
height="388"
top_delta="0"
name="optimize_panel"
- visible="false"
+ visible="true"
width="535"
left="0">
<panel
@@ -312,7 +302,7 @@ Advanced users familiar with 3d content creation tools may prefer to use the [se
height="10"
font="SansSerifBig"
layout="topleft">
- Optimize
+ Optimize model
</text>
</panel>
<text
@@ -324,7 +314,7 @@ Advanced users familiar with 3d content creation tools may prefer to use the [se
name="description"
word_wrap="true"
left_delta="5">
- This wizard has optimized your model to improve performance. You may adjust the results of the optimization process bellow or click Next to continue.
+ We have optimized the model for performance. Adjust it further if you wish.
</text>
<panel
top_delta="40"
@@ -411,116 +401,89 @@ Advanced users familiar with 3d content creation tools may prefer to use the [se
bg_opaque_color="DkGray2"
background_visible="true"
background_opaque="true">
- <text top="10" left="10" width="85" text_color="White" follows="left|top" height="15" name="lod_label">
- Model Preview:
- </text>
- <combo_box left_pad="5" top_delta="-5" follows="left|top" list_position="below" height="22"
- name="preview_lod_combo2" width="90" 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>
- <panel
- left="10"
- top_pad="5"
- name="preview_panel"
- bevel_style="none"
- highlight_light_color="0.09 0.09 0.09 1"
- border_style="line"
- border="true"
- height="185"
- follows="all"
- width="185">
- </panel>
- <text top="45" left="214" text_color="White" font="SansSerifSmallBold" halign="center" width="110" height="30" wrap="true">Higher Performance</text>
- <text top="75" left="204" halign="center" width="130" word_wrap="true" font="SansSerifSmall" height="80">Faster rendering but less detailed; lowers Resource (prim) cost.</text>
- <text top="45" left="378" text_color="White" font="SansSerifSmallBold" halign="center" width="90" height="30" wrap="true">Higher Accuracy</text>
- <text top="75" left="364" halign="center" width="130" word_wrap="true" font="SansSerifSmall" height="80">More detailed model but slower; increases Resource (prim) cost.</text>
+ <text top="69" left="10" text_color="White" font="SansSerifSmallBold" width="120" height="16" wrap="true">Performance</text>
+ <text top="85" left="10" width="120" word_wrap="true" font="SansSerifSmall" height="40">Faster rendering
+Less detail
+Lower prim weight</text>
+ <text top="69" left="184" text_color="White" font="SansSerifSmallBold" width="120" height="16" wrap="true">Accuracy</text>
+ <text top="85" left="184" width="120" word_wrap="true" font="SansSerifSmall" height="40">Slower rendering
+More detail
+Higher prim weight</text>
- <slider
+ <slider
follows="left|top"
height="20"
increment="1"
layout="topleft"
- left="204"
- max_val="3"
- initial_value="2"
+ left="10"
+ max_val="2"
+ initial_value="1"
min_val="0"
name="accuracy_slider"
show_text="false"
top="130"
width="290" />
- <text
+ <text
font="SansSerifSmall"
top_pad="0"
- width="300"
+ width="5"
left_delta="6"
height="4">'
- </text>
-
-
- <icon
- top_pad="14"
- left_delta="0"
- width="280"
- height="2"
- image_name="model_wizard\divider_line.png"/>
-
- <text top_delta="20" width="200" text_color="White" left_delta="50" name="streaming cost" height="20">Resource Cost: [COST]</text>
- <text
- top_pad="15"
- width="130"
- height="14"
- left="10"
- text_color="White"
- word_wrap="true">
- Dimensions (meters):
- </text>
- <text
- top_pad="0"
- width="160"
- height="15"
- font="SansSerifSmallBold"
- text_color="White"
- name="dimensions"
- left_delta="0">
- X: Y: Z:
- </text>
- <text
- top_delta="0"
- width="160"
- height="15"
- name="dimension_dividers"
- left_delta="41">
- | |
+ </text>
+ <text
+ font="SansSerifSmall"
+ top_delta="0"
+ width="5"
+ left_delta="137"
+ height="4">'
+ </text>
+ <text
+ font="SansSerifSmall"
+ top_delta="0"
+ width="5"
+ left_delta="137"
+ height="4">'
+ </text>
+ <button
+ follows="left|top"
+ height="20"
+ label="Recalculate Geometry"
+ layout="topleft"
+ left="80"
+ name="recalculate_geometry_btn"
+ top_pad="15"
+ width="150">
+ </button>
+ <text top="10" right="-10" width="185" text_color="White" follows="left|top" height="15" name="lod_label">
+ Geometry preview
</text>
- <text
- top_delta="0"
- width="160"
- height="15"
- name="dimension_x"
- left_delta="-25"/>
- <text
- top_delta="0"
- width="160"
- height="15"
- name="dimension_y"
- left_delta="46"/>
- <text
- top_delta="0"
- width="160"
- height="15"
- name="dimension_z"
- left_delta="46"/>
+ <panel
+ right="-10"
+ top="32"
+ name="optimize_preview_panel"
+ bevel_style="none"
+ highlight_light_color="0.09 0.09 0.09 1"
+ border_style="line"
+ border="true"
+ height="185"
+ follows="all"
+ width="185">
+ </panel>
+ <combo_box left_delta="75" top_pad="10" follows="left|top" list_position="below" height="22"
+ name="preview_lod_combo" width="110" tool_tip="LOD to view in preview render">
+ <combo_item name="high">
+ High detail
+ </combo_item>
+ <combo_item name="medium">
+ Medium detail
+ </combo_item>
+ <combo_item name="low">
+ Low detail
+ </combo_item>
+ <combo_item name="lowest">
+ Lowest detail
+ </combo_item>
+ </combo_box>
</panel>
</panel>
@@ -549,7 +512,7 @@ Advanced users familiar with 3d content creation tools may prefer to use the [se
font="SansSerifBig"
text_color="White"
layout="topleft">
- Physics
+ Adjust physics
</text>
</panel>
<text
@@ -561,7 +524,7 @@ Advanced users familiar with 3d content creation tools may prefer to use the [se
name="description"
word_wrap="true"
left_delta="5">
- The wizard will create a physical shape, which determines how the object interacts with other objects and avatars. Set the slider to the detail level most appropriate for how your object will be used:
+ We will create a shape for the outer hull of the model. Adjust the shape's detail level as needed for the intended purpose of your model.
</text>
<panel
top_delta="44"
@@ -572,172 +535,94 @@ Advanced users familiar with 3d content creation tools may prefer to use the [se
bg_opaque_color="DkGray2"
background_visible="true"
background_opaque="true">
- <text top="15" left="20" text_color="White" font="SansSerifSmallBold" width="110" height="30" wrap="true" halign="center">Higher Performance</text>
- <text top="45" left="10" halign="center" width="130" word_wrap="true" font="SansSerifSmall" height="80">Faster rendering but less detailed; lowers Resource (prim) cost.</text>
- <text top="15" left="372" text_color="White" font="SansSerifSmallBold" width="90" height="30" wrap="true" halign="center">Higher Accuracy</text>
- <text top="45" left="360" halign="center" width="130" word_wrap="true" font="SansSerifSmall" height="80">More detailed model but slower; increases Resource (prim) cost.</text>
+ <text top="10" left="10" text_color="White" font="SansSerifSmallBold" width="120" halign="right" height="16" wrap="true">Performance</text>
+ <text top="26" left="10" width="120" word_wrap="true" font="SansSerifSmall" halign="right" height="40">Faster rendering
+Less detail
+Lower prim weight</text>
+ <text top="174" left="10" text_color="White" font="SansSerifSmallBold" width="120" halign="right" height="16" wrap="true">Accuracy</text>
+ <text top="190" left="10" width="120" word_wrap="true" font="SansSerifSmall" halign="right" height="40">Slower rendering
+More detail
+Higher prim weight</text>
<slider
follows="left|top"
- height="22"
+ height="190"
increment=".1"
layout="topleft"
- left="20"
+ left="140"
max_val="1"
initial_value="0.5"
min_val="0"
name="physics_slider"
+ orientation="vertical"
show_text="false"
- top="90"
- width="440" />
- <text
- font="SansSerifSmall"
- top_pad="0"
- width="500"
- left_delta="6"
- height="4">' ' ' ' ' ' ' ' ' ' '</text>
- <text top_pad="10" width="110" halign="center" word_wrap="true" left="25" height="40">Recommended for solid objects</text>
- <text top_delta="0" width="110" halign="center" word_wrap="true" left="190" height="40">Recommended for buildings</text>
- <text top_delta="0" width="110" halign="center" word_wrap="true" left="350" height="40">Recommended for vehicles</text>
-
-
- <icon
- top_pad="5"
- left="15"
- width="470"
- height="2"
- image_name="model_wizard\divider_line.png"/>
-
- <text top_delta="30" width="180" text_color="White" left="160" name="streaming cost" height="20">Resource Cost: [COST]</text>
-
- </panel>
- </panel>
-
- <panel
- height="388"
- top_delta="0"
- name="physics2_panel"
- visible="true"
- width="535"
- left="0">
- <panel
- height="22"
- top_pad="15"
- name="header_panel"
- width="505"
- bg_opaque_color="DkGray2"
- background_visible="true"
- background_opaque="true"
- left="15">
- <text
- width="200"
- left="10"
- name="header_text"
- text_color="White"
- top="3"
- height="10"
- font="SansSerifBig"
- layout="topleft">
- Physics
- </text>
- </panel>
- <text
- top_pad="14"
- width="475"
- height="50"
- font="SansSerifSmall"
- layout="topleft"
- name="description"
- word_wrap="true"
- left_delta="5">
- Preview the physics shape below then click Next to continue. To modify the physics shape, click the Back button.
- </text>
- <panel
- top_delta="40"
- left="15"
- height="270"
- width="505"
- name="content"
- bg_opaque_color="DkGray2"
- background_visible="true"
- background_opaque="true">
- <text top="10" left="10" width="85" text_color="White" follows="left|top" height="15" name="lod_label">
- Model Preview:
+ top="25"
+ width="22" />
+ <text top="10" width="120" word_wrap="true" left_pad="10" height="50">Examples:
+Moving objects
+Flying objects
+Vehicles</text>
+ <text top="95" width="120" word_wrap="true" left_delta="0" height="50">Examples:
+Small static objects
+Less detailed objects
+Simple furniture</text>
+ <text top="180" width="120" word_wrap="true" left_delta="0" height="50">Examples:
+Static objects
+Detailed objects
+Buildings</text>
+ <button
+ follows="left|top"
+ height="20"
+ label="Recalculate physics"
+ layout="topleft"
+ left="80"
+ name="recalculate_physics_btn"
+ top_pad="10"
+ width="150">
+ </button>
+ <button
+ enabled="false"
+ follows="left|top"
+ height="20"
+ label="Recalculating..."
+ layout="topleft"
+ left_delta="0"
+ name="recalculating_physics_btn"
+ top_delta="0"
+ visible="false"
+ width="150">
+ </button>
+ <text top="10" right="-10" width="185" text_color="White" follows="left|top" height="15" name="lod_label">
+ Physics preview
</text>
- <combo_box left_pad="5" top_delta="-5" follows="left|top" list_position="below" height="22"
- name="preview_lod_combo3" width="90" tool_tip="LOD to view in preview render">
+ <panel
+ right="-10"
+ top="32"
+ name="physics_preview_panel"
+ bevel_style="none"
+ highlight_light_color="0.09 0.09 0.09 1"
+ border_style="line"
+ border="true"
+ height="185"
+ follows="all"
+ width="185">
+ </panel>
+ <combo_box left_delta="75" top_pad="10" follows="left|top" list_position="below" height="22"
+ name="preview_lod_combo2" width="110" tool_tip="LOD to view in preview render">
<combo_item name="high">
- High
+ High detail
</combo_item>
<combo_item name="medium">
- Medium
+ Medium detail
</combo_item>
<combo_item name="low">
- Low
+ Low detail
</combo_item>
<combo_item name="lowest">
- Lowest
+ Lowest detail
</combo_item>
</combo_box>
- <panel
- left="10"
- top_pad="10"
- name="preview_panel"
- bevel_style="none"
- highlight_light_color="0.09 0.09 0.09 1"
- border_style="line"
- border="true"
- height="190"
- follows="all"
- width="190">
- </panel>
- <text
- top_pad="8"
- width="130"
- height="14"
- left="10"
- text_color="White"
- word_wrap="true">
- Dimensions (meters):
- </text>
- <text
- top_pad="0"
- width="160"
- height="15"
- font="SansSerifSmallBold"
- text_color="White"
- name="dimensions"
- left_delta="0">
- X: Y: Z:
- </text>
- <text
- top_delta="0"
- width="160"
- height="15"
- name="dimension_dividers"
- left_delta="41">
- | |
- </text>
- <text
- top_delta="0"
- width="160"
- height="15"
- name="dimension_x"
- left_delta="-25"/>
- <text
- top_delta="0"
- width="160"
- height="15"
- name="dimension_y"
- left_delta="46"/>
- <text
- top_delta="0"
- width="160"
- height="15"
- name="dimension_z"
- left_delta="46"/>
- <text top="60" width="180" text_color="White" left="225" name="streaming cost" height="20">Resource Cost: [COST]</text>
- </panel>
+ </panel>
</panel>
<panel
@@ -768,162 +653,44 @@ Advanced users familiar with 3d content creation tools may prefer to use the [se
Review
</text>
</panel>
- <text
+ <panel
top_pad="14"
- width="470"
- height="24"
- font="SansSerifSmall"
- layout="topleft"
- name="description"
- word_wrap="true"
- left_delta="5">
- Review the details below then click. Upload to upload your model. Your L$ balance will be charged when you click Upload.
- </text>
- <icon
- top_pad="10"
- left="20"
- width="495"
- height="2"
- image_name="model_wizard\divider_line.png"/>
- <panel
- top_pad="5"
left="15"
- height="270"
+ height="310"
width="505"
- name="content">
- <text top="10" left="10" width="85" text_color="White" follows="left|top" height="15" name="lod_label">
- Model Preview:
- </text>
- <combo_box left_pad="5" top_delta="-5" follows="left|top" list_position="below" height="22"
- name="preview_lod_combo" width="90" 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>
- <panel
- left="10"
- top_pad="10"
- name="preview_panel"
- bevel_style="none"
- highlight_light_color="0.09 0.09 0.09 1"
- border_style="line"
- border="true"
- height="190"
- follows="all"
- width="190">
- </panel>
- <text
- top_pad="8"
- width="130"
- height="14"
- left="10"
- text_color="White"
- word_wrap="true">
- Dimensions (meters):
- </text>
- <text
- top_pad="0"
- width="160"
- height="15"
- font="SansSerifSmallBold"
- text_color="White"
- name="dimensions"
- left_delta="0">
- X: Y: Z:
- </text>
- <text
- top_delta="0"
- width="160"
- height="15"
- name="dimension_dividers"
- left_delta="41">
- | |
- </text>
- <text
- top_delta="0"
- width="160"
- height="15"
- name="dimension_x"
- left_delta="-25"/>
- <text
- top_delta="0"
- width="160"
- height="15"
- name="dimension_y"
- left_delta="46"/>
- <text
- top_delta="0"
- width="160"
- height="15"
- name="dimension_z"
- left_delta="46"/>
+ name="content"
+ bg_opaque_color="DkGray2"
+ background_visible="true"
+ background_opaque="true">
+ <text
+ top="20"
+ width="485"
+ font="SansSerifMedium"
+ text_color="White"
+ left="10"
+ name="review_prim_equiv"
+ height="16">Impact to parcel/region: [EQUIV] prim equivalents
+ </text>
+ <text
+ top_pad="20"
+ width="485"
+ font="SansSerifMedium"
+ text_color="White"
+ left="10"
+ name="review_fee"
+ height="16">Your account will be charged an upload fee of L$ [FEE].
+ </text>
+ <text
+ top_pad="20"
+ width="485"
+ font="SansSerifMedium"
+ text_color="White"
+ left="10"
+ name="review_confirmation"
+ height="32"
+ word_wrap="true">By clicking the upload button, you confirm that you have the appropriate rights to the material contained in the model.
+ </text>
</panel>
- <text
- width="300"
- height="12"
- top="125"
- name="streaming cost"
- left="230"
- font="SansSerifSmallBold"
- text_color="White">Resource Cost: [COST]</text>
- <text
- width="285"
- height="30"
- top_pad="0"
- left_delta="0"
- word_wrap="true"
- font="SansSerifItalic">This is the cost to your Region's prim/object limit, at default scale</text>
- <text
- width="300"
- height="12"
- name="physics cost"
- top_pad="10"
- left_delta="0"
- font="SansSerifSmallBold"
- text_color="White">Physics Cost: [COST]</text>
- <text
- width="285"
- height="30"
- top_pad="0"
- left_delta="0"
- word_wrap="true"
- font="SansSerifItalic">This is the cost to your Region's prim/object limit, at default scale</text>
- <text
- width="200"
- height="12"
- top_pad="10"
- left_delta="0"
- font="SansSerifSmallBold"
- text_color="White">Upload Fee:</text>
- <text
- width="285"
- height="26"
- top_pad="0"
- left_delta="0"
- word_wrap="true"
- font="SansSerifItalic">This is the amount the upload will cost.</text>
- <check_box
- height="16"
- layout="topleft"
- left_delta="0"
- name="confirm_checkbox"
- top_pad="15"
- width="16" />
- <text
- height="100"
- width="240"
- word_wrap="true"
- left_delta="25"
- top_delta="0">I confirm that I have the appropriate rights to the material contained in this model. [secondlife:///app/floater/learn_more Learn more]</text>
</panel>
@@ -954,46 +721,79 @@ Advanced users familiar with 3d content creation tools may prefer to use the [se
height="10"
font="SansSerifBig"
layout="topleft">
- Upload Complete!
+ Upload complete
</text>
</panel>
<text
top_pad="14"
- width="474"
- height="20"
- font="SansSerifSmall"
+ width="495"
+ height="16"
+ font="SansSerifMedium"
layout="topleft"
- name="description"
+ name="model_uploaded_text"
+ text_color="White"
word_wrap="true"
- left_delta="5">
- Congratulations! Your model has been sucessfully uploaded. You will find the model in the Objects folder in your inventory.
+ left="25">
+ Your model has been uploaded.
+ </text>
+ <text
+ top_pad="5"
+ width="495"
+ height="16"
+ font="SansSerifMedium"
+ layout="topleft"
+ name="inventory_text"
+ text_color="White"
+ word_wrap="true"
+ left="25">
+ You will find it in the Objects folder in your inventory.
+ </text>
+ <text
+ top_pad="20"
+ width="495"
+ font="SansSerifMedium"
+ text_color="White"
+ left="25"
+ name="charged_fee"
+ height="16">Your account has been charged L$ [FEE].
</text>
- <icon
- top_pad="15"
- left_delta="0"
- width="495"
- height="2"
- image_name="model_wizard\divider_line.png"/>
</panel>
<button
top="440"
- right="-245"
+ right="-285"
width="90"
height="22"
name="back"
label="&lt;&lt; Back" />
<button
top_delta="0"
- right="-150"
+ right="-190"
width="90"
height="22"
name="next"
label="Next &gt;&gt; " />
<button
top_delta="0"
+ left_delta="0"
+ width="160"
+ height="22"
+ name="calculate"
+ label="Calculate weights &amp; fee &gt;&gt; " />
+ <button
+ enabled="false"
+ visible="false"
+ top_delta="0"
+ left_delta="0"
+ width="160"
+ height="22"
+ name="calculating"
+ label="Calculating... " />
+ <button
+ enabled="false"
+ top_delta="0"
right="-150"
width="90"
height="22"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index db1cee5d08..97d84a16c6 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -6841,6 +6841,20 @@ Select residents to share with.
See the log file for details.
</notification>
+ <notification
+ name="MeshUploadPermError"
+ icon="alert.tga"
+ type="alert">
+ Error while requesting mesh upload permissons.
+ </notification>
+
+ <notification
+ name="RegionCapabilityRequestError"
+ icon="alert.tga"
+ type="alert">
+ Could not get region capability &apos;[CAPABILITY]&apos;.
+ </notification>
+
<notification
icon="notifytip.tga"
name="ShareItemsConfirmation"