summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rwxr-xr-xindra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl3
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl3
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl2
-rw-r--r--indra/newview/llfloaterdebugmaterials.cpp1991
-rw-r--r--indra/newview/llfloaterdebugmaterials.h216
-rw-r--r--indra/newview/llviewerfloaterreg.cpp2
-rw-r--r--indra/newview/llviewerobject.cpp21
-rw-r--r--indra/newview/llviewerobject.h14
-rw-r--r--indra/newview/llviewerregion.cpp1
-rw-r--r--indra/newview/llviewershadermgr.cpp10
-rw-r--r--indra/newview/llvovolume.cpp12
-rw-r--r--indra/newview/llvovolume.h2
-rw-r--r--indra/newview/pipeline.cpp52
-rw-r--r--indra/newview/skins/default/colors.xml9
-rw-r--r--indra/newview/skins/default/xui/en/floater_debug_materials.xml1097
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml11
-rw-r--r--indra/newview/tests/llmediadataclient_test.cpp1
-rw-r--r--indra/newview/viewer_manifest.py2
20 files changed, 3404 insertions, 49 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index dff2c04fbc..746703db66 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -194,6 +194,7 @@ set(viewer_SOURCE_FILES
llfloaterbuyland.cpp
llfloatercamera.cpp
llfloatercolorpicker.cpp
+ llfloaterdebugmaterials.cpp
llfloaterdeleteenvpreset.cpp
llfloaterdestinations.cpp
llfloaterdisplayname.cpp
@@ -771,6 +772,7 @@ set(viewer_HEADER_FILES
llfloaterbuyland.h
llfloatercamera.h
llfloatercolorpicker.h
+ llfloaterdebugmaterials.h
llfloaterdeleteenvpreset.h
llfloaterdestinations.h
llfloaterdisplayname.h
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
index 7e79317543..9e194cdcd1 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
@@ -128,8 +128,7 @@ void main()
if (sa > 0.0)
{
- sa = 6 * texture2D(lightFunc, vec2(sa, spec.a)).r * min(dist_atten*4.0, 1.0);
- sa *= noise;
+ sa = texture2D(lightFunc, vec2(sa, spec.a)).r * min(dist_atten*4.0, 1.0);
col += da*sa*light_col[i].rgb*spec.rgb;
}
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
index 75757b26c8..6e5ac8317b 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
@@ -110,8 +110,7 @@ void main()
float sa = dot(normalize(lv-normalize(pos)),norm);
if (sa > 0.0)
{
- sa = 6 * texture2D(lightFunc, vec2(sa, spec.a)).r * min(dist_atten*4.0, 1.0);
- sa *= noise;
+ sa = texture2D(lightFunc, vec2(sa, spec.a)).r * min(dist_atten*4.0, 1.0);
col += da*sa*color.rgb*spec.rgb;
}
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
index 89448e2167..14eaafeb68 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
@@ -301,7 +301,7 @@ void main()
//
vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
float sa = dot(refnormpersp, sun_dir.xyz);
- vec3 dumbshiny = vary_SunlitColor*(6 * texture2D(lightFunc, vec2(sa, spec.a)).r);
+ vec3 dumbshiny = vary_SunlitColor*(texture2D(lightFunc, vec2(sa, spec.a)).r);
// add the two types of shiny together
vec3 spec_contrib = dumbshiny * spec.rgb;
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
index 9df9d75905..457189b48e 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
@@ -309,7 +309,7 @@ void main()
//
vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
float sa = dot(refnormpersp, sun_dir.xyz);
- vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*(6 * texture2D(lightFunc, vec2(sa, spec.a)).r);
+ vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*(texture2D(lightFunc, vec2(sa, spec.a)).r);
// add the two types of shiny together
vec3 spec_contrib = dumbshiny * spec.rgb;
diff --git a/indra/newview/llfloaterdebugmaterials.cpp b/indra/newview/llfloaterdebugmaterials.cpp
new file mode 100644
index 0000000000..3420665883
--- /dev/null
+++ b/indra/newview/llfloaterdebugmaterials.cpp
@@ -0,0 +1,1991 @@
+/**
+* @file llfloaterdebugmaterials.cpp
+* @brief Implementation of llfloaterdebugmaterials
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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 "llfloaterdebugmaterials.h"
+
+#include <string>
+#include <vector>
+#include <map>
+
+#include <boost/shared_ptr.hpp>
+#include <boost/bind.hpp>
+#include <boost/function.hpp>
+#include <boost/signals2.hpp>
+
+#include "llagent.h"
+#include "llbutton.h"
+#include "llcolorswatch.h"
+#include "llenvmanager.h"
+#include "llfloater.h"
+#include "llfontgl.h"
+#include "llhttpclient.h"
+#include "lllineeditor.h"
+#include "llmaterialid.h"
+#include "llresmgr.h"
+#include "llscrolllistcell.h"
+#include "llscrolllistctrl.h"
+#include "llscrolllistitem.h"
+#include "llsd.h"
+#include "llsdserialize.h"
+#include "llselectmgr.h"
+#include "llspinctrl.h"
+#include "llstring.h"
+#include "llstyle.h"
+#include "lltextbase.h"
+#include "lltexturectrl.h"
+#include "lltextvalidate.h"
+#include "llthread.h"
+#include "lluicolortable.h"
+#include "lluictrl.h"
+#include "lluuid.h"
+#include "llviewerobject.h"
+#include "llviewerobjectlist.h"
+#include "llviewerparcelmgr.h"
+#include "llviewerregion.h"
+#include "v4color.h"
+#include "v4coloru.h"
+
+#define MATERIALS_CAPABILITY_NAME "RenderMaterials"
+
+#define MATERIALS_CAP_ZIP_FIELD "Zipped"
+
+#define MATERIALS_CAP_FULL_PER_FACE_FIELD "FullMaterialsPerFace"
+#define MATERIALS_CAP_FACE_FIELD "Face"
+#define MATERIALS_CAP_MATERIAL_FIELD "Material"
+#define MATERIALS_CAP_OBJECT_ID_FIELD "ID"
+#define MATERIALS_CAP_MATERIAL_ID_FIELD "MaterialID"
+
+#define MATERIALS_CAP_NORMAL_MAP_FIELD "NormMap"
+#define MATERIALS_CAP_NORMAL_MAP_OFFSET_X_FIELD "NormOffsetX"
+#define MATERIALS_CAP_NORMAL_MAP_OFFSET_Y_FIELD "NormOffsetY"
+#define MATERIALS_CAP_NORMAL_MAP_REPEAT_X_FIELD "NormRepeatX"
+#define MATERIALS_CAP_NORMAL_MAP_REPEAT_Y_FIELD "NormRepeatY"
+#define MATERIALS_CAP_NORMAL_MAP_ROTATION_FIELD "NormRotation"
+
+#define MATERIALS_CAP_SPECULAR_MAP_FIELD "SpecMap"
+#define MATERIALS_CAP_SPECULAR_MAP_OFFSET_X_FIELD "SpecOffsetX"
+#define MATERIALS_CAP_SPECULAR_MAP_OFFSET_Y_FIELD "SpecOffsetY"
+#define MATERIALS_CAP_SPECULAR_MAP_REPEAT_X_FIELD "SpecRepeatX"
+#define MATERIALS_CAP_SPECULAR_MAP_REPEAT_Y_FIELD "SpecRepeatY"
+#define MATERIALS_CAP_SPECULAR_MAP_ROTATION_FIELD "SpecRotation"
+
+#define MATERIALS_CAP_SPECULAR_COLOR_FIELD "SpecColor"
+#define MATERIALS_CAP_SPECULAR_EXP_FIELD "SpecExp"
+#define MATERIALS_CAP_ENV_INTENSITY_FIELD "EnvIntensity"
+#define MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD "AlphaMaskCutoff"
+#define MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD "DiffuseAlphaMode"
+
+#define MULTI_MATERIALS_STATUS_FIELD "status"
+#define MULTI_MATERIALS_DATA_FIELD "data"
+
+#define VIEWABLE_OBJECTS_REGION_ID_FIELD "regionId"
+#define VIEWABLE_OBJECTS_OBJECT_ID_FIELD "objectId"
+#define VIEWABLE_OBJECTS_MATERIAL_ID_FIELD "materialId"
+
+class MaterialsResponder : public LLHTTPClient::Responder
+{
+public:
+ typedef boost::function<void (bool, const LLSD&)> CallbackFunction;
+
+ MaterialsResponder(const std::string& pMethod, const std::string& pCapabilityURL, CallbackFunction pCallback);
+ virtual ~MaterialsResponder();
+
+ virtual void result(const LLSD& pContent);
+ virtual void error(U32 pStatus, const std::string& pReason);
+
+protected:
+
+private:
+ std::string mMethod;
+ std::string mCapabilityURL;
+ CallbackFunction mCallback;
+};
+
+class MultiMaterialsResponder
+{
+public:
+ typedef boost::function<void (bool, const LLSD&)> CallbackFunction;
+
+ MultiMaterialsResponder(CallbackFunction pCallback, unsigned int pNumRequests);
+ virtual ~MultiMaterialsResponder();
+
+ void onMaterialsResponse(bool pRequestStatus, const LLSD& pContent);
+
+protected:
+
+private:
+ bool appendRequestResults(bool pRequestStatus, const LLSD& pResults);
+ void fireResponse();
+
+ CallbackFunction mCallback;
+ unsigned int mNumRequests;
+
+ bool mRequestStatus;
+ LLSD mContent;
+ LLMutex* mMutex;
+};
+
+BOOL LLFloaterDebugMaterials::postBuild()
+{
+ mStatusText = findChild<LLTextBase>("material_status");
+ llassert(mStatusText != NULL);
+
+ mGetButton = findChild<LLButton>("get_button");
+ llassert(mGetButton != NULL);
+ mGetButton->setCommitCallback(boost::bind(&LLFloaterDebugMaterials::onGetClicked, this));
+
+ mParsingStatusText = findChild<LLTextBase>("loading_status");
+ llassert(mParsingStatusText != NULL);
+
+ mGetNormalMapScrollList = findChild<LLScrollListCtrl>("get_normal_map_scroll_list");
+ llassert(mGetNormalMapScrollList != NULL);
+ mGetNormalMapScrollList->setCommitCallback(boost::bind(&LLFloaterDebugMaterials::onGetScrollListSelectionChange, this, _1));
+
+ mGetSpecularMapScrollList = findChild<LLScrollListCtrl>("get_specular_map_scroll_list");
+ llassert(mGetSpecularMapScrollList != NULL);
+ mGetSpecularMapScrollList->setCommitCallback(boost::bind(&LLFloaterDebugMaterials::onGetScrollListSelectionChange, this, _1));
+
+ mGetOtherDataScrollList = findChild<LLScrollListCtrl>("get_other_data_scroll_list");
+ llassert(mGetOtherDataScrollList != NULL);
+ mGetOtherDataScrollList->setCommitCallback(boost::bind(&LLFloaterDebugMaterials::onGetScrollListSelectionChange, this, _1));
+
+ mNormalMap = findChild<LLTextureCtrl>("normal_map");
+ llassert(mNormalMap != NULL);
+
+ mNormalMapOffsetX = findChild<LLLineEditor>("normal_map_offset_x");
+ llassert(mNormalMapOffsetX != NULL);
+ mNormalMapOffsetX->setPrevalidate(LLTextValidate::validateInt);
+ mNormalMapOffsetX->setCommitCallback(boost::bind(&LLFloaterDebugMaterials::onValueEntered, this, _1));
+
+ mNormalMapOffsetY = findChild<LLLineEditor>("normal_map_offset_y");
+ llassert(mNormalMapOffsetY != NULL);
+ mNormalMapOffsetY->setPrevalidate(LLTextValidate::validateInt);
+ mNormalMapOffsetY->setCommitCallback(boost::bind(&LLFloaterDebugMaterials::onValueEntered, this, _1));
+
+ mNormalMapRepeatX = findChild<LLLineEditor>("normal_map_repeat_x");
+ llassert(mNormalMapRepeatX != NULL);
+ mNormalMapRepeatX->setPrevalidate(LLTextValidate::validateInt);
+ mNormalMapRepeatX->setCommitCallback(boost::bind(&LLFloaterDebugMaterials::onValueEntered, this, _1));
+
+ mNormalMapRepeatY = findChild<LLLineEditor>("normal_map_repeat_y");
+ llassert(mNormalMapRepeatY != NULL);
+ mNormalMapRepeatY->setPrevalidate(LLTextValidate::validateInt);
+ mNormalMapRepeatY->setCommitCallback(boost::bind(&LLFloaterDebugMaterials::onValueEntered, this, _1));
+
+ mNormalMapRotation = findChild<LLLineEditor>("normal_map_rotation");
+ llassert(mNormalMapRotation != NULL);
+ mNormalMapRotation->setPrevalidate(LLTextValidate::validateInt);
+ mNormalMapRotation->setCommitCallback(boost::bind(&LLFloaterDebugMaterials::onValueEntered, this, _1));
+
+ mSpecularMap = findChild<LLTextureCtrl>("specular_map");
+ llassert(mSpecularMap != NULL);
+
+ mSpecularMapOffsetX = findChild<LLLineEditor>("specular_map_offset_x");
+ llassert(mSpecularMapOffsetX != NULL);
+ mSpecularMapOffsetX->setPrevalidate(LLTextValidate::validateInt);
+ mSpecularMapOffsetX->setCommitCallback(boost::bind(&LLFloaterDebugMaterials::onValueEntered, this, _1));
+
+ mSpecularMapOffsetY = findChild<LLLineEditor>("specular_map_offset_y");
+ llassert(mSpecularMapOffsetY != NULL);
+ mSpecularMapOffsetY->setPrevalidate(LLTextValidate::validateInt);
+ mSpecularMapOffsetY->setCommitCallback(boost::bind(&LLFloaterDebugMaterials::onValueEntered, this, _1));
+
+ mSpecularMapRepeatX = findChild<LLLineEditor>("specular_map_repeat_x");
+ llassert(mSpecularMapRepeatX != NULL);
+ mSpecularMapRepeatX->setPrevalidate(LLTextValidate::validateInt);
+ mSpecularMapRepeatX->setCommitCallback(boost::bind(&LLFloaterDebugMaterials::onValueEntered, this, _1));
+
+ mSpecularMapRepeatY = findChild<LLLineEditor>("specular_map_repeat_y");
+ llassert(mSpecularMapRepeatY != NULL);
+ mSpecularMapRepeatY->setPrevalidate(LLTextValidate::validateInt);
+ mSpecularMapRepeatY->setCommitCallback(boost::bind(&LLFloaterDebugMaterials::onValueEntered, this, _1));
+
+ mSpecularMapRotation = findChild<LLLineEditor>("specular_map_rotation");
+ llassert(mSpecularMapRotation != NULL);
+ mSpecularMapRotation->setPrevalidate(LLTextValidate::validateInt);
+ mSpecularMapRotation->setCommitCallback(boost::bind(&LLFloaterDebugMaterials::onValueEntered, this, _1));
+
+ mSpecularColor = findChild<LLColorSwatchCtrl>("specular_color");
+ llassert(mSpecularColor != NULL);
+
+ mSpecularColorAlpha = findChild<LLSpinCtrl>("specular_color_alpha");
+ llassert(mSpecularColorAlpha != NULL);
+
+ mSpecularExponent = findChild<LLLineEditor>("specular_exponent");
+ llassert(mSpecularExponent != NULL);
+ mSpecularExponent->setPrevalidate(LLTextValidate::validateInt);
+ mSpecularExponent->setCommitCallback(boost::bind(&LLFloaterDebugMaterials::onValueEntered, this, _1));
+
+ mEnvironmentExponent = findChild<LLLineEditor>("environment_exponent");
+ llassert(mEnvironmentExponent != NULL);
+ mEnvironmentExponent->setPrevalidate(LLTextValidate::validateInt);
+ mEnvironmentExponent->setCommitCallback(boost::bind(&LLFloaterDebugMaterials::onValueEntered, this, _1));
+
+ mAlphaMaskCutoff = findChild<LLLineEditor>("alpha_mask_cutoff");
+ llassert(mAlphaMaskCutoff != NULL);
+ mAlphaMaskCutoff->setPrevalidate(LLTextValidate::validateInt);
+ mAlphaMaskCutoff->setCommitCallback(boost::bind(&LLFloaterDebugMaterials::onValueEntered, this, _1));
+
+ mDiffuseAlphaMode = findChild<LLLineEditor>("diffuse_alpha_mode");
+ llassert(mDiffuseAlphaMode != NULL);
+ mDiffuseAlphaMode->setPrevalidate(LLTextValidate::validateInt);
+ mDiffuseAlphaMode->setCommitCallback(boost::bind(&LLFloaterDebugMaterials::onValueEntered, this, _1));
+
+ mPutSetButton = findChild<LLButton>("put_set_button");
+ llassert(mPutSetButton != NULL);
+ mPutSetButton->setCommitCallback(boost::bind(&LLFloaterDebugMaterials::onPutSetClicked, this));
+
+ mPutClearButton = findChild<LLButton>("put_clear_button");
+ llassert(mPutClearButton != NULL);
+ mPutClearButton->setCommitCallback(boost::bind(&LLFloaterDebugMaterials::onPutClearClicked, this));
+
+ LLButton* resetPutValuesButton = findChild<LLButton>("reset_put_values_button");
+ llassert(resetPutValuesButton != NULL);
+ resetPutValuesButton->setCommitCallback(boost::bind(&LLFloaterDebugMaterials::onResetPutValuesClicked, this));
+
+ mPutScrollList = findChild<LLScrollListCtrl>("put_scroll_list");
+ llassert(mPutScrollList != NULL);
+
+ mQueryViewableObjectsButton = findChild<LLButton>("query_viewable_objects_button");
+ llassert(mQueryViewableObjectsButton != NULL);
+ mQueryViewableObjectsButton->setCommitCallback(boost::bind(&LLFloaterDebugMaterials::onQueryVisibleObjectsClicked, this));
+
+ mQueryStatusText = findChild<LLTextBase>("query_status");
+ llassert(mQueryStatusText != NULL);
+
+ mViewableObjectsScrollList = findChild<LLScrollListCtrl>("viewable_objects_scroll_list");
+ llassert(mViewableObjectsScrollList != NULL);
+ mViewableObjectsScrollList->setCommitCallback(boost::bind(&LLFloaterDebugMaterials::onViewableObjectsScrollListSelectionChange, this));
+
+ mPostButton = findChild<LLButton>("post_button");
+ llassert(mPostButton != NULL);
+ mPostButton->setCommitCallback(boost::bind(&LLFloaterDebugMaterials::onPostClicked, this));
+
+ mPostNormalMapScrollList = findChild<LLScrollListCtrl>("post_normal_map_scroll_list");
+ llassert(mPostNormalMapScrollList != NULL);
+ mPostNormalMapScrollList->setCommitCallback(boost::bind(&LLFloaterDebugMaterials::onPostScrollListSelectionChange, this, _1));
+
+ mPostSpecularMapScrollList = findChild<LLScrollListCtrl>("post_specular_map_scroll_list");
+ llassert(mPostSpecularMapScrollList != NULL);
+ mPostSpecularMapScrollList->setCommitCallback(boost::bind(&LLFloaterDebugMaterials::onPostScrollListSelectionChange, this, _1));
+
+ mPostOtherDataScrollList = findChild<LLScrollListCtrl>("post_other_data_scroll_list");
+ llassert(mPostOtherDataScrollList != NULL);
+ mPostOtherDataScrollList->setCommitCallback(boost::bind(&LLFloaterDebugMaterials::onPostScrollListSelectionChange, this, _1));
+
+ mDefaultSpecularColor = LLUIColorTable::instance().getColor("White");
+
+ mWarningColor = LLUIColorTable::instance().getColor("MaterialWarningColor");
+ mErrorColor = LLUIColorTable::instance().getColor("MaterialErrorColor");
+
+ setState(kNoRegion);
+
+ return LLFloater::postBuild();
+}
+
+void LLFloaterDebugMaterials::onOpen(const LLSD& pKey)
+{
+ LLFloater::onOpen(pKey);
+
+ if (!mRegionCrossConnection.connected())
+ {
+ mRegionCrossConnection = LLEnvManagerNew::instance().setRegionChangeCallback(boost::bind(&LLFloaterDebugMaterials::onRegionCross, this));
+ }
+
+ if (!mTeleportFailedConnection.connected())
+ {
+ mTeleportFailedConnection = LLViewerParcelMgr::getInstance()->setTeleportFailedCallback(boost::bind(&LLFloaterDebugMaterials::onRegionCross, this));
+ }
+
+ if (!mSelectionUpdateConnection.connected())
+ {
+ mSelectionUpdateConnection = LLSelectMgr::getInstance()->mUpdateSignal.connect(boost::bind(&LLFloaterDebugMaterials::onInWorldSelectionChange, this));
+ }
+
+ checkRegionMaterialStatus();
+ resetObjectEditInputs();
+ clearGetResults();
+ clearPutResults();
+ clearViewableObjectsResults();
+ clearPostResults();
+}
+
+void LLFloaterDebugMaterials::onClose(bool pIsAppQuitting)
+{
+ resetObjectEditInputs();
+ clearGetResults();
+ clearPutResults();
+ clearViewableObjectsResults();
+ clearPostResults();
+
+ if (mSelectionUpdateConnection.connected())
+ {
+ mSelectionUpdateConnection.disconnect();
+ }
+
+ if (mTeleportFailedConnection.connected())
+ {
+ mTeleportFailedConnection.disconnect();
+ }
+
+ if (mRegionCrossConnection.connected())
+ {
+ mRegionCrossConnection.disconnect();
+ }
+
+ LLFloater::onClose(pIsAppQuitting);
+}
+
+void LLFloaterDebugMaterials::draw()
+{
+ if (mUnparsedGetData.isDefined())
+ {
+ parseGetResponse();
+ }
+ if (mNextUnparsedQueryDataIndex >= 0)
+ {
+ parseQueryViewableObjects();
+ }
+ LLFloater::draw();
+}
+
+LLFloaterDebugMaterials::LLFloaterDebugMaterials(const LLSD& pParams)
+ : LLFloater(pParams),
+ mStatusText(NULL),
+ mGetButton(NULL),
+ mParsingStatusText(NULL),
+ mGetNormalMapScrollList(NULL),
+ mGetSpecularMapScrollList(NULL),
+ mGetOtherDataScrollList(NULL),
+ mNormalMap(NULL),
+ mNormalMapOffsetX(NULL),
+ mNormalMapOffsetY(NULL),
+ mNormalMapRepeatX(NULL),
+ mNormalMapRepeatY(NULL),
+ mNormalMapRotation(NULL),
+ mSpecularMap(NULL),
+ mSpecularMapOffsetX(NULL),
+ mSpecularMapOffsetY(NULL),
+ mSpecularMapRepeatX(NULL),
+ mSpecularMapRepeatY(NULL),
+ mSpecularMapRotation(NULL),
+ mSpecularColor(NULL),
+ mSpecularColorAlpha(NULL),
+ mSpecularExponent(NULL),
+ mEnvironmentExponent(NULL),
+ mAlphaMaskCutoff(NULL),
+ mDiffuseAlphaMode(NULL),
+ mPutSetButton(NULL),
+ mPutClearButton(NULL),
+ mPutScrollList(NULL),
+ mQueryViewableObjectsButton(NULL),
+ mQueryStatusText(NULL),
+ mViewableObjectsScrollList(NULL),
+ mPostButton(NULL),
+ mPostNormalMapScrollList(NULL),
+ mPostSpecularMapScrollList(NULL),
+ mPostOtherDataScrollList(NULL),
+ mState(kNoRegion),
+ mWarningColor(),
+ mErrorColor(),
+ mRegionCrossConnection(),
+ mTeleportFailedConnection(),
+ mSelectionUpdateConnection(),
+ mUnparsedGetData(),
+ mNextUnparsedGetDataIndex(-1),
+ mNextUnparsedQueryDataIndex(-1),
+ mMultiMaterialsResponder()
+{
+}
+
+LLFloaterDebugMaterials::~LLFloaterDebugMaterials()
+{
+ if (!mMultiMaterialsResponder)
+ {
+ mMultiMaterialsResponder.reset();
+ }
+}
+
+void LLFloaterDebugMaterials::onGetClicked()
+{
+ requestGetMaterials();
+}
+
+void LLFloaterDebugMaterials::onValueEntered(LLUICtrl* pUICtrl)
+{
+ LLLineEditor *pLineEditor = static_cast<LLLineEditor *>(pUICtrl);
+ llassert(pLineEditor != NULL);
+
+ const std::string &valueString = pLineEditor->getText();
+
+ S32 intValue = 0;
+ bool doResetValue = (!valueString.empty() && !LLStringUtil::convertToS32(valueString, intValue));
+
+ if (doResetValue)
+ {
+ LL_WARNS("debugMaterials") << "cannot parse string '" << valueString << "' to an S32 value" <<LL_ENDL;
+ LLSD value = static_cast<LLSD::Integer>(intValue);
+ pLineEditor->setValue(value);
+ }
+}
+
+void LLFloaterDebugMaterials::onPutSetClicked()
+{
+ requestPutMaterials(true);
+}
+
+void LLFloaterDebugMaterials::onPutClearClicked()
+{
+ requestPutMaterials(false);
+}
+
+void LLFloaterDebugMaterials::onResetPutValuesClicked()
+{
+ resetObjectEditInputs();
+}
+
+void LLFloaterDebugMaterials::onQueryVisibleObjectsClicked()
+{
+ clearViewableObjectsResults();
+ setUnparsedQueryData();
+}
+
+void LLFloaterDebugMaterials::onPostClicked()
+{
+ requestPostMaterials();
+}
+
+void LLFloaterDebugMaterials::onRegionCross()
+{
+ checkRegionMaterialStatus();
+ clearGetResults();
+ clearPutResults();
+ clearViewableObjectsResults();
+ clearPostResults();
+}
+
+void LLFloaterDebugMaterials::onInWorldSelectionChange()
+{
+ updateControls();
+}
+
+void LLFloaterDebugMaterials::onGetScrollListSelectionChange(LLUICtrl* pUICtrl)
+{
+ LLScrollListCtrl* scrollListCtrl = dynamic_cast<LLScrollListCtrl*>(pUICtrl);
+ llassert(scrollListCtrl != NULL);
+
+ if (scrollListCtrl != mGetNormalMapScrollList)
+ {
+ mGetNormalMapScrollList->deselectAllItems(TRUE);
+ }
+ if (scrollListCtrl != mGetSpecularMapScrollList)
+ {
+ mGetSpecularMapScrollList->deselectAllItems(TRUE);
+ }
+ if (scrollListCtrl != mGetOtherDataScrollList)
+ {
+ mGetOtherDataScrollList->deselectAllItems(TRUE);
+ }
+
+ std::vector<LLScrollListItem*> selectedItems = scrollListCtrl->getAllSelected();
+ if (!selectedItems.empty())
+ {
+ llassert(selectedItems.size() == 1);
+ LLScrollListItem* selectedItem = selectedItems.front();
+
+ llassert(selectedItem != NULL);
+ const LLSD& selectedIdValue = selectedItem->getValue();
+
+ if (scrollListCtrl != mGetNormalMapScrollList)
+ {
+ mGetNormalMapScrollList->selectByValue(selectedIdValue);
+ mGetNormalMapScrollList->scrollToShowSelected();
+ }
+ if (scrollListCtrl != mGetSpecularMapScrollList)
+ {
+ mGetSpecularMapScrollList->selectByValue(selectedIdValue);
+ mGetSpecularMapScrollList->scrollToShowSelected();
+ }
+ if (scrollListCtrl != mGetOtherDataScrollList)
+ {
+ mGetOtherDataScrollList->selectByValue(selectedIdValue);
+ mGetOtherDataScrollList->scrollToShowSelected();
+ }
+ }
+}
+
+void LLFloaterDebugMaterials::onPostScrollListSelectionChange(LLUICtrl* pUICtrl)
+{
+ LLScrollListCtrl* scrollListCtrl = dynamic_cast<LLScrollListCtrl*>(pUICtrl);
+ llassert(scrollListCtrl != NULL);
+
+ if (scrollListCtrl != mPostNormalMapScrollList)
+ {
+ mPostNormalMapScrollList->deselectAllItems(TRUE);
+ }
+ if (scrollListCtrl != mPostSpecularMapScrollList)
+ {
+ mPostSpecularMapScrollList->deselectAllItems(TRUE);
+ }
+ if (scrollListCtrl != mPostOtherDataScrollList)
+ {
+ mPostOtherDataScrollList->deselectAllItems(TRUE);
+ }
+
+ std::vector<LLScrollListItem*> selectedItems = scrollListCtrl->getAllSelected();
+ if (!selectedItems.empty())
+ {
+ llassert(selectedItems.size() == 1);
+ LLScrollListItem* selectedItem = selectedItems.front();
+
+ llassert(selectedItem != NULL);
+ const LLSD& selectedIdValue = selectedItem->getValue();
+
+ if (scrollListCtrl != mPostNormalMapScrollList)
+ {
+ mPostNormalMapScrollList->selectByValue(selectedIdValue);
+ mPostNormalMapScrollList->scrollToShowSelected();
+ }
+ if (scrollListCtrl != mPostSpecularMapScrollList)
+ {
+ mPostSpecularMapScrollList->selectByValue(selectedIdValue);
+ mPostSpecularMapScrollList->scrollToShowSelected();
+ }
+ if (scrollListCtrl != mPostOtherDataScrollList)
+ {
+ mPostOtherDataScrollList->selectByValue(selectedIdValue);
+ mPostOtherDataScrollList->scrollToShowSelected();
+ }
+ }
+}
+
+void LLFloaterDebugMaterials::onViewableObjectsScrollListSelectionChange()
+{
+ updateControls();
+}
+
+void LLFloaterDebugMaterials::onDeferredCheckRegionMaterialStatus(LLUUID regionId)
+{
+ checkRegionMaterialStatus(regionId);
+}
+
+void LLFloaterDebugMaterials::onDeferredRequestGetMaterials(LLUUID regionId)
+{
+ requestGetMaterials(regionId);
+}
+
+void LLFloaterDebugMaterials::onDeferredRequestPutMaterials(LLUUID regionId, bool pIsDoSet)
+{
+ requestPutMaterials(regionId, pIsDoSet);
+}
+
+void LLFloaterDebugMaterials::onGetResponse(bool pRequestStatus, const LLSD& pContent)
+{
+ clearGetResults();
+ if (pRequestStatus)
+ {
+ setState(kRequestCompleted);
+ setUnparsedGetData(pContent);
+ }
+ else
+ {
+ setState(kError);
+ }
+}
+
+void LLFloaterDebugMaterials::onPutResponse(bool pRequestStatus, const LLSD& pContent)
+{
+ if (pRequestStatus)
+ {
+ setState(kRequestCompleted);
+ parsePutResponse(pContent);
+ }
+ else
+ {
+ setState(kError);
+ }
+}
+
+void LLFloaterDebugMaterials::onPostResponse(bool pRequestStatus, const LLSD& pContent)
+{
+ if (pRequestStatus)
+ {
+ setState(kRequestCompleted);
+ parsePostResponse(pContent);
+ }
+ else
+ {
+ setState(kError);
+ }
+ mMultiMaterialsResponder.reset();
+}
+
+void LLFloaterDebugMaterials::checkRegionMaterialStatus()
+{
+ LLViewerRegion *region = gAgent.getRegion();
+
+ if (region == NULL)
+ {
+ LL_WARNS("debugMaterials") << "Region is NULL" << LL_ENDL;
+ setState(kNoRegion);
+ }
+ else if (!region->capabilitiesReceived())
+ {
+ setState(kCapabilitiesLoading);
+ region->setCapabilitiesReceivedCallback(boost::bind(&LLFloaterDebugMaterials::onDeferredCheckRegionMaterialStatus, this, region->getRegionID()));
+ }
+ else
+ {
+ std::string capURL = region->getCapability(MATERIALS_CAPABILITY_NAME);
+
+ if (capURL.empty())
+ {
+ LL_WARNS("debugMaterials") << "Capability '" << MATERIALS_CAPABILITY_NAME
+ << "' is not defined on the current region '" << region->getName() << "'" << LL_ENDL;
+ setState(kNotEnabled);
+ }
+ else
+ {
+ setState(kReady);
+ }
+ }
+}
+
+void LLFloaterDebugMaterials::checkRegionMaterialStatus(const LLUUID& regionId)
+{
+ const LLViewerRegion *region = gAgent.getRegion();
+
+ if ((region != NULL) && (region->getRegionID() == regionId))
+ {
+ checkRegionMaterialStatus();
+ }
+}
+
+void LLFloaterDebugMaterials::requestGetMaterials()
+{
+ LLViewerRegion *region = gAgent.getRegion();
+
+ if (region == NULL)
+ {
+ LL_WARNS("debugMaterials") << "Region is NULL" << LL_ENDL;
+ setState(kNoRegion);
+ }
+ else if (!region->capabilitiesReceived())
+ {
+ setState(kCapabilitiesLoading);
+ region->setCapabilitiesReceivedCallback(boost::bind(&LLFloaterDebugMaterials::onDeferredRequestGetMaterials, this, region->getRegionID()));
+ }
+ else
+ {
+ std::string capURL = region->getCapability(MATERIALS_CAPABILITY_NAME);
+
+ if (capURL.empty())
+ {
+ LL_WARNS("debugMaterials") << "Capability '" << MATERIALS_CAPABILITY_NAME
+ << "' is not defined on the current region '" << region->getName() << "'" << LL_ENDL;
+ setState(kNotEnabled);
+ }
+ else
+ {
+ setState(kRequestStarted);
+ LLHTTPClient::ResponderPtr materialsResponder = new MaterialsResponder("GET", capURL, boost::bind(&LLFloaterDebugMaterials::onGetResponse, this, _1, _2));
+ LLHTTPClient::get(capURL, materialsResponder);
+ }
+ }
+}
+
+void LLFloaterDebugMaterials::requestGetMaterials(const LLUUID& regionId)
+{
+ const LLViewerRegion *region = gAgent.getRegion();
+
+ if ((region != NULL) && (region->getRegionID() == regionId))
+ {
+ requestGetMaterials();
+ }
+}
+
+void LLFloaterDebugMaterials::requestPutMaterials(bool pIsDoSet)
+{
+ LLViewerRegion *region = gAgent.getRegion();
+
+ if (region == NULL)
+ {
+ LL_WARNS("debugMaterials") << "Region is NULL" << LL_ENDL;
+ setState(kNoRegion);
+ }
+ else if (!region->capabilitiesReceived())
+ {
+ setState(kCapabilitiesLoading);
+ region->setCapabilitiesReceivedCallback(boost::bind(&LLFloaterDebugMaterials::onDeferredRequestPutMaterials, this, region->getRegionID(), pIsDoSet));
+ }
+ else
+ {
+ std::string capURL = region->getCapability(MATERIALS_CAPABILITY_NAME);
+
+ if (capURL.empty())
+ {
+ LL_WARNS("debugMaterials") << "Capability '" << MATERIALS_CAPABILITY_NAME
+ << "' is not defined on the current region '" << region->getName() << "'" << LL_ENDL;
+ setState(kNotEnabled);
+ }
+ else
+ {
+ setState(kRequestStarted);
+
+ LLSD facesData = LLSD::emptyArray();
+
+ LLSD materialData = LLSD::emptyMap();
+ if (pIsDoSet)
+ {
+ materialData[MATERIALS_CAP_NORMAL_MAP_FIELD] = mNormalMap->getImageAssetID();
+ materialData[MATERIALS_CAP_NORMAL_MAP_OFFSET_X_FIELD] = static_cast<LLSD::Integer>(getNormalMapOffsetX());
+ materialData[MATERIALS_CAP_NORMAL_MAP_OFFSET_Y_FIELD] = static_cast<LLSD::Integer>(getNormalMapOffsetY());
+ materialData[MATERIALS_CAP_NORMAL_MAP_REPEAT_X_FIELD] = static_cast<LLSD::Integer>(getNormalMapRepeatX());
+ materialData[MATERIALS_CAP_NORMAL_MAP_REPEAT_Y_FIELD] = static_cast<LLSD::Integer>(getNormalMapRepeatY());
+ materialData[MATERIALS_CAP_NORMAL_MAP_ROTATION_FIELD] = static_cast<LLSD::Integer>(getNormalMapRotation());
+
+ materialData[MATERIALS_CAP_SPECULAR_MAP_FIELD] = mSpecularMap->getImageAssetID();
+ materialData[MATERIALS_CAP_SPECULAR_MAP_OFFSET_X_FIELD] = static_cast<LLSD::Integer>(getSpecularMapOffsetX());
+ materialData[MATERIALS_CAP_SPECULAR_MAP_OFFSET_Y_FIELD] = static_cast<LLSD::Integer>(getSpecularMapOffsetY());
+ materialData[MATERIALS_CAP_SPECULAR_MAP_REPEAT_X_FIELD] = static_cast<LLSD::Integer>(getSpecularMapRepeatX());
+ materialData[MATERIALS_CAP_SPECULAR_MAP_REPEAT_Y_FIELD] = static_cast<LLSD::Integer>(getSpecularMapRepeatY());
+ materialData[MATERIALS_CAP_SPECULAR_MAP_ROTATION_FIELD] = static_cast<LLSD::Integer>(getSpecularMapRotation());
+
+ LLColor4U specularColor = getSpecularColor();
+ materialData[MATERIALS_CAP_SPECULAR_COLOR_FIELD] = specularColor.getValue();
+ materialData[MATERIALS_CAP_SPECULAR_EXP_FIELD] = static_cast<LLSD::Integer>(getSpecularExponent());
+ materialData[MATERIALS_CAP_ENV_INTENSITY_FIELD] = static_cast<LLSD::Integer>(getEnvironmentExponent());
+ materialData[MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD] = static_cast<LLSD::Integer>(getAlphMaskCutoff());
+ materialData[MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD] = static_cast<LLSD::Integer>(getDiffuseAlphaMode());
+ }
+
+ LLObjectSelectionHandle selectionHandle = LLSelectMgr::getInstance()->getEditSelection();
+ for (LLObjectSelection::valid_iterator objectIter = selectionHandle->valid_begin();
+ objectIter != selectionHandle->valid_end(); ++objectIter)
+ {
+ LLSelectNode* objectNode = *objectIter;
+ LLViewerObject* viewerObject = objectNode->getObject();
+
+ if (viewerObject != NULL)
+ {
+ const LLViewerRegion* viewerRegion = viewerObject->getRegion();
+ if (region != viewerRegion)
+ {
+ LL_ERRS("debugMaterials") << "cannot currently edit an object on a different region through the debug materials floater" << llendl;
+ }
+ S32 numTEs = llmin(static_cast<S32>(viewerObject->getNumTEs()), viewerObject->getNumFaces());
+ for (S32 curTEIndex = 0; curTEIndex < numTEs; ++curTEIndex)
+ {
+ if (objectNode->isTESelected(curTEIndex))
+ {
+ LLSD faceData = LLSD::emptyMap();
+ faceData[MATERIALS_CAP_FACE_FIELD] = static_cast<LLSD::Integer>(curTEIndex);
+ faceData[MATERIALS_CAP_OBJECT_ID_FIELD] = static_cast<LLSD::Integer>(viewerObject->getLocalID());
+ if (pIsDoSet)
+ {
+ faceData[MATERIALS_CAP_MATERIAL_FIELD] = materialData;
+ }
+ facesData.append(faceData);
+ }
+ }
+ }
+ }
+
+ LLSD materialsData = LLSD::emptyMap();
+ materialsData[MATERIALS_CAP_FULL_PER_FACE_FIELD] = facesData;
+
+ std::string materialString = zip_llsd(materialsData);
+ S32 materialSize = materialString.size();
+
+ if (materialSize <= 0)
+ {
+ LL_ERRS("debugMaterials") << "cannot zip LLSD binary content" << LL_ENDL;
+ }
+ else
+ {
+ LLSD::Binary materialBinary;
+ materialBinary.resize(materialSize);
+ memcpy(materialBinary.data(), materialString.data(), materialSize);
+
+ LLSD putData = LLSD::emptyMap();
+ putData[MATERIALS_CAP_ZIP_FIELD] = materialBinary;
+
+ LLHTTPClient::ResponderPtr materialsResponder = new MaterialsResponder("PUT", capURL, boost::bind(&LLFloaterDebugMaterials::onPutResponse, this, _1, _2));
+ LLHTTPClient::put(capURL, putData, materialsResponder);
+ }
+ }
+ }
+}
+
+void LLFloaterDebugMaterials::requestPutMaterials(const LLUUID& regionId, bool pIsDoSet)
+{
+ const LLViewerRegion *region = gAgent.getRegion();
+
+ if ((region != NULL) && (region->getRegionID() == regionId))
+ {
+ requestPutMaterials(pIsDoSet);
+ }
+}
+
+void LLFloaterDebugMaterials::requestPostMaterials()
+{
+ llassert(!mMultiMaterialsResponder);
+
+ std::vector<LLScrollListItem*> selectedItems = mViewableObjectsScrollList->getAllSelected();
+ std::map<LLUUID, std::string> uniqueRegions;
+
+ if (!selectedItems.empty())
+ {
+ for (std::vector<LLScrollListItem*>::const_iterator selectedItemIter = selectedItems.begin();
+ selectedItemIter != selectedItems.end(); ++selectedItemIter)
+ {
+ const LLScrollListItem* selectedItem = *selectedItemIter;
+ const LLSD& selectedItemValue = selectedItem->getValue();
+ llassert(selectedItemValue.isMap());
+
+ llassert(selectedItemValue.has(VIEWABLE_OBJECTS_REGION_ID_FIELD));
+ llassert(selectedItemValue.get(VIEWABLE_OBJECTS_REGION_ID_FIELD).isUUID());
+ const LLUUID& regionId = selectedItemValue.get(VIEWABLE_OBJECTS_REGION_ID_FIELD).asUUID();
+ if (uniqueRegions.find(regionId) == uniqueRegions.end())
+ {
+ llassert(selectedItemValue.has(VIEWABLE_OBJECTS_OBJECT_ID_FIELD));
+ llassert(selectedItemValue.get(VIEWABLE_OBJECTS_OBJECT_ID_FIELD).isUUID());
+ const LLUUID& objectId = selectedItemValue.get(VIEWABLE_OBJECTS_OBJECT_ID_FIELD).asUUID();
+ LLViewerObject* viewerObject = gObjectList.findObject(objectId);
+ if (viewerObject != NULL)
+ {
+ LLViewerRegion* region = viewerObject->getRegion();
+ if (region != NULL)
+ {
+ if (!region->capabilitiesReceived())
+ {
+ LL_WARNS("debugMaterials") << "region '" << region->getName() << "' (id:"
+ << region->getRegionID().asString() << ") has not received capabilities"
+ << LL_ENDL;
+ }
+ else
+ {
+ std::string capURL = region->getCapability(MATERIALS_CAPABILITY_NAME);
+
+ if (capURL.empty())
+ {
+ LL_WARNS("debugMaterials") << "Capability '" << MATERIALS_CAPABILITY_NAME
+ << "' is not defined on the current region '" << region->getName() << "'" << LL_ENDL;
+ }
+ else
+ {
+ uniqueRegions.insert(std::make_pair<LLUUID, std::string>(regionId, capURL));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ unsigned int numRegions = static_cast<unsigned int>(uniqueRegions.size());
+
+ if (numRegions > 0U)
+ {
+ setState(kRequestStarted);
+ mMultiMaterialsResponder = MultiMaterialsResponderPtr(new MultiMaterialsResponder(boost::bind(&LLFloaterDebugMaterials::onPostResponse, this, _1, _2), numRegions));
+
+ for (std::map<LLUUID, std::string>::const_iterator regionIdIter = uniqueRegions.begin();
+ regionIdIter != uniqueRegions.end(); ++regionIdIter)
+ {
+ const LLUUID& regionId = regionIdIter->first;
+ std::string capURL = regionIdIter->second;
+
+ LLSD materialIdsData = LLSD::emptyArray();
+
+ for (std::vector<LLScrollListItem*>::const_iterator selectedItemIter = selectedItems.begin();
+ selectedItemIter != selectedItems.end(); ++selectedItemIter)
+ {
+ const LLScrollListItem* selectedItem = *selectedItemIter;
+ const LLSD& selectedItemValue = selectedItem->getValue();
+
+ llassert(selectedItemValue.has(VIEWABLE_OBJECTS_REGION_ID_FIELD));
+ llassert(selectedItemValue.get(VIEWABLE_OBJECTS_REGION_ID_FIELD).isUUID());
+ const LLUUID& selectedItemRegionId = selectedItemValue.get(VIEWABLE_OBJECTS_REGION_ID_FIELD).asUUID();
+ if (selectedItemRegionId == regionId)
+ {
+ llassert(selectedItemValue.has(VIEWABLE_OBJECTS_MATERIAL_ID_FIELD));
+ llassert(selectedItemValue.get(VIEWABLE_OBJECTS_MATERIAL_ID_FIELD).isBinary());
+ const LLSD& materidIdLLSD = selectedItemValue.get(VIEWABLE_OBJECTS_MATERIAL_ID_FIELD);
+
+ materialIdsData.append(materidIdLLSD);
+ }
+ }
+
+ if (materialIdsData.size() <= 0)
+ {
+ LL_ERRS("debugMaterials") << "no material IDs to POST to region id " << regionId.asString()
+ << LL_ENDL;
+ }
+ else
+ {
+ std::string materialsString = zip_llsd(materialIdsData);
+ S32 materialsSize = materialsString.size();
+
+ if (materialsSize <= 0)
+ {
+ LL_ERRS("debugMaterials") << "cannot zip LLSD binary content" << LL_ENDL;
+ }
+ else
+ {
+ LLSD::Binary materialsBinary;
+ materialsBinary.resize(materialsSize);
+ memcpy(materialsBinary.data(), materialsString.data(), materialsSize);
+
+ LLSD postData = LLSD::emptyMap();
+ postData[MATERIALS_CAP_ZIP_FIELD] = materialsBinary;
+
+ LLHTTPClient::ResponderPtr materialsResponder = new MaterialsResponder("POST",
+ capURL, boost::bind(&MultiMaterialsResponder::onMaterialsResponse, mMultiMaterialsResponder.get(), _1, _2));
+ LLHTTPClient::post(capURL, postData, materialsResponder);
+ }
+ }
+ }
+ }
+ }
+}
+
+void LLFloaterDebugMaterials::parseQueryViewableObjects()
+{
+ llassert(mNextUnparsedQueryDataIndex >= 0);
+
+ if (mNextUnparsedQueryDataIndex >= 0)
+ {
+ LLScrollListCell::Params cellParams;
+ LLScrollListItem::Params rowParams;
+
+ S32 numViewerObjects = gObjectList.getNumObjects();
+ S32 viewerObjectIndex = mNextUnparsedQueryDataIndex;
+ for (S32 currentParseCount = 0;
+ (currentParseCount < 10) && (viewerObjectIndex < numViewerObjects);
+ ++currentParseCount, ++viewerObjectIndex)
+ {
+ const LLViewerObject *viewerObject = gObjectList.getObject(viewerObjectIndex);
+ if ((viewerObject != NULL) && !viewerObject->isDead())
+ {
+ U8 objectNumTEs = viewerObject->getNumTEs();
+
+ if (objectNumTEs > 0U)
+ {
+ const LLUUID& objectId = viewerObject->getID();
+ U32 objectLocalId = viewerObject->getLocalID();
+ const LLViewerRegion* objectRegion = viewerObject->getRegion();
+
+ for (U8 curTEIndex = 0U; curTEIndex < objectNumTEs; ++curTEIndex)
+ {
+ const LLTextureEntry* objectTE = viewerObject->getTE(curTEIndex);
+ llassert(objectTE != NULL);
+ const LLMaterialID& objectMaterialID = objectTE->getMaterialID();
+ if (!objectMaterialID.isNull())
+ {
+ cellParams.font = LLFontGL::getFontMonospace();
+
+ cellParams.column = "object_id";
+ cellParams.value = objectId.asString();
+ rowParams.columns.add(cellParams);
+
+ cellParams.font = LLFontGL::getFontSansSerif();
+
+ cellParams.column = "region";
+ cellParams.value = ((objectRegion == NULL) ? "<null>" : objectRegion->getName());
+ rowParams.columns.add(cellParams);
+
+ cellParams.column = "local_id";
+ cellParams.value = llformat("%d", objectLocalId);
+ rowParams.columns.add(cellParams);
+
+ cellParams.column = "face_index";
+ cellParams.value = llformat("%u", static_cast<unsigned int>(curTEIndex));
+ rowParams.columns.add(cellParams);
+ cellParams.font = LLFontGL::getFontMonospace();
+
+ std::string materialIDString = convertToPrintableMaterialID(objectMaterialID);
+ cellParams.column = "material_id";
+ cellParams.value = materialIDString;
+ rowParams.columns.add(cellParams);
+
+ LLSD rowValue = LLSD::emptyMap();
+ rowValue[VIEWABLE_OBJECTS_REGION_ID_FIELD] = objectRegion->getRegionID();
+ rowValue[VIEWABLE_OBJECTS_OBJECT_ID_FIELD] = objectId;
+ rowValue[VIEWABLE_OBJECTS_MATERIAL_ID_FIELD] = objectMaterialID.asLLSD();
+
+ rowParams.value = rowValue;
+
+ mViewableObjectsScrollList->addRow(rowParams);
+ }
+ }
+ }
+ }
+ }
+
+ if (viewerObjectIndex < numViewerObjects)
+ {
+ mNextUnparsedQueryDataIndex = viewerObjectIndex;
+ updateQueryParsingStatus();
+ }
+ else
+ {
+ clearUnparsedQueryData();
+ }
+ }
+}
+
+void LLFloaterDebugMaterials::parseGetResponse()
+{
+ llassert(mUnparsedGetData.isDefined());
+ llassert(mNextUnparsedGetDataIndex >= 0);
+
+ if (mUnparsedGetData.isDefined())
+ {
+ LLScrollListCell::Params cellParams;
+ LLScrollListItem::Params normalMapRowParams;
+ LLScrollListItem::Params specularMapRowParams;
+ LLScrollListItem::Params otherDataRowParams;
+
+ llassert(mUnparsedGetData.isArray());
+ LLSD::array_const_iterator materialIter = mUnparsedGetData.beginArray();
+ S32 materialIndex;
+
+ for (materialIndex = 0;
+ (materialIndex < mNextUnparsedGetDataIndex) && (materialIter != mUnparsedGetData.endArray());
+ ++materialIndex, ++materialIter)
+ {
+ }
+
+ for (S32 currentParseCount = 0;
+ (currentParseCount < 10) && (materialIter != mUnparsedGetData.endArray());
+ ++currentParseCount, ++materialIndex, ++materialIter)
+ {
+ const LLSD &material = *materialIter;
+ llassert(material.isMap());
+ llassert(material.has(MATERIALS_CAP_OBJECT_ID_FIELD));
+ llassert(material.get(MATERIALS_CAP_OBJECT_ID_FIELD).isBinary());
+ const LLSD &materialID = material.get(MATERIALS_CAP_OBJECT_ID_FIELD);
+ std::string materialIDString = convertToPrintableMaterialID(materialID);
+
+ llassert(material.has(MATERIALS_CAP_MATERIAL_FIELD));
+ const LLSD &materialData = material.get(MATERIALS_CAP_MATERIAL_FIELD);
+ llassert(materialData.isMap());
+
+ llassert(materialData.has(MATERIALS_CAP_NORMAL_MAP_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_NORMAL_MAP_FIELD).isUUID());
+ const LLUUID &normalMapID = materialData.get(MATERIALS_CAP_NORMAL_MAP_FIELD).asUUID();
+
+ llassert(materialData.has(MATERIALS_CAP_NORMAL_MAP_OFFSET_X_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_NORMAL_MAP_OFFSET_X_FIELD).isInteger());
+ S32 normalMapOffsetX = materialData.get(MATERIALS_CAP_NORMAL_MAP_OFFSET_X_FIELD).asInteger();
+
+ llassert(materialData.has(MATERIALS_CAP_NORMAL_MAP_OFFSET_Y_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_NORMAL_MAP_OFFSET_Y_FIELD).isInteger());
+ S32 normalMapOffsetY = materialData.get(MATERIALS_CAP_NORMAL_MAP_OFFSET_Y_FIELD).asInteger();
+
+ llassert(materialData.has(MATERIALS_CAP_NORMAL_MAP_REPEAT_X_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_NORMAL_MAP_REPEAT_X_FIELD).isInteger());
+ S32 normalMapRepeatX = materialData.get(MATERIALS_CAP_NORMAL_MAP_REPEAT_X_FIELD).asInteger();
+
+ llassert(materialData.has(MATERIALS_CAP_NORMAL_MAP_REPEAT_Y_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_NORMAL_MAP_REPEAT_Y_FIELD).isInteger());
+ S32 normalMapRepeatY = materialData.get(MATERIALS_CAP_NORMAL_MAP_REPEAT_Y_FIELD).asInteger();
+
+ llassert(materialData.has(MATERIALS_CAP_NORMAL_MAP_ROTATION_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_NORMAL_MAP_ROTATION_FIELD).isInteger());
+ S32 normalMapRotation = materialData.get(MATERIALS_CAP_NORMAL_MAP_ROTATION_FIELD).asInteger();
+
+ llassert(materialData.has(MATERIALS_CAP_SPECULAR_MAP_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_SPECULAR_MAP_FIELD).isUUID());
+ const LLUUID &specularMapID = materialData.get(MATERIALS_CAP_SPECULAR_MAP_FIELD).asUUID();
+
+ llassert(materialData.has(MATERIALS_CAP_SPECULAR_MAP_OFFSET_X_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_SPECULAR_MAP_OFFSET_X_FIELD).isInteger());
+ S32 specularMapOffsetX = materialData.get(MATERIALS_CAP_SPECULAR_MAP_OFFSET_X_FIELD).asInteger();
+
+ llassert(materialData.has(MATERIALS_CAP_SPECULAR_MAP_OFFSET_Y_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_SPECULAR_MAP_OFFSET_Y_FIELD).isInteger());
+ S32 specularMapOffsetY = materialData.get(MATERIALS_CAP_SPECULAR_MAP_OFFSET_Y_FIELD).asInteger();
+
+ llassert(materialData.has(MATERIALS_CAP_SPECULAR_MAP_REPEAT_X_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_SPECULAR_MAP_REPEAT_X_FIELD).isInteger());
+ S32 specularMapRepeatX = materialData.get(MATERIALS_CAP_SPECULAR_MAP_REPEAT_X_FIELD).asInteger();
+
+ llassert(materialData.has(MATERIALS_CAP_SPECULAR_MAP_REPEAT_Y_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_SPECULAR_MAP_REPEAT_Y_FIELD).isInteger());
+ S32 specularMapRepeatY = materialData.get(MATERIALS_CAP_SPECULAR_MAP_REPEAT_Y_FIELD).asInteger();
+
+ llassert(materialData.has(MATERIALS_CAP_SPECULAR_MAP_ROTATION_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_SPECULAR_MAP_ROTATION_FIELD).isInteger());
+ S32 specularMapRotation = materialData.get(MATERIALS_CAP_SPECULAR_MAP_ROTATION_FIELD).asInteger();
+
+ llassert(materialData.has(MATERIALS_CAP_SPECULAR_COLOR_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_SPECULAR_COLOR_FIELD).isArray());
+ LLColor4U specularColor;
+ specularColor.setValue(materialData.get(MATERIALS_CAP_SPECULAR_COLOR_FIELD));
+
+ llassert(materialData.has(MATERIALS_CAP_SPECULAR_EXP_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_SPECULAR_EXP_FIELD).isInteger());
+ S32 specularExp = materialData.get(MATERIALS_CAP_SPECULAR_EXP_FIELD).asInteger();
+
+ llassert(materialData.has(MATERIALS_CAP_ENV_INTENSITY_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_ENV_INTENSITY_FIELD).isInteger());
+ S32 envIntensity = materialData.get(MATERIALS_CAP_ENV_INTENSITY_FIELD).asInteger();
+
+ llassert(materialData.has(MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD).isInteger());
+ S32 alphaMaskCutoff = materialData.get(MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD).asInteger();
+
+ llassert(materialData.has(MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD).isInteger());
+ S32 diffuseAlphaMode = materialData.get(MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD).asInteger();
+
+ cellParams.font = LLFontGL::getFontMonospace();
+
+ cellParams.column = "id";
+ cellParams.value = materialIDString;
+ normalMapRowParams.columns.add(cellParams);
+ specularMapRowParams.columns.add(cellParams);
+ otherDataRowParams.columns.add(cellParams);
+
+ cellParams.column = "normal_map_list_map";
+ cellParams.value = normalMapID.asString();
+ normalMapRowParams.columns.add(cellParams);
+
+ cellParams.font = LLFontGL::getFontSansSerif();
+
+ cellParams.column = "normal_map_list_offset_x";
+ cellParams.value = llformat("%d", normalMapOffsetX);
+ normalMapRowParams.columns.add(cellParams);
+
+ cellParams.column = "normal_map_list_offset_y";
+ cellParams.value = llformat("%d", normalMapOffsetY);
+ normalMapRowParams.columns.add(cellParams);
+
+ cellParams.column = "normal_map_list_repeat_x";
+ cellParams.value = llformat("%d", normalMapRepeatX);
+ normalMapRowParams.columns.add(cellParams);
+
+ cellParams.column = "normal_map_list_repeat_y";
+ cellParams.value = llformat("%d", normalMapRepeatY);
+ normalMapRowParams.columns.add(cellParams);
+
+ cellParams.column = "normal_map_list_rotation";
+ cellParams.value = llformat("%d", normalMapRotation);
+ normalMapRowParams.columns.add(cellParams);
+
+ cellParams.font = LLFontGL::getFontMonospace();
+
+ cellParams.column = "specular_map_list_map";
+ cellParams.value = specularMapID.asString();
+ specularMapRowParams.columns.add(cellParams);
+
+ cellParams.font = LLFontGL::getFontSansSerif();
+
+ cellParams.column = "specular_map_list_offset_x";
+ cellParams.value = llformat("%d", specularMapOffsetX);
+ specularMapRowParams.columns.add(cellParams);
+
+ cellParams.column = "specular_map_list_offset_y";
+ cellParams.value = llformat("%d", specularMapOffsetY);
+ specularMapRowParams.columns.add(cellParams);
+
+ cellParams.column = "specular_map_list_repeat_x";
+ cellParams.value = llformat("%d", specularMapRepeatX);
+ specularMapRowParams.columns.add(cellParams);
+
+ cellParams.column = "specular_map_list_repeat_y";
+ cellParams.value = llformat("%d", specularMapRepeatY);
+ specularMapRowParams.columns.add(cellParams);
+
+ cellParams.column = "specular_map_list_rotation";
+ cellParams.value = llformat("%d", specularMapRotation);
+ specularMapRowParams.columns.add(cellParams);
+
+ cellParams.column = "specular_color";
+ cellParams.value = llformat("(%d, %d, %d, %d)", specularColor.mV[0],
+ specularColor.mV[1], specularColor.mV[2], specularColor.mV[3]);
+ otherDataRowParams.columns.add(cellParams);
+
+ cellParams.column = "specular_exponent";
+ cellParams.value = llformat("%d", specularExp);
+ otherDataRowParams.columns.add(cellParams);
+
+ cellParams.column = "env_intensity";
+ cellParams.value = llformat("%d", envIntensity);
+ otherDataRowParams.columns.add(cellParams);
+
+ cellParams.column = "alpha_mask_cutoff";
+ cellParams.value = llformat("%d", alphaMaskCutoff);
+ otherDataRowParams.columns.add(cellParams);
+
+ cellParams.column = "diffuse_alpha_mode";
+ cellParams.value = llformat("%d", diffuseAlphaMode);
+ otherDataRowParams.columns.add(cellParams);
+
+ normalMapRowParams.value = materialIDString;
+ specularMapRowParams.value = materialIDString;
+ otherDataRowParams.value = materialIDString;
+
+ mGetNormalMapScrollList->addRow(normalMapRowParams);
+ mGetSpecularMapScrollList->addRow(specularMapRowParams);
+ mGetOtherDataScrollList->addRow(otherDataRowParams);
+ }
+
+ if (materialIter != mUnparsedGetData.endArray())
+ {
+ mNextUnparsedGetDataIndex = materialIndex;
+ updateGetParsingStatus();
+ }
+ else
+ {
+ clearUnparsedGetData();
+ }
+ }
+}
+
+void LLFloaterDebugMaterials::parsePutResponse(const LLSD& pContent)
+{
+ clearPutResults();
+
+ LLScrollListCell::Params cellParams;
+ LLScrollListItem::Params rowParams;
+
+ llassert(pContent.isMap());
+ llassert(pContent.has(MATERIALS_CAP_ZIP_FIELD));
+ llassert(pContent.get(MATERIALS_CAP_ZIP_FIELD).isBinary());
+
+ LLSD::Binary responseBinary = pContent.get(MATERIALS_CAP_ZIP_FIELD).asBinary();
+ S32 responseSize = static_cast<S32>(responseBinary.size());
+ std::string responseString(reinterpret_cast<const char*>(responseBinary.data()), responseSize);
+
+ std::istringstream responseStream(responseString);
+
+ LLSD responseContent;
+ if (!unzip_llsd(responseContent, responseStream, responseSize))
+ {
+ LL_ERRS("debugMaterials") << "cannot unzip LLSD binary content" << LL_ENDL;
+ }
+ else
+ {
+ llassert(responseContent.isArray());
+ for (LLSD::array_const_iterator faceIter = responseContent.beginArray(); faceIter != responseContent.endArray();
+ ++faceIter)
+ {
+ const LLSD &face = *faceIter;
+ llassert(face.isMap());
+
+ llassert(face.has(MATERIALS_CAP_FACE_FIELD));
+ llassert(face.get(MATERIALS_CAP_FACE_FIELD).isInteger());
+ S32 faceId = face.get(MATERIALS_CAP_FACE_FIELD).asInteger();
+
+ llassert(face.has(MATERIALS_CAP_OBJECT_ID_FIELD));
+ llassert(face.get(MATERIALS_CAP_OBJECT_ID_FIELD).isInteger());
+ S32 objectId = face.get(MATERIALS_CAP_OBJECT_ID_FIELD).asInteger();
+
+ llassert(face.has(MATERIALS_CAP_MATERIAL_ID_FIELD));
+ llassert(face.get(MATERIALS_CAP_MATERIAL_ID_FIELD).isBinary());
+ std::string materialIDString = convertToPrintableMaterialID(face.get(MATERIALS_CAP_MATERIAL_ID_FIELD));
+
+ cellParams.font = LLFontGL::getFontMonospace();
+
+ cellParams.column = "material_id";
+ cellParams.value = materialIDString;
+ rowParams.columns.add(cellParams);
+
+ cellParams.font = LLFontGL::getFontSansSerif();
+
+ cellParams.column = "object_id";
+ cellParams.value = llformat("%d", objectId);
+ rowParams.columns.add(cellParams);
+
+ cellParams.column = "face_index";
+ cellParams.value = llformat("%d", faceId);
+ rowParams.columns.add(cellParams);
+
+ mPutScrollList->addRow(rowParams);
+ }
+ }
+}
+
+void LLFloaterDebugMaterials::parsePostResponse(const LLSD& pMultiContent)
+{
+ clearPostResults();
+
+ llassert(pMultiContent.isArray());
+ for (LLSD::array_const_iterator contentIter = pMultiContent.beginArray();
+ contentIter != pMultiContent.endArray(); ++contentIter)
+ {
+ const LLSD& content = *contentIter;
+
+ llassert(content.isMap());
+ llassert(content.has(MULTI_MATERIALS_STATUS_FIELD));
+ llassert(content.get(MULTI_MATERIALS_STATUS_FIELD).isBoolean());
+ if (content.get(MULTI_MATERIALS_STATUS_FIELD).asBoolean())
+ {
+ llassert(content.has(MULTI_MATERIALS_DATA_FIELD));
+ llassert(content.get(MULTI_MATERIALS_DATA_FIELD).isMap());
+ const LLSD& postData = content.get(MULTI_MATERIALS_DATA_FIELD);
+
+ llassert(postData.has(MATERIALS_CAP_ZIP_FIELD));
+ llassert(postData.get(MATERIALS_CAP_ZIP_FIELD).isBinary());
+
+ LLSD::Binary postDataBinary = postData.get(MATERIALS_CAP_ZIP_FIELD).asBinary();
+ S32 postDataSize = static_cast<S32>(postDataBinary.size());
+ std::string postDataString(reinterpret_cast<const char*>(postDataBinary.data()), postDataSize);
+
+ std::istringstream postDataStream(postDataString);
+
+ LLSD unzippedPostData;
+ if (!unzip_llsd(unzippedPostData, postDataStream, postDataSize))
+ {
+ LL_ERRS("debugMaterials") << "cannot unzip LLSD binary content" << LL_ENDL;
+ }
+
+ LLScrollListCell::Params cellParams;
+ LLScrollListItem::Params normalMapRowParams;
+ LLScrollListItem::Params specularMapRowParams;
+ LLScrollListItem::Params otherDataRowParams;
+
+ llassert(unzippedPostData.isArray());
+ for (LLSD::array_const_iterator materialIter = unzippedPostData.beginArray();
+ materialIter != unzippedPostData.endArray(); ++materialIter)
+ {
+ const LLSD &material = *materialIter;
+ llassert(material.isMap());
+ llassert(material.has(MATERIALS_CAP_OBJECT_ID_FIELD));
+ llassert(material.get(MATERIALS_CAP_OBJECT_ID_FIELD).isBinary());
+ const LLSD &materialID = material.get(MATERIALS_CAP_OBJECT_ID_FIELD);
+ std::string materialIDString = convertToPrintableMaterialID(materialID);
+
+ llassert(material.has(MATERIALS_CAP_MATERIAL_FIELD));
+ const LLSD &materialData = material.get(MATERIALS_CAP_MATERIAL_FIELD);
+ llassert(materialData.isMap());
+
+ llassert(materialData.has(MATERIALS_CAP_NORMAL_MAP_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_NORMAL_MAP_FIELD).isUUID());
+ const LLUUID &normalMapID = materialData.get(MATERIALS_CAP_NORMAL_MAP_FIELD).asUUID();
+
+ llassert(materialData.has(MATERIALS_CAP_NORMAL_MAP_OFFSET_X_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_NORMAL_MAP_OFFSET_X_FIELD).isInteger());
+ S32 normalMapOffsetX = materialData.get(MATERIALS_CAP_NORMAL_MAP_OFFSET_X_FIELD).asInteger();
+
+ llassert(materialData.has(MATERIALS_CAP_NORMAL_MAP_OFFSET_Y_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_NORMAL_MAP_OFFSET_Y_FIELD).isInteger());
+ S32 normalMapOffsetY = materialData.get(MATERIALS_CAP_NORMAL_MAP_OFFSET_Y_FIELD).asInteger();
+
+ llassert(materialData.has(MATERIALS_CAP_NORMAL_MAP_REPEAT_X_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_NORMAL_MAP_REPEAT_X_FIELD).isInteger());
+ S32 normalMapRepeatX = materialData.get(MATERIALS_CAP_NORMAL_MAP_REPEAT_X_FIELD).asInteger();
+
+ llassert(materialData.has(MATERIALS_CAP_NORMAL_MAP_REPEAT_Y_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_NORMAL_MAP_REPEAT_Y_FIELD).isInteger());
+ S32 normalMapRepeatY = materialData.get(MATERIALS_CAP_NORMAL_MAP_REPEAT_Y_FIELD).asInteger();
+
+ llassert(materialData.has(MATERIALS_CAP_NORMAL_MAP_ROTATION_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_NORMAL_MAP_ROTATION_FIELD).isInteger());
+ S32 normalMapRotation = materialData.get(MATERIALS_CAP_NORMAL_MAP_ROTATION_FIELD).asInteger();
+
+ llassert(materialData.has(MATERIALS_CAP_SPECULAR_MAP_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_SPECULAR_MAP_FIELD).isUUID());
+ const LLUUID &specularMapID = materialData.get(MATERIALS_CAP_SPECULAR_MAP_FIELD).asUUID();
+
+ llassert(materialData.has(MATERIALS_CAP_SPECULAR_MAP_OFFSET_X_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_SPECULAR_MAP_OFFSET_X_FIELD).isInteger());
+ S32 specularMapOffsetX = materialData.get(MATERIALS_CAP_SPECULAR_MAP_OFFSET_X_FIELD).asInteger();
+
+ llassert(materialData.has(MATERIALS_CAP_SPECULAR_MAP_OFFSET_Y_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_SPECULAR_MAP_OFFSET_Y_FIELD).isInteger());
+ S32 specularMapOffsetY = materialData.get(MATERIALS_CAP_SPECULAR_MAP_OFFSET_Y_FIELD).asInteger();
+
+ llassert(materialData.has(MATERIALS_CAP_SPECULAR_MAP_REPEAT_X_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_SPECULAR_MAP_REPEAT_X_FIELD).isInteger());
+ S32 specularMapRepeatX = materialData.get(MATERIALS_CAP_SPECULAR_MAP_REPEAT_X_FIELD).asInteger();
+
+ llassert(materialData.has(MATERIALS_CAP_SPECULAR_MAP_REPEAT_Y_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_SPECULAR_MAP_REPEAT_Y_FIELD).isInteger());
+ S32 specularMapRepeatY = materialData.get(MATERIALS_CAP_SPECULAR_MAP_REPEAT_Y_FIELD).asInteger();
+
+ llassert(materialData.has(MATERIALS_CAP_SPECULAR_MAP_ROTATION_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_SPECULAR_MAP_ROTATION_FIELD).isInteger());
+ S32 specularMapRotation = materialData.get(MATERIALS_CAP_SPECULAR_MAP_ROTATION_FIELD).asInteger();
+
+ llassert(materialData.has(MATERIALS_CAP_SPECULAR_COLOR_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_SPECULAR_COLOR_FIELD).isArray());
+ LLColor4U specularColor;
+ specularColor.setValue(materialData.get(MATERIALS_CAP_SPECULAR_COLOR_FIELD));
+
+ llassert(materialData.has(MATERIALS_CAP_SPECULAR_EXP_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_SPECULAR_EXP_FIELD).isInteger());
+ S32 specularExp = materialData.get(MATERIALS_CAP_SPECULAR_EXP_FIELD).asInteger();
+
+ llassert(materialData.has(MATERIALS_CAP_ENV_INTENSITY_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_ENV_INTENSITY_FIELD).isInteger());
+ S32 envIntensity = materialData.get(MATERIALS_CAP_ENV_INTENSITY_FIELD).asInteger();
+
+ llassert(materialData.has(MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD).isInteger());
+ S32 alphaMaskCutoff = materialData.get(MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD).asInteger();
+
+ llassert(materialData.has(MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD).isInteger());
+ S32 diffuseAlphaMode = materialData.get(MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD).asInteger();
+
+ cellParams.font = LLFontGL::getFontMonospace();
+
+ cellParams.column = "id";
+ cellParams.value = materialIDString;
+ normalMapRowParams.columns.add(cellParams);
+ specularMapRowParams.columns.add(cellParams);
+ otherDataRowParams.columns.add(cellParams);
+
+ cellParams.column = "normal_map_list_map";
+ cellParams.value = normalMapID.asString();
+ normalMapRowParams.columns.add(cellParams);
+
+ cellParams.font = LLFontGL::getFontSansSerif();
+
+ cellParams.column = "normal_map_list_offset_x";
+ cellParams.value = llformat("%d", normalMapOffsetX);
+ normalMapRowParams.columns.add(cellParams);
+
+ cellParams.column = "normal_map_list_offset_y";
+ cellParams.value = llformat("%d", normalMapOffsetY);
+ normalMapRowParams.columns.add(cellParams);
+
+ cellParams.column = "normal_map_list_repeat_x";
+ cellParams.value = llformat("%d", normalMapRepeatX);
+ normalMapRowParams.columns.add(cellParams);
+
+ cellParams.column = "normal_map_list_repeat_y";
+ cellParams.value = llformat("%d", normalMapRepeatY);
+ normalMapRowParams.columns.add(cellParams);
+
+ cellParams.column = "normal_map_list_rotation";
+ cellParams.value = llformat("%d", normalMapRotation);
+ normalMapRowParams.columns.add(cellParams);
+
+ cellParams.font = LLFontGL::getFontMonospace();
+
+ cellParams.column = "specular_map_list_map";
+ cellParams.value = specularMapID.asString();
+ specularMapRowParams.columns.add(cellParams);
+
+ cellParams.font = LLFontGL::getFontSansSerif();
+
+ cellParams.column = "specular_map_list_offset_x";
+ cellParams.value = llformat("%d", specularMapOffsetX);
+ specularMapRowParams.columns.add(cellParams);
+
+ cellParams.column = "specular_map_list_offset_y";
+ cellParams.value = llformat("%d", specularMapOffsetY);
+ specularMapRowParams.columns.add(cellParams);
+
+ cellParams.column = "specular_map_list_repeat_x";
+ cellParams.value = llformat("%d", specularMapRepeatX);
+ specularMapRowParams.columns.add(cellParams);
+
+ cellParams.column = "specular_map_list_repeat_y";
+ cellParams.value = llformat("%d", specularMapRepeatY);
+ specularMapRowParams.columns.add(cellParams);
+
+ cellParams.column = "specular_map_list_rotation";
+ cellParams.value = llformat("%d", specularMapRotation);
+ specularMapRowParams.columns.add(cellParams);
+
+ cellParams.column = "specular_color";
+ cellParams.value = llformat("(%d, %d, %d, %d)", specularColor.mV[0],
+ specularColor.mV[1], specularColor.mV[2], specularColor.mV[3]);
+ otherDataRowParams.columns.add(cellParams);
+
+ cellParams.column = "specular_exponent";
+ cellParams.value = llformat("%d", specularExp);
+ otherDataRowParams.columns.add(cellParams);
+
+ cellParams.column = "env_intensity";
+ cellParams.value = llformat("%d", envIntensity);
+ otherDataRowParams.columns.add(cellParams);
+
+ cellParams.column = "alpha_mask_cutoff";
+ cellParams.value = llformat("%d", alphaMaskCutoff);
+ otherDataRowParams.columns.add(cellParams);
+
+ cellParams.column = "diffuse_alpha_mode";
+ cellParams.value = llformat("%d", diffuseAlphaMode);
+ otherDataRowParams.columns.add(cellParams);
+
+ normalMapRowParams.value = materialIDString;
+ specularMapRowParams.value = materialIDString;
+ otherDataRowParams.value = materialIDString;
+
+ mPostNormalMapScrollList->addRow(normalMapRowParams);
+ mPostSpecularMapScrollList->addRow(specularMapRowParams);
+ mPostOtherDataScrollList->addRow(otherDataRowParams);
+ }
+ }
+ }
+}
+
+void LLFloaterDebugMaterials::setState(EState pState)
+{
+ mState = pState;
+ updateStatusMessage();
+ updateControls();
+}
+
+void LLFloaterDebugMaterials::resetObjectEditInputs()
+{
+ const LLSD zeroValue = static_cast<LLSD::Integer>(0);
+ const LLSD maxAlphaValue = static_cast<LLSD::Integer>(255);
+
+ mNormalMap->clear();
+ mNormalMapOffsetX->setValue(zeroValue);
+ mNormalMapOffsetY->setValue(zeroValue);
+ mNormalMapRepeatX->setValue(zeroValue);
+ mNormalMapRepeatY->setValue(zeroValue);
+ mNormalMapRotation->setValue(zeroValue);
+
+ mSpecularMap->clear();
+ mSpecularMapOffsetX->setValue(zeroValue);
+ mSpecularMapOffsetY->setValue(zeroValue);
+ mSpecularMapRepeatX->setValue(zeroValue);
+ mSpecularMapRepeatY->setValue(zeroValue);
+ mSpecularMapRotation->setValue(zeroValue);
+
+ mSpecularColor->set(mDefaultSpecularColor);
+ mSpecularColorAlpha->setValue(maxAlphaValue);
+ mSpecularExponent->setValue(zeroValue);
+ mEnvironmentExponent->setValue(zeroValue);
+ mAlphaMaskCutoff->setValue(zeroValue);
+ mDiffuseAlphaMode->setValue(zeroValue);
+}
+
+void LLFloaterDebugMaterials::clearGetResults()
+{
+ mGetNormalMapScrollList->deleteAllItems();
+ mGetSpecularMapScrollList->deleteAllItems();
+ mGetOtherDataScrollList->deleteAllItems();
+ clearUnparsedGetData();
+}
+
+void LLFloaterDebugMaterials::clearPutResults()
+{
+ mPutScrollList->deleteAllItems();
+}
+
+void LLFloaterDebugMaterials::clearPostResults()
+{
+ mPostNormalMapScrollList->deleteAllItems();
+ mPostSpecularMapScrollList->deleteAllItems();
+ mPostOtherDataScrollList->deleteAllItems();
+}
+
+void LLFloaterDebugMaterials::clearViewableObjectsResults()
+{
+ mViewableObjectsScrollList->deleteAllItems();
+ clearUnparsedQueryData();
+}
+
+void LLFloaterDebugMaterials::setUnparsedGetData(const LLSD& pGetData)
+{
+ llassert(pGetData.isMap());
+ llassert(pGetData.has(MATERIALS_CAP_ZIP_FIELD));
+ llassert(pGetData.get(MATERIALS_CAP_ZIP_FIELD).isBinary());
+
+ LLSD::Binary getDataBinary = pGetData.get(MATERIALS_CAP_ZIP_FIELD).asBinary();
+ S32 getDataSize = static_cast<S32>(getDataBinary.size());
+ std::string getDataString(reinterpret_cast<const char*>(getDataBinary.data()), getDataSize);
+
+ std::istringstream getDataStream(getDataString);
+
+ llassert(!mUnparsedGetData.isDefined());
+ if (!unzip_llsd(mUnparsedGetData, getDataStream, getDataSize))
+ {
+ LL_ERRS("debugMaterials") << "cannot unzip LLSD binary content" << LL_ENDL;
+ }
+ mNextUnparsedGetDataIndex = 0;
+
+ updateGetParsingStatus();
+}
+
+void LLFloaterDebugMaterials::clearUnparsedGetData()
+{
+ mUnparsedGetData.clear();
+ mNextUnparsedGetDataIndex = -1;
+
+ updateGetParsingStatus();
+}
+
+void LLFloaterDebugMaterials::updateGetParsingStatus()
+{
+ std::string parsingStatus;
+
+ if (mUnparsedGetData.isDefined())
+ {
+ LLLocale locale(LLStringUtil::getLocale());
+ std::string numProcessedString;
+ LLResMgr::getInstance()->getIntegerString(numProcessedString, mNextUnparsedGetDataIndex);
+
+ std::string numTotalString;
+ LLResMgr::getInstance()->getIntegerString(numTotalString, mUnparsedGetData.size());
+
+ LLStringUtil::format_map_t stringArgs;
+ stringArgs["[NUM_PROCESSED]"] = numProcessedString;
+ stringArgs["[NUM_TOTAL]"] = numTotalString;
+
+ parsingStatus = getString("loading_status_in_progress", stringArgs);
+ }
+ else
+ {
+ parsingStatus = getString("loading_status_done");
+ }
+
+ mParsingStatusText->setText(static_cast<const LLStringExplicit>(parsingStatus));
+}
+
+void LLFloaterDebugMaterials::setUnparsedQueryData()
+{
+ mNextUnparsedQueryDataIndex = 0;
+
+ updateQueryParsingStatus();
+}
+
+void LLFloaterDebugMaterials::clearUnparsedQueryData()
+{
+ mNextUnparsedQueryDataIndex = -1;
+
+ updateQueryParsingStatus();
+}
+
+void LLFloaterDebugMaterials::updateQueryParsingStatus()
+{
+ std::string queryStatus;
+
+ if (mNextUnparsedQueryDataIndex >= 0)
+ {
+ LLLocale locale(LLStringUtil::getLocale());
+ std::string numProcessedString;
+ LLResMgr::getInstance()->getIntegerString(numProcessedString, mNextUnparsedQueryDataIndex);
+
+ std::string numTotalString;
+ LLResMgr::getInstance()->getIntegerString(numTotalString, gObjectList.getNumObjects());
+
+ LLStringUtil::format_map_t stringArgs;
+ stringArgs["[NUM_PROCESSED]"] = numProcessedString;
+ stringArgs["[NUM_TOTAL]"] = numTotalString;
+
+ queryStatus = getString("querying_status_in_progress", stringArgs);
+ }
+ else
+ {
+ queryStatus = getString("querying_status_done");
+ }
+
+ mQueryStatusText->setText(static_cast<const LLStringExplicit>(queryStatus));
+}
+
+void LLFloaterDebugMaterials::updateStatusMessage()
+{
+ std::string statusText;
+ LLStyle::Params styleParams;
+
+ switch (getState())
+ {
+ case kNoRegion :
+ statusText = getString("status_no_region");
+ styleParams.color = mErrorColor;
+ break;
+ case kCapabilitiesLoading :
+ statusText = getString("status_capabilities_loading");
+ styleParams.color = mWarningColor;
+ break;
+ case kReady :
+ statusText = getString("status_ready");
+ break;
+ case kRequestStarted :
+ statusText = getString("status_request_started");
+ styleParams.color = mWarningColor;
+ break;
+ case kRequestCompleted :
+ statusText = getString("status_request_completed");
+ break;
+ case kNotEnabled :
+ statusText = getString("status_not_enabled");
+ styleParams.color = mErrorColor;
+ break;
+ case kError :
+ statusText = getString("status_error");
+ styleParams.color = mErrorColor;
+ break;
+ default :
+ statusText = getString("status_ready");
+ llassert(0);
+ break;
+ }
+
+ mStatusText->setText((LLStringExplicit)statusText, styleParams);
+}
+
+void LLFloaterDebugMaterials::updateControls()
+{
+ LLObjectSelectionHandle selectionHandle = LLSelectMgr::getInstance()->getEditSelection();
+ bool isPutEnabled = (selectionHandle->valid_begin() != selectionHandle->valid_end());
+ bool isPostEnabled = (mViewableObjectsScrollList->getNumSelected() > 0);
+
+ switch (getState())
+ {
+ case kNoRegion :
+ case kCapabilitiesLoading :
+ case kRequestStarted :
+ case kNotEnabled :
+ mGetButton->setEnabled(FALSE);
+ mPutSetButton->setEnabled(FALSE);
+ mPutClearButton->setEnabled(FALSE);
+ mPostButton->setEnabled(FALSE);
+ break;
+ case kReady :
+ case kRequestCompleted :
+ case kError :
+ mGetButton->setEnabled(TRUE);
+ mPutSetButton->setEnabled(isPutEnabled);
+ mPutClearButton->setEnabled(isPutEnabled);
+ mPostButton->setEnabled(isPostEnabled);
+ break;
+ default :
+ mGetButton->setEnabled(TRUE);
+ mPutSetButton->setEnabled(isPutEnabled);
+ mPutClearButton->setEnabled(isPutEnabled);
+ mPostButton->setEnabled(isPostEnabled);
+ llassert(0);
+ break;
+ }
+}
+
+std::string LLFloaterDebugMaterials::convertToPrintableMaterialID(const LLSD& pBinaryHash) const
+{
+ llassert(pBinaryHash.isBinary());
+ const LLSD::Binary &materialIDValue = pBinaryHash.asBinary();
+ unsigned int valueSize = materialIDValue.size();
+
+ llassert(valueSize == 16);
+ std::string materialID(reinterpret_cast<const char *>(&materialIDValue[0]), valueSize);
+ std::string materialIDString;
+ for (unsigned int i = 0U; i < (valueSize / 4); ++i)
+ {
+ if (i != 0U)
+ {
+ materialIDString += "-";
+ }
+ const U32 *value = reinterpret_cast<const U32*>(&materialID.c_str()[i * 4]);
+ materialIDString += llformat("%08x", *value);
+ }
+ return materialIDString;
+}
+
+std::string LLFloaterDebugMaterials::convertToPrintableMaterialID(const LLMaterialID& pMaterialID) const
+{
+ std::string materialID(reinterpret_cast<const char *>(pMaterialID.get()), 16);
+ std::string materialIDString;
+ for (unsigned int i = 0U; i < 4; ++i)
+ {
+ if (i != 0U)
+ {
+ materialIDString += "-";
+ }
+ const U32 *value = reinterpret_cast<const U32*>(&materialID.c_str()[i * 4]);
+ materialIDString += llformat("%08x", *value);
+ }
+ return materialIDString;
+}
+
+S32 LLFloaterDebugMaterials::getNormalMapOffsetX() const
+{
+ return getLineEditorValue(mNormalMapOffsetX);
+}
+
+S32 LLFloaterDebugMaterials::getNormalMapOffsetY() const
+{
+ return getLineEditorValue(mNormalMapOffsetY);
+}
+
+S32 LLFloaterDebugMaterials::getNormalMapRepeatX() const
+{
+ return getLineEditorValue(mNormalMapRepeatX);
+}
+
+S32 LLFloaterDebugMaterials::getNormalMapRepeatY() const
+{
+ return getLineEditorValue(mNormalMapRepeatY);
+}
+
+S32 LLFloaterDebugMaterials::getNormalMapRotation() const
+{
+ return getLineEditorValue(mNormalMapRotation);
+}
+
+S32 LLFloaterDebugMaterials::getSpecularMapOffsetX() const
+{
+ return getLineEditorValue(mSpecularMapOffsetX);
+}
+
+S32 LLFloaterDebugMaterials::getSpecularMapOffsetY() const
+{
+ return getLineEditorValue(mSpecularMapOffsetY);
+}
+
+S32 LLFloaterDebugMaterials::getSpecularMapRepeatX() const
+{
+ return getLineEditorValue(mSpecularMapRepeatX);
+}
+
+S32 LLFloaterDebugMaterials::getSpecularMapRepeatY() const
+{
+ return getLineEditorValue(mSpecularMapRepeatY);
+}
+
+S32 LLFloaterDebugMaterials::getSpecularMapRotation() const
+{
+ return getLineEditorValue(mSpecularMapRotation);
+}
+
+LLColor4U LLFloaterDebugMaterials::getSpecularColor() const
+{
+ const LLColor4& specularColor = mSpecularColor->get();
+ LLColor4U specularColor4U = specularColor;
+
+ specularColor4U.setAlpha(static_cast<U8>(llclamp(llround(mSpecularColorAlpha->get()), 0, 255)));
+
+ return specularColor4U;
+}
+
+S32 LLFloaterDebugMaterials::getSpecularExponent() const
+{
+ return getLineEditorValue(mSpecularExponent);
+}
+
+S32 LLFloaterDebugMaterials::getEnvironmentExponent() const
+{
+ return getLineEditorValue(mEnvironmentExponent);
+}
+
+S32 LLFloaterDebugMaterials::getAlphMaskCutoff() const
+{
+ return getLineEditorValue(mAlphaMaskCutoff);
+}
+
+S32 LLFloaterDebugMaterials::getDiffuseAlphaMode() const
+{
+ return getLineEditorValue(mDiffuseAlphaMode);
+}
+
+S32 LLFloaterDebugMaterials::getLineEditorValue(const LLLineEditor *pLineEditor) const
+{
+ S32 value = 0;
+
+ LLStringUtil::convertToS32(pLineEditor->getText(), value);
+
+ return value;
+}
+
+MaterialsResponder::MaterialsResponder(const std::string& pMethod, const std::string& pCapabilityURL, CallbackFunction pCallback)
+ : LLHTTPClient::Responder(),
+ mMethod(pMethod),
+ mCapabilityURL(pCapabilityURL),
+ mCallback(pCallback)
+{
+}
+
+MaterialsResponder::~MaterialsResponder()
+{
+}
+
+void MaterialsResponder::result(const LLSD& pContent)
+{
+ mCallback(true, pContent);
+}
+
+void MaterialsResponder::error(U32 pStatus, const std::string& pReason)
+{
+ LL_WARNS("debugMaterials") << "--------------------------------------------------------------------------" << LL_ENDL;
+ LL_WARNS("debugMaterials") << mMethod << " Error[" << pStatus << "] cannot access cap '" << MATERIALS_CAPABILITY_NAME
+ << "' with url '" << mCapabilityURL << "' because " << pReason << LL_ENDL;
+ LL_WARNS("debugMaterials") << "--------------------------------------------------------------------------" << LL_ENDL;
+
+ LLSD emptyResult;
+ mCallback(false, emptyResult);
+}
+
+MultiMaterialsResponder::MultiMaterialsResponder(CallbackFunction pCallback, unsigned int pNumRequests)
+ : mCallback(pCallback),
+ mNumRequests(pNumRequests),
+ mRequestStatus(true),
+ mContent(LLSD::emptyArray()),
+ mMutex(NULL)
+{
+ mMutex = new LLMutex(NULL);
+ llassert(mMutex);
+}
+
+MultiMaterialsResponder::~MultiMaterialsResponder()
+{
+ llassert(mMutex);
+ if (mMutex)
+ {
+ delete mMutex;
+ }
+}
+
+void MultiMaterialsResponder::onMaterialsResponse(bool pRequestStatus, const LLSD& pContent)
+{
+ LLSD result = LLSD::emptyMap();
+
+ result[MULTI_MATERIALS_STATUS_FIELD] = static_cast<LLSD::Boolean>(pRequestStatus);
+ result[MULTI_MATERIALS_DATA_FIELD] = pContent;
+
+ if (appendRequestResults(pRequestStatus, result))
+ {
+ fireResponse();
+ }
+}
+
+bool MultiMaterialsResponder::appendRequestResults(bool pRequestStatus, const LLSD& pResults)
+{
+ llassert(mMutex);
+ LLMutexLock mutexLock(mMutex);
+
+ mRequestStatus = mRequestStatus && pRequestStatus;
+ mContent.append(pResults);
+ llassert(mNumRequests > 0U);
+ return (--mNumRequests == 0U);
+}
+
+void MultiMaterialsResponder::fireResponse()
+{
+ mCallback(mRequestStatus, mContent);
+}
diff --git a/indra/newview/llfloaterdebugmaterials.h b/indra/newview/llfloaterdebugmaterials.h
new file mode 100644
index 0000000000..565e440187
--- /dev/null
+++ b/indra/newview/llfloaterdebugmaterials.h
@@ -0,0 +1,216 @@
+/**
+* @file llfloaterdebugmaterials.h
+* @brief Header file for llfloaterdebugmaterials
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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_LLFLOATERDEBUGMATERIALS_H
+#define LL_LLFLOATERDEBUGMATERIALS_H
+
+#include <string>
+
+#include <boost/shared_ptr.hpp>
+#include <boost/signals2.hpp>
+
+#include "llfloater.h"
+#include "lluuid.h"
+#include "v4color.h"
+
+class LLButton;
+class LLColorSwatchCtrl;
+class LLColor4U;
+class LLLineEditor;
+class LLMaterialID;
+class LLScrollListCtrl;
+class LLSD;
+class LLSpinCtrl;
+class LLTextBase;
+class LLTextureCtrl;
+class LLUICtrl;
+class MultiMaterialsResponder;
+
+typedef boost::shared_ptr<MultiMaterialsResponder> MultiMaterialsResponderPtr;
+
+class LLFloaterDebugMaterials : public LLFloater
+{
+public:
+ virtual BOOL postBuild();
+
+ virtual void onOpen(const LLSD& pKey);
+ virtual void onClose(bool pIsAppQuitting);
+
+ virtual void draw();
+
+protected:
+
+private:
+ friend class LLFloaterReg;
+
+ typedef enum {
+ kNoRegion,
+ kCapabilitiesLoading,
+ kReady,
+ kRequestStarted,
+ kRequestCompleted,
+ kNotEnabled,
+ kError
+ } EState;
+
+ LLFloaterDebugMaterials(const LLSD& pParams);
+ virtual ~LLFloaterDebugMaterials();
+
+ void onGetClicked();
+ void onValueEntered(LLUICtrl* pUICtrl);
+ void onPutSetClicked();
+ void onPutClearClicked();
+ void onResetPutValuesClicked();
+ void onQueryVisibleObjectsClicked();
+ void onPostClicked();
+ void onRegionCross();
+ void onInWorldSelectionChange();
+ void onGetScrollListSelectionChange(LLUICtrl* pUICtrl);
+ void onPostScrollListSelectionChange(LLUICtrl* pUICtrl);
+ void onViewableObjectsScrollListSelectionChange();
+ void onDeferredCheckRegionMaterialStatus(LLUUID regionId);
+ void onDeferredRequestGetMaterials(LLUUID regionId);
+ void onDeferredRequestPutMaterials(LLUUID regionId, bool pIsDoSet);
+ void onGetResponse(bool pRequestStatus, const LLSD& pContent);
+ void onPutResponse(bool pRequestStatus, const LLSD& pContent);
+ void onPostResponse(bool pRequestStatus, const LLSD& pContent);
+
+ void checkRegionMaterialStatus();
+ void checkRegionMaterialStatus(const LLUUID& regionId);
+
+ void requestGetMaterials();
+ void requestGetMaterials(const LLUUID& regionId);
+
+ void requestPutMaterials(bool pIsDoSet);
+ void requestPutMaterials(const LLUUID& regionId, bool pIsDoSet);
+
+ void requestPostMaterials();
+
+ void parseGetResponse();
+ void parsePutResponse(const LLSD& pContent);
+ void parseQueryViewableObjects();
+ void parsePostResponse(const LLSD& pMultiContent);
+
+ void setState(EState pState);
+ inline EState getState() const;
+
+ void resetObjectEditInputs();
+ void clearGetResults();
+ void clearPutResults();
+ void clearPostResults();
+ void clearViewableObjectsResults();
+
+ void setUnparsedGetData(const LLSD& pGetData);
+ void clearUnparsedGetData();
+ void updateGetParsingStatus();
+
+ void setUnparsedQueryData();
+ void clearUnparsedQueryData();
+ void updateQueryParsingStatus();
+
+ void updateStatusMessage();
+ void updateControls();
+ std::string convertToPrintableMaterialID(const LLSD& pBinaryHash) const;
+ std::string convertToPrintableMaterialID(const LLMaterialID& pMaterialID) const;
+
+ S32 getNormalMapOffsetX() const;
+ S32 getNormalMapOffsetY() const;
+ S32 getNormalMapRepeatX() const;
+ S32 getNormalMapRepeatY() const;
+ S32 getNormalMapRotation() const;
+
+ S32 getSpecularMapOffsetX() const;
+ S32 getSpecularMapOffsetY() const;
+ S32 getSpecularMapRepeatX() const;
+ S32 getSpecularMapRepeatY() const;
+ S32 getSpecularMapRotation() const;
+
+ LLColor4U getSpecularColor() const;
+ S32 getSpecularExponent() const;
+ S32 getEnvironmentExponent() const;
+ S32 getAlphMaskCutoff() const;
+ S32 getDiffuseAlphaMode() const;
+ S32 getLineEditorValue(const LLLineEditor *pLineEditor) const;
+
+ LLTextBase* mStatusText;
+ LLButton* mGetButton;
+ LLTextBase* mParsingStatusText;
+ LLScrollListCtrl* mGetNormalMapScrollList;
+ LLScrollListCtrl* mGetSpecularMapScrollList;
+ LLScrollListCtrl* mGetOtherDataScrollList;
+ LLTextureCtrl* mNormalMap;
+ LLLineEditor* mNormalMapOffsetX;
+ LLLineEditor* mNormalMapOffsetY;
+ LLLineEditor* mNormalMapRepeatX;
+ LLLineEditor* mNormalMapRepeatY;
+ LLLineEditor* mNormalMapRotation;
+ LLTextureCtrl* mSpecularMap;
+ LLLineEditor* mSpecularMapOffsetX;
+ LLLineEditor* mSpecularMapOffsetY;
+ LLLineEditor* mSpecularMapRepeatX;
+ LLLineEditor* mSpecularMapRepeatY;
+ LLLineEditor* mSpecularMapRotation;
+ LLColorSwatchCtrl* mSpecularColor;
+ LLSpinCtrl* mSpecularColorAlpha;
+ LLLineEditor* mSpecularExponent;
+ LLLineEditor* mEnvironmentExponent;
+ LLLineEditor* mAlphaMaskCutoff;
+ LLLineEditor* mDiffuseAlphaMode;
+ LLButton* mPutSetButton;
+ LLButton* mPutClearButton;
+ LLScrollListCtrl* mPutScrollList;
+ LLButton* mQueryViewableObjectsButton;
+ LLTextBase* mQueryStatusText;
+ LLScrollListCtrl* mViewableObjectsScrollList;
+ LLButton* mPostButton;
+ LLScrollListCtrl* mPostNormalMapScrollList;
+ LLScrollListCtrl* mPostSpecularMapScrollList;
+ LLScrollListCtrl* mPostOtherDataScrollList;
+
+ LLColor4 mDefaultSpecularColor;
+
+ EState mState;
+ LLColor4 mWarningColor;
+ LLColor4 mErrorColor;
+
+ boost::signals2::connection mRegionCrossConnection;
+ boost::signals2::connection mTeleportFailedConnection;
+ boost::signals2::connection mSelectionUpdateConnection;
+
+ LLSD mUnparsedGetData;
+ S32 mNextUnparsedGetDataIndex;
+
+ S32 mNextUnparsedQueryDataIndex;
+ MultiMaterialsResponderPtr mMultiMaterialsResponder;
+};
+
+
+LLFloaterDebugMaterials::EState LLFloaterDebugMaterials::getState() const
+{
+ return mState;
+}
+
+#endif // LL_LLFLOATERDEBUGMATERIALS_H
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 1f7cf0cdd4..b630b5bbe6 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -50,6 +50,7 @@
#include "llfloaterbump.h"
#include "llfloaterbvhpreview.h"
#include "llfloatercamera.h"
+#include "llfloaterdebugmaterials.h"
#include "llfloaterdeleteenvpreset.h"
#include "llfloaterdisplayname.h"
#include "llfloatereditdaycycle.h"
@@ -255,6 +256,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("pathfinding_characters", "floater_pathfinding_characters.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPathfindingCharacters>);
LLFloaterReg::add("pathfinding_linksets", "floater_pathfinding_linksets.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPathfindingLinksets>);
LLFloaterReg::add("pathfinding_console", "floater_pathfinding_console.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPathfindingConsole>);
+ LLFloaterReg::add("floater_debug_materials", "floater_debug_materials.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDebugMaterials>);
LLFloaterReg::add("people", "floater_people.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
LLFloaterReg::add("places", "floater_places.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreference>);
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index b2bd547811..347d82d492 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -41,6 +41,7 @@
#include "llframetimer.h"
#include "llinventory.h"
#include "llinventorydefines.h"
+#include "llmaterialid.h"
#include "llmaterialtable.h"
#include "llmutelist.h"
#include "llnamevalue.h"
@@ -4247,6 +4248,26 @@ S32 LLViewerObject::setTEGlow(const U8 te, const F32 glow)
return retval;
}
+S32 LLViewerObject::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID)
+{
+ S32 retval = 0;
+ const LLTextureEntry *tep = getTE(te);
+ if (!tep)
+ {
+ llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
+ }
+ else if (pMaterialID != tep->getMaterialID())
+ {
+ retval = LLPrimitive::setTEMaterialID(te, pMaterialID);
+ setChanged(TEXTURE);
+ if (mDrawable.notNull() && retval)
+ {
+ gPipeline.markTextured(mDrawable);
+ }
+ }
+ return retval;
+}
+
S32 LLViewerObject::setTEScale(const U8 te, const F32 s, const F32 t)
{
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 1fb30db8f2..255d0cd080 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -56,6 +56,7 @@ class LLDrawable;
class LLHost;
class LLHUDText;
class LLWorld;
+class LLMaterialID;
class LLNameValue;
class LLNetMap;
class LLMessageSystem;
@@ -88,18 +89,6 @@ typedef void (*inventory_callback)(LLViewerObject*,
S32 serial_num,
void*);
-// for exporting textured materials from SL
-struct LLMaterialExportInfo
-{
-public:
- LLMaterialExportInfo(S32 mat_index, S32 texture_index, LLColor4 color) :
- mMaterialIndex(mat_index), mTextureIndex(texture_index), mColor(color) {};
-
- S32 mMaterialIndex;
- S32 mTextureIndex;
- LLColor4 mColor;
-};
-
struct PotentialReturnableObject
{
LLBBox box;
@@ -320,6 +309,7 @@ public:
/*virtual*/ S32 setTEFullbright(const U8 te, const U8 fullbright );
/*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags );
/*virtual*/ S32 setTEGlow(const U8 te, const F32 glow);
+ /*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID);
/*virtual*/ BOOL setMaterial(const U8 material);
virtual void setTEImage(const U8 te, LLViewerTexture *imagep); // Not derived from LLPrimitive
virtual void changeTEImage(S32 index, LLViewerTexture* new_image) ;
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index b607afbd9d..7c4cce2439 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1557,6 +1557,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("ProductInfoRequest");
capabilityNames.append("ProvisionVoiceAccountRequest");
capabilityNames.append("RemoteParcelRequest");
+ capabilityNames.append("RenderMaterials");
capabilityNames.append("RequestTextureDownload");
capabilityNames.append("ResourceCostSelected");
capabilityNames.append("RetrieveNavMeshSrc");
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 4b0e0598f6..43de7450c8 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -826,12 +826,14 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
shaders.push_back( make_pair( "objects/indexedTextureV.glsl", 1 ) );
}
shaders.push_back( make_pair( "objects/nonindexedTextureV.glsl", 1 ) );
-
+
+ boost::unordered_map<std::string, std::string> attribs;
+
// We no longer have to bind the shaders to global glhandles, they are automatically added to a map now.
for (U32 i = 0; i < shaders.size(); i++)
{
// Note usage of GL_VERTEX_SHADER_ARB
- if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER_ARB) == 0)
+ if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER_ARB, attribs) == 0)
{
return FALSE;
}
@@ -879,11 +881,11 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightShinyF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightShinyWaterF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightShinyWaterF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
-
+
for (U32 i = 0; i < shaders.size(); i++)
{
// Note usage of GL_FRAGMENT_SHADER_ARB
- if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER_ARB, index_channels[i]) == 0)
+ if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER_ARB, attribs, index_channels[i]) == 0)
{
return FALSE;
}
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 5d1c335078..50ba7e47a4 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -36,6 +36,7 @@
#include "lldir.h"
#include "llflexibleobject.h"
#include "llfloatertools.h"
+#include "llmaterialid.h"
#include "llmaterialtable.h"
#include "llprimitive.h"
#include "llvolume.h"
@@ -1976,6 +1977,17 @@ S32 LLVOVolume::setTEGlow(const U8 te, const F32 glow)
return res;
}
+S32 LLVOVolume::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID)
+{
+ S32 res = LLViewerObject::setTEMaterialID(te, pMaterialID);
+ if (res)
+ {
+ gPipeline.markTextured(mDrawable);
+ mFaceMappingChanged = TRUE;
+ }
+ return res;
+}
+
S32 LLVOVolume::setTEScale(const U8 te, const F32 s, const F32 t)
{
S32 res = LLViewerObject::setTEScale(te, s, t);
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 5482c80f2b..ff6dca9737 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -37,6 +37,7 @@
class LLViewerTextureAnim;
class LLDrawPool;
+class LLMaterialID;
class LLSelectNode;
class LLObjectMediaDataClient;
class LLObjectMediaNavigateClient;
@@ -185,6 +186,7 @@ public:
/*virtual*/ S32 setTEBumpShinyFullbright(const U8 te, const U8 bump);
/*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags);
/*virtual*/ S32 setTEGlow(const U8 te, const F32 glow);
+ /*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID);
/*virtual*/ S32 setTEScale(const U8 te, const F32 s, const F32 t);
/*virtual*/ S32 setTEScaleS(const U8 te, const F32 s);
/*virtual*/ S32 setTEScaleT(const U8 te, const F32 t);
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index ea2dc60b07..71d4cefdb3 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -397,7 +397,7 @@ void validate_framebuffer_object();
bool addDeferredAttachments(LLRenderTarget& target)
{
return target.addColorAttachment(GL_RGBA) && //specular
- target.addColorAttachment(GL_RGBA); //normal+z
+ target.addColorAttachment(GL_RGB10_A2); //normal+z
}
LLPipeline::LLPipeline() :
@@ -865,7 +865,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
if (!mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
if (!mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
if (!addDeferredAttachments(mDeferredScreen)) return false;
-
+
if (!mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
if (samples > 0)
{
@@ -1208,6 +1208,11 @@ void LLPipeline::createGLBuffers()
gBumpImageList.restoreGL();
}
+F32 lerpf(F32 a, F32 b, F32 w)
+{
+ return a + w * (b - a);
+}
+
void LLPipeline::createLUTBuffers()
{
if (sRenderDeferred)
@@ -1216,45 +1221,40 @@ void LLPipeline::createLUTBuffers()
{
U32 lightResX = gSavedSettings.getU32("RenderSpecularResX");
U32 lightResY = gSavedSettings.getU32("RenderSpecularResY");
- U8* ls = new U8[lightResX*lightResY];
- F32 specExp = gSavedSettings.getF32("RenderSpecularExponent");
- // Calculate the (normalized) Blinn-Phong specular lookup texture.
+ F32* ls = new F32[lightResX*lightResY];
+ //F32 specExp = gSavedSettings.getF32("RenderSpecularExponent"); // Note: only use this when creating new specular lighting functions.
+ // Calculate the (normalized) Gaussian specular lookup texture. (with a few tweaks)
for (U32 y = 0; y < lightResY; ++y)
{
for (U32 x = 0; x < lightResX; ++x)
{
ls[y*lightResX+x] = 0;
F32 sa = (F32) x/(lightResX-1);
- F32 spec = (F32) y/(lightResY-1);
- F32 n = spec * spec * specExp;
+ F32 spec = (F32) y/(lightResY);
+ F32 n = spec;
- // Nothing special here. Just your typical blinn-phong term.
- spec = powf(sa, n);
+ float angleNormalHalf = acosf(sa);
+ float exponent = angleNormalHalf / ((1 - n));
+ exponent = -(exponent * exponent);
+ spec = expf(exponent);
// Apply our normalization function.
- // Note: This is the full equation that applies the full normalization curve, not an approximation.
- // This is fine, given we only need to create our LUT once per buffer initialization.
- // The only trade off is we have a really low dynamic range.
- // This means we have to account for things not being able to exceed 0 to 1 in our shaders.
- spec *= (((n + 2) * (n + 4)) / (8 * F_PI * (powf(2, -n/2) + n)));
+ // This is based around the phong normalization function, trading n+2 for n+1 instead.
+ // Since we're using a gaussian model here, we actually don't really need as large of an exponent as blinn-phong shading.
+ // Instead, we assume that the correct exponent is 8 here.
+ // This was achieved through much tweaking to find a decent "middleground" with our specular highlights with the gaussian term.
+ // Bigger highlights don't look too soft, smaller highlights don't look too bright, and everything in the middle seems to have a well maintained highlight curvature.
+ // There isn't really much theory behind this one. This was done purely to produce a nice and mostly customizable BRDF.
- // Always sample at a 1.0/2.2 curve.
- // This "Gamma corrects" our specular term, boosting our lower exponent reflections.
- spec = powf(spec, 1.f/2.2f);
+ spec = lerpf(spec, spec * (n * 8 + 1) / 4.5, n);
- // Easy fix for our dynamic range problem: divide by 6 here, multiply by 6 in our shaders.
- // This allows for our specular term to exceed a value of 1 in our shaders.
- // This is something that can be important for energy conserving specular models where higher exponents can result in highlights that exceed a range of 0 to 1.
- // Technically, we could just use an R16F texture, but driver support for R16F textures can be somewhat spotty at times.
- // This works remarkably well for higher specular exponents, though banding can sometimes be seen on lower exponents.
- // Combined with a bit of noise and trilinear filtering, the banding is hardly noticable.
- ls[y*lightResX+x] = (U8)(llclamp(spec * (1.f / 6), 0.f, 1.f) * 255);
+ ls[y*lightResX+x] = spec;
}
}
- LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_R8, 1, &mLightFunc);
+ LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_R16F, 1, &mLightFunc);
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc);
- LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_R8, lightResX, lightResY, GL_RED, GL_UNSIGNED_BYTE, ls, false);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_R16F, lightResX, lightResY, GL_RED, GL_FLOAT, ls, false);
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR);
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index 9bf2922033..48a9430fdc 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -645,6 +645,15 @@
name="PathfindingGoodColor"
reference="LtGreen" />
<color
+ name="MaterialErrorColor"
+ reference="LtRed" />
+ <color
+ name="MaterialWarningColor"
+ reference="DrYellow" />
+ <color
+ name="MaterialGoodColor"
+ reference="LtGreen" />
+ <color
name="PathfindingDefaultBeaconColor"
reference="Red_80" />
<color
diff --git a/indra/newview/skins/default/xui/en/floater_debug_materials.xml b/indra/newview/skins/default/xui/en/floater_debug_materials.xml
new file mode 100644
index 0000000000..b7624d2b1e
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_debug_materials.xml
@@ -0,0 +1,1097 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ positioning="cascading"
+ can_tear_off="false"
+ can_resize="true"
+ height="746"
+ width="1040"
+ min_height="750"
+ min_width="1040"
+ layout="topleft"
+ name="floater_debug_materials"
+ reuse_instance="true"
+ save_rect="false"
+ single_instance="true"
+ title="Debug materials">
+ <floater.string name="status_no_region">No current region available.</floater.string>
+ <floater.string name="status_capabilities_loading">Region capabilities are loading.</floater.string>
+ <floater.string name="status_ready">Materials are enabled for this region.</floater.string>
+ <floater.string name="status_request_started">Request sent.</floater.string>
+ <floater.string name="status_request_completed">Request received.</floater.string>
+ <floater.string name="status_not_enabled">Materials are not enabled for this region.</floater.string>
+ <floater.string name="status_error">An error occurred during the request.</floater.string>
+ <floater.string name="loading_status_in_progress">Processing [NUM_PROCESSED] out of [NUM_TOTAL]</floater.string>
+ <floater.string name="loading_status_done">Complete</floater.string>
+ <floater.string name="querying_status_in_progress">Processing [NUM_PROCESSED] out of [NUM_TOTAL]</floater.string>
+ <floater.string name="querying_status_done">Complete</floater.string>
+ <panel
+ border="false"
+ bevel_style="none"
+ follows="left|top"
+ layout="topleft"
+ left="12"
+ top_pad="10"
+ height="61"
+ width="214">
+ <text
+ height="13"
+ word_wrap="true"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ length="1"
+ layout="topleft"
+ left="0"
+ top_pad="0"
+ width="214">
+ Status
+ </text>
+ <text
+ height="40"
+ word_wrap="true"
+ use_ellipses="false"
+ type="string"
+ text_color="MaterialGoodColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left="0"
+ name="material_status"
+ top_pad="8"
+ width="214">
+ </text>
+ </panel>
+ <tab_container
+ follows="left|top|right"
+ layout="topleft"
+ tab_position="top"
+ left="10"
+ top_pad="10"
+ height="641"
+ width="1020">
+ <panel
+ border="true"
+ bevel_style="none"
+ follows="left|top|right"
+ layout="topleft"
+ label="Current region"
+ height="641"
+ top_pad="10"
+ width="1020">
+ <panel
+ border="false"
+ bevel_style="none"
+ follows="left|top|right"
+ layout="topleft"
+ height="479"
+ top_pad="10"
+ width="1020">
+ <button
+ follows="left|top"
+ height="22"
+ label="Get"
+ layout="topleft"
+ name="get_button"
+ top_pad="0"
+ width="214"/>
+ <text
+ height="13"
+ word_wrap="true"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left="2"
+ top_pad="8"
+ width="150">
+ Loading Status
+ </text>
+ <text
+ height="13"
+ word_wrap="true"
+ use_ellipses="false"
+ type="string"
+ text_color="MaterialGoodColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left_pad="0"
+ name="loading_status"
+ top_pad="-13"
+ width="400">
+ </text>
+ <scroll_list
+ column_padding="0"
+ draw_heading="true"
+ follows="left|top|right"
+ height="135"
+ layout="topleft"
+ left="0"
+ top_pad="10"
+ tab_stop="false"
+ multi_select="false"
+ name="get_other_data_scroll_list"
+ width="775">
+ <scroll_list.columns
+ label="Material ID"
+ name="id"
+ dynamic_width="true" />
+ <scroll_list.columns
+ label="Specular Color"
+ name="specular_color"
+ width="120" />
+ <scroll_list.columns
+ label="Specular Exponent"
+ name="specular_exponent"
+ width="112" />
+ <scroll_list.columns
+ label="Env Intensity"
+ name="env_intensity"
+ width="80" />
+ <scroll_list.columns
+ label="Alpha Mask Cutoff"
+ name="alpha_mask_cutoff"
+ width="110" />
+ <scroll_list.columns
+ label="Diffuse Alpha Mode"
+ name="diffuse_alpha_mode"
+ width="118" />
+ </scroll_list>
+ <scroll_list
+ column_padding="0"
+ draw_heading="true"
+ follows="left|top|right"
+ height="135"
+ layout="topleft"
+ top_pad="10"
+ tab_stop="false"
+ multi_select="false"
+ name="get_specular_map_scroll_list"
+ width="1020">
+ <scroll_list.columns
+ label="Material ID"
+ name="id"
+ dynamic_width="true" />
+ <scroll_list.columns
+ label="Specular Map"
+ name="specular_map_list_map"
+ width="225" />
+ <scroll_list.columns
+ label="Offset X"
+ name="specular_map_list_offset_x"
+ width="112" />
+ <scroll_list.columns
+ label="Offset Y"
+ name="specular_map_list_offset_y"
+ width="112" />
+ <scroll_list.columns
+ label="Repeat X"
+ name="specular_map_list_repeat_x"
+ width="112" />
+ <scroll_list.columns
+ label="Repeat Y"
+ name="specular_map_list_repeat_y"
+ width="112" />
+ <scroll_list.columns
+ label="Rotation"
+ name="specular_map_list_rotation"
+ width="112" />
+ </scroll_list>
+ <scroll_list
+ column_padding="0"
+ draw_heading="true"
+ follows="left|top|right"
+ height="135"
+ layout="topleft"
+ top_pad="10"
+ tab_stop="false"
+ multi_select="false"
+ name="get_normal_map_scroll_list"
+ width="1020">
+ <scroll_list.columns
+ label="Material ID"
+ name="id"
+ dynamic_width="true" />
+ <scroll_list.columns
+ label="Normal Map"
+ name="normal_map_list_map"
+ width="225" />
+ <scroll_list.columns
+ label="Offset X"
+ name="normal_map_list_offset_x"
+ width="112" />
+ <scroll_list.columns
+ label="Offset Y"
+ name="normal_map_list_offset_y"
+ width="112" />
+ <scroll_list.columns
+ label="Repeat X"
+ name="normal_map_list_repeat_x"
+ width="112" />
+ <scroll_list.columns
+ label="Repeat Y"
+ name="normal_map_list_repeat_y"
+ width="112" />
+ <scroll_list.columns
+ label="Rotation"
+ name="normal_map_list_rotation"
+ width="112" />
+ </scroll_list>
+ </panel>
+ </panel>
+ <panel
+ border="true"
+ bevel_style="none"
+ follows="left|top|right"
+ layout="topleft"
+ label="Object editing"
+ height="641"
+ top_pad="10"
+ width="1010">
+ <panel
+ border="false"
+ bevel_style="none"
+ follows="left|top|right"
+ layout="topleft"
+ left="2"
+ top_pad="10"
+ height="420"
+ width="810">
+ <panel
+ border="false"
+ bevel_style="none"
+ follows="left|top|right"
+ layout="topleft"
+ height="265"
+ top_pad="0"
+ width="810">
+ <panel
+ border="false"
+ bevel_style="none"
+ follows="left|top|right"
+ layout="topleft"
+ height="226"
+ top_pad="0"
+ width="263">
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left="0"
+ top_pad="38"
+ width="160">
+ Normal Map
+ </text>
+ <texture_picker
+ allow_no_texture="true"
+ can_apply_immediately="true"
+ default_image_name="Default"
+ follows="left|top"
+ left_pad="0"
+ top_pad="-50"
+ label_width="0"
+ height="100"
+ width="100"
+ mouse_opaque="true"
+ name="normal_map"
+ tool_tip="Click to open texture picker" />
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left_pad="-260"
+ top_pad="10"
+ width="160">
+ Normal Map Offset X
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ default_text="0"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="0"
+ top_pad="-18"
+ max_length_chars="255"
+ name="normal_map_offset_x"
+ width="80" />
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left_pad="-240"
+ top_pad="10"
+ width="160">
+ Normal Map Offset Y
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ default_text="0"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="0"
+ top_pad="-18"
+ max_length_chars="255"
+ name="normal_map_offset_y"
+ width="80" />
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left_pad="-240"
+ top_pad="10"
+ width="160">
+ Normal Map Repeat X
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ default_text="0"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="0"
+ top_pad="-18"
+ max_length_chars="255"
+ name="normal_map_repeat_x"
+ width="80" />
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left_pad="-240"
+ top_pad="10"
+ width="160">
+ Normal Map Repeat Y
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ default_text="0"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="0"
+ top_pad="-18"
+ max_length_chars="255"
+ name="normal_map_repeat_y"
+ width="80" />
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left_pad="-240"
+ top_pad="10"
+ width="160">
+ Normal Map Rotation
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ default_text="0"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="0"
+ top_pad="-18"
+ max_length_chars="255"
+ name="normal_map_rotation"
+ width="80" />
+ </panel>
+ <panel
+ border="false"
+ bevel_style="none"
+ follows="left|top|right"
+ layout="topleft"
+ height="226"
+ top_pad="-226"
+ left_pad="20"
+ width="263">
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left="0"
+ top_pad="38"
+ width="160">
+ Specular Map
+ </text>
+ <texture_picker
+ allow_no_texture="true"
+ can_apply_immediately="true"
+ default_image_name="Default"
+ follows="left|top"
+ left_pad="0"
+ top_pad="-50"
+ label_width="0"
+ height="100"
+ width="100"
+ mouse_opaque="true"
+ name="specular_map"
+ tool_tip="Click to open texture picker" />
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left_pad="-260"
+ top_pad="10"
+ width="160">
+ Specular Map Offset X
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ default_text="0"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="0"
+ top_pad="-18"
+ max_length_chars="255"
+ name="specular_map_offset_x"
+ width="80" />
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left_pad="-240"
+ top_pad="10"
+ width="160">
+ Specular Map Offset Y
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ default_text="0"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="0"
+ top_pad="-18"
+ max_length_chars="255"
+ name="specular_map_offset_y"
+ width="80" />
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left_pad="-240"
+ top_pad="10"
+ width="160">
+ Specular Map Repeat X
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ default_text="0"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="0"
+ top_pad="-18"
+ max_length_chars="255"
+ name="specular_map_repeat_x"
+ width="80" />
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left_pad="-240"
+ top_pad="10"
+ width="160">
+ Specular Map Repeat Y
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ default_text="0"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="0"
+ top_pad="-18"
+ max_length_chars="255"
+ name="specular_map_repeat_y"
+ width="80" />
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left_pad="-240"
+ top_pad="10"
+ width="160">
+ Specular Map Rotation
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ default_text="0"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="0"
+ top_pad="-18"
+ max_length_chars="255"
+ name="specular_map_rotation"
+ width="80" />
+ </panel>
+ <panel
+ border="false"
+ bevel_style="none"
+ follows="left|top|right"
+ layout="topleft"
+ height="162"
+ top_pad="-226"
+ left_pad="20"
+ width="243">
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left="0"
+ top_pad="10"
+ width="160">
+ Specular Color
+ </text>
+ <color_swatch
+ can_apply_immediately="true"
+ color="1 1 1 1"
+ follows="left|top"
+ height="30"
+ layout="topleft"
+ label_height="0"
+ label_width="0"
+ left_pad="0"
+ top_pad="-22"
+ name="specular_color"
+ tool_tip="Click to open color picker"
+ width="40" />
+ <spinner
+ follows="left|top"
+ height="20"
+ initial_value="255"
+ max_val="255"
+ min_val="0"
+ increment="1"
+ decimal_digits="0"
+ allow_text_entry="true"
+ layout="topleft"
+ label_width="160"
+ left="0"
+ top_pad="10"
+ label="Specular Color Alpha"
+ name="specular_color_alpha"
+ width="240" />
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left_pad="-240"
+ top_pad="13"
+ width="160">
+ Specular Exponent
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ default_text="0"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="0"
+ top_pad="-18"
+ max_length_chars="255"
+ name="specular_exponent"
+ width="80" />
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left_pad="-240"
+ top_pad="10"
+ width="160">
+ Environment Exponent
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ default_text="0"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="0"
+ top_pad="-18"
+ max_length_chars="255"
+ name="environment_exponent"
+ width="80" />
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left_pad="-240"
+ top_pad="10"
+ width="160">
+ Alpha Mask Cuttoff
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ default_text="0"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="0"
+ top_pad="-18"
+ max_length_chars="255"
+ name="alpha_mask_cutoff"
+ width="80" />
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left_pad="-240"
+ top_pad="10"
+ width="160">
+ Diffuse Alpha Mode
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ default_text="0"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="0"
+ top_pad="-18"
+ max_length_chars="255"
+ name="diffuse_alpha_mode"
+ width="80" />
+ </panel>
+ <panel
+ border="false"
+ bevel_style="none"
+ follows="left|top|right"
+ layout="topleft"
+ height="22"
+ left="0"
+ top_pad="80"
+ width="810">
+ <button
+ follows="left|top"
+ height="22"
+ label="Set Face Data"
+ layout="topleft"
+ name="put_set_button"
+ left="0"
+ top="0"
+ width="214"/>
+ <button
+ follows="left|top"
+ height="22"
+ label="Clear Face Data"
+ layout="topleft"
+ name="put_clear_button"
+ left_pad="20"
+ width="214"/>
+ <button
+ follows="left|top"
+ height="22"
+ label="Reset Input Values"
+ layout="topleft"
+ name="reset_put_values_button"
+ left_pad="146"
+ width="214"/>
+ </panel>
+ </panel>
+ <view_border
+ bevel_style="none"
+ follows="left|top"
+ height="0"
+ layout="topleft"
+ name="horiz_separator"
+ top_pad="10"
+ left="0"
+ width="810"/>
+ <panel
+ border="false"
+ bevel_style="none"
+ follows="left|top|right"
+ layout="topleft"
+ height="125"
+ top_pad="20"
+ width="400">
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left="0"
+ top_pad="0"
+ width="160">
+ Results
+ </text>
+ <scroll_list
+ column_padding="0"
+ draw_heading="true"
+ follows="left|top|right"
+ height="100"
+ layout="topleft"
+ left="0"
+ top_pad="10"
+ tab_stop="false"
+ multi_select="true"
+ name="put_scroll_list"
+ width="400">
+ <scroll_list.columns
+ label="Object ID"
+ name="object_id"
+ width="80" />
+ <scroll_list.columns
+ label="Face Index"
+ name="face_index"
+ width="70" />
+ <scroll_list.columns
+ label="MaterialID"
+ name="material_id"
+ dynamic_width="true" />
+ </scroll_list>
+ </panel>
+ </panel>
+ </panel>
+ <panel
+ border="true"
+ bevel_style="none"
+ follows="left|top|right"
+ layout="topleft"
+ label="Viewable objects"
+ height="641"
+ top_pad="10"
+ width="1020">
+ <panel
+ border="false"
+ bevel_style="none"
+ follows="left|top|right"
+ layout="topleft"
+ height="641"
+ top_pad="0"
+ width="1020">
+ <panel
+ border="false"
+ bevel_style="none"
+ follows="left|top|right"
+ layout="topleft"
+ left="0"
+ top_pad="10"
+ height="153"
+ width="835">
+ <button
+ follows="left|top"
+ height="22"
+ label="Query Viewable Objects"
+ layout="topleft"
+ name="query_viewable_objects_button"
+ top_pad="0"
+ width="214"/>
+ <text
+ height="13"
+ word_wrap="true"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left="2"
+ top_pad="8"
+ width="150">
+ Loading Status
+ </text>
+ <text
+ height="13"
+ word_wrap="true"
+ use_ellipses="false"
+ type="string"
+ text_color="MaterialGoodColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left_pad="0"
+ name="query_status"
+ top_pad="-13"
+ width="400">
+ </text>
+ <scroll_list
+ column_padding="0"
+ draw_heading="true"
+ follows="left|top|right"
+ height="100"
+ layout="topleft"
+ top_pad="10"
+ left="0"
+ tab_stop="false"
+ multi_select="true"
+ name="viewable_objects_scroll_list"
+ width="835">
+ <scroll_list.columns
+ label="Object ID"
+ name="object_id"
+ width="225" />
+ <scroll_list.columns
+ label="Region"
+ name="region"
+ width="225" />
+ <scroll_list.columns
+ label="Local ID"
+ name="local_id"
+ width="70" />
+ <scroll_list.columns
+ label="Face"
+ name="face_index"
+ width="70" />
+ <scroll_list.columns
+ label="Material ID"
+ name="material_id"
+ dynamic_width="true" />
+ </scroll_list>
+ </panel>
+ <view_border
+ bevel_style="none"
+ follows="left|right|top"
+ height="0"
+ layout="topleft"
+ name="horiz_separator"
+ top_pad="10"
+ left="0"
+ width="1020"/>
+ <panel
+ border="false"
+ bevel_style="none"
+ follows="left|top|right"
+ layout="topleft"
+ height="458"
+ top_pad="10"
+ width="1020">
+ <button
+ follows="left|top"
+ height="22"
+ label="Post Material ID"
+ layout="topleft"
+ name="post_button"
+ top_pad="0"
+ width="214"/>
+ <scroll_list
+ column_padding="0"
+ draw_heading="true"
+ follows="left|top|right"
+ height="135"
+ layout="topleft"
+ top_pad="10"
+ left="0"
+ tab_stop="false"
+ multi_select="false"
+ name="post_other_data_scroll_list"
+ width="775">
+ <scroll_list.columns
+ label="Material ID"
+ name="id"
+ dynamic_width="true" />
+ <scroll_list.columns
+ label="Specular Color"
+ name="specular_color"
+ width="120" />
+ <scroll_list.columns
+ label="Specular Exponent"
+ name="specular_exponent"
+ width="112" />
+ <scroll_list.columns
+ label="Env Intensity"
+ name="env_intensity"
+ width="80" />
+ <scroll_list.columns
+ label="Alpha Mask Cutoff"
+ name="alpha_mask_cutoff"
+ width="110" />
+ <scroll_list.columns
+ label="Diffuse Alpha Mode"
+ name="diffuse_alpha_mode"
+ width="118" />
+ </scroll_list>
+ <scroll_list
+ column_padding="0"
+ draw_heading="true"
+ follows="left|top|right"
+ height="135"
+ layout="topleft"
+ top_pad="10"
+ tab_stop="false"
+ multi_select="false"
+ name="post_specular_map_scroll_list"
+ width="1020">
+ <scroll_list.columns
+ label="Material ID"
+ name="id"
+ dynamic_width="true" />
+ <scroll_list.columns
+ label="Specular Map"
+ name="specular_map_list_map"
+ width="225" />
+ <scroll_list.columns
+ label="Offset X"
+ name="specular_map_list_offset_x"
+ width="112" />
+ <scroll_list.columns
+ label="Offset Y"
+ name="specular_map_list_offset_y"
+ width="112" />
+ <scroll_list.columns
+ label="Repeat X"
+ name="specular_map_list_repeat_x"
+ width="112" />
+ <scroll_list.columns
+ label="Repeat Y"
+ name="specular_map_list_repeat_y"
+ width="112" />
+ <scroll_list.columns
+ label="Rotation"
+ name="specular_map_list_rotation"
+ width="112" />
+ </scroll_list>
+ <scroll_list
+ column_padding="0"
+ draw_heading="true"
+ follows="left|top|right"
+ height="135"
+ layout="topleft"
+ top_pad="10"
+ tab_stop="false"
+ multi_select="false"
+ name="post_normal_map_scroll_list"
+ width="1020">
+ <scroll_list.columns
+ label="Material ID"
+ name="id"
+ dynamic_width="true" />
+ <scroll_list.columns
+ label="Normal Map"
+ name="normal_map_list_map"
+ width="225" />
+ <scroll_list.columns
+ label="Offset X"
+ name="normal_map_list_offset_x"
+ width="112" />
+ <scroll_list.columns
+ label="Offset Y"
+ name="normal_map_list_offset_y"
+ width="112" />
+ <scroll_list.columns
+ label="Repeat X"
+ name="normal_map_list_repeat_x"
+ width="112" />
+ <scroll_list.columns
+ label="Repeat Y"
+ name="normal_map_list_repeat_y"
+ width="112" />
+ <scroll_list.columns
+ label="Rotation"
+ name="normal_map_list_rotation"
+ width="112" />
+ </scroll_list>
+ </panel>
+ </panel>
+ </panel>
+ </tab_container>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 18932a32d0..721a1818dd 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -2619,6 +2619,17 @@
<menu_item_check.on_enable
function="Advanced.EnableRenderDeferredOptions" />
</menu_item_check>
+
+ <menu_item_separator/>
+
+ <menu_item_call
+ label="Debug materials ..."
+ name="DebugMaterialsMenu">
+ <menu_item_call.on_click
+ function="Floater.ToggleOrBringToFront"
+ parameter="floater_debug_materials" />
+ </menu_item_call>
+
<menu_item_separator />
<menu_item_check
diff --git a/indra/newview/tests/llmediadataclient_test.cpp b/indra/newview/tests/llmediadataclient_test.cpp
index 0254c5881f..37f94b82df 100644
--- a/indra/newview/tests/llmediadataclient_test.cpp
+++ b/indra/newview/tests/llmediadataclient_test.cpp
@@ -39,6 +39,7 @@
#include "../llvovolume.h"
#include "../../llprimitive/llmediaentry.cpp"
+#include "../../llprimitive/llmaterialid.cpp"
#include "../../llprimitive/lltextureentry.cpp"
#include "../../llmessage/tests/llcurl_stub.cpp"
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index ea75d4f4f6..8cc181671f 100644
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -202,7 +202,7 @@ class ViewerManifest(LLManifest):
grid_flags = ''
if not self.default_grid():
grid_flags = "--grid %(grid)s "\
- "--helperuri http://preview-%(grid)s.secondlife.com/helpers/" %\
+ %\
{'grid':self.grid()}
# set command line flags for channel