summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BuildParams11
-rw-r--r--indra/cmake/LLAddBuildTest.cmake8
-rw-r--r--indra/llcorehttp/CMakeLists.txt2
-rw-r--r--indra/llprimitive/CMakeLists.txt2
-rw-r--r--indra/llprimitive/llmaterialid.cpp176
-rw-r--r--indra/llprimitive/llmaterialid.h74
-rwxr-xr-xindra/llprimitive/llprimitive.cpp34
-rw-r--r--indra/llprimitive/llprimitive.h2
-rw-r--r--indra/llprimitive/llprimtexturelist.cpp10
-rw-r--r--indra/llprimitive/llprimtexturelist.h2
-rw-r--r--indra/llprimitive/lltextureentry.cpp17
-rw-r--r--indra/llprimitive/lltextureentry.h4
-rw-r--r--indra/llrender/llglslshader.cpp66
-rw-r--r--indra/llrender/llglslshader.h13
-rw-r--r--indra/llrender/llshadermgr.cpp10
-rw-r--r--indra/llrender/llshadermgr.h2
-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.cpp1957
-rw-r--r--indra/newview/llfloaterdebugmaterials.h214
-rw-r--r--indra/newview/llpanelface.cpp110
-rw-r--r--indra/newview/llpanelface.h4
-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/floater_tools.xml538
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml11
-rw-r--r--indra/newview/skins/default/xui/en/panel_tools_texture.xml483
-rw-r--r--indra/newview/tests/llmediadataclient_test.cpp1
-rw-r--r--indra/newview/viewer_manifest.py2
40 files changed, 4362 insertions, 623 deletions
diff --git a/BuildParams b/BuildParams
index 6a0e30e526..4d5f83eba6 100644
--- a/BuildParams
+++ b/BuildParams
@@ -132,6 +132,17 @@ viewer-pathfinding.build_debug_release_separately = true
viewer-pathfinding.build_CYGWIN_Debug = false
viewer-pathfinding.build_viewer_update_version_manager = false
+# ========================================
+# viewer-materials
+# ========================================
+
+viewer-materials.viewer_channel = "Project Viewer - Materials"
+viewer-materials.login_channel = "Project Viewer - Materials"
+viewer-materials.viewer_grid = aditi
+viewer-materials.build_debug_release_separately = true
+viewer-materials.build_CYGWIN_Debug = false
+viewer-materials.build_viewer_update_version_manager = false
+
# =================================================================
# asset delivery 2010 projects
# =================================================================
diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake
index 543075db5b..afae38b51c 100644
--- a/indra/cmake/LLAddBuildTest.cmake
+++ b/indra/cmake/LLAddBuildTest.cmake
@@ -201,14 +201,6 @@ FUNCTION(LL_ADD_INTEGRATION_TEST
endif(TEST_DEBUG)
ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files})
SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}")
- if (WINDOWS)
- set_target_properties(INTEGRATION_TEST_${testname}
- PROPERTIES
- LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /INCLUDE:__tcmalloc"
- LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO"
- LINK_FLAGS_RELEASE ""
- )
- endif(WINDOWS)
if(STANDALONE)
SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} PROPERTIES COMPILE_FLAGS -I"${TUT_INCLUDE_DIR}")
diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt
index 82fb3f0d4e..9adfd0ed62 100644
--- a/indra/llcorehttp/CMakeLists.txt
+++ b/indra/llcorehttp/CMakeLists.txt
@@ -174,7 +174,7 @@ if (LL_TESTS)
# The following come from LLAddBuildTest.cmake's INTEGRATION_TEST_xxxx target.
set_target_properties(http_texture_load
PROPERTIES
- LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /INCLUDE:__tcmalloc"
+ LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS ${TCMALLOC_LINK_FLAGS}"
LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO"
LINK_FLAGS_RELEASE ""
)
diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt
index e4d9de7eb6..82d0f892f2 100644
--- a/indra/llprimitive/CMakeLists.txt
+++ b/indra/llprimitive/CMakeLists.txt
@@ -20,6 +20,7 @@ include_directories(
)
set(llprimitive_SOURCE_FILES
+ llmaterialid.cpp
llmaterialtable.cpp
llmediaentry.cpp
llmodel.cpp
@@ -37,6 +38,7 @@ set(llprimitive_HEADER_FILES
CMakeLists.txt
legacy_object_types.h
+ llmaterialid.h
llmaterialtable.h
llmediaentry.h
llmodel.h
diff --git a/indra/llprimitive/llmaterialid.cpp b/indra/llprimitive/llmaterialid.cpp
new file mode 100644
index 0000000000..590f5cd91f
--- /dev/null
+++ b/indra/llprimitive/llmaterialid.cpp
@@ -0,0 +1,176 @@
+/**
+* @file llmaterialid.cpp
+* @brief Implementation of llmaterialid
+* @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 "linden_common.h"
+
+#include "llmaterialid.h"
+
+#include <string>
+
+#include "llformat.h"
+
+const LLMaterialID LLMaterialID::null;
+
+LLMaterialID::LLMaterialID()
+{
+ clear();
+}
+
+LLMaterialID::LLMaterialID(const LLSD& pMaterialID)
+{
+ llassert(pMaterialID.isBinary());
+ parseFromBinary(pMaterialID.asBinary());
+}
+
+LLMaterialID::LLMaterialID(const LLSD::Binary& pMaterialID)
+{
+ parseFromBinary(pMaterialID);
+}
+
+LLMaterialID::LLMaterialID(const void* pMemory)
+{
+ set(pMemory);
+}
+
+LLMaterialID::LLMaterialID(const LLMaterialID& pOtherMaterialID)
+{
+ copyFromOtherMaterialID(pOtherMaterialID);
+}
+
+LLMaterialID::~LLMaterialID()
+{
+}
+
+bool LLMaterialID::operator == (const LLMaterialID& pOtherMaterialID) const
+{
+ return (compareToOtherMaterialID(pOtherMaterialID) == 0);
+}
+
+bool LLMaterialID::operator != (const LLMaterialID& pOtherMaterialID) const
+{
+ return (compareToOtherMaterialID(pOtherMaterialID) != 0);
+}
+
+bool LLMaterialID::operator < (const LLMaterialID& pOtherMaterialID) const
+{
+ return (compareToOtherMaterialID(pOtherMaterialID) < 0);
+}
+
+bool LLMaterialID::operator <= (const LLMaterialID& pOtherMaterialID) const
+{
+ return (compareToOtherMaterialID(pOtherMaterialID) <= 0);
+}
+
+bool LLMaterialID::operator > (const LLMaterialID& pOtherMaterialID) const
+{
+ return (compareToOtherMaterialID(pOtherMaterialID) > 0);
+}
+
+bool LLMaterialID::operator >= (const LLMaterialID& pOtherMaterialID) const
+{
+ return (compareToOtherMaterialID(pOtherMaterialID) >= 0);
+}
+
+LLMaterialID& LLMaterialID::operator = (const LLMaterialID& pOtherMaterialID)
+{
+ copyFromOtherMaterialID(pOtherMaterialID);
+ return (*this);
+}
+
+bool LLMaterialID::isNull() const
+{
+ return (compareToOtherMaterialID(LLMaterialID::null) == 0);
+}
+
+const U8* LLMaterialID::get() const
+{
+ return mID;
+}
+
+void LLMaterialID::set(const void* pMemory)
+{
+ llassert(pMemory != NULL);
+
+ // assumes that the required size of memory is available
+ memcpy(mID, pMemory, MATERIAL_ID_SIZE * sizeof(U8));
+}
+
+void LLMaterialID::clear()
+{
+ memset(mID, 0, MATERIAL_ID_SIZE * sizeof(U8));
+}
+
+LLSD LLMaterialID::asLLSD() const
+{
+ LLSD::Binary materialIDBinary;
+
+ materialIDBinary.resize(MATERIAL_ID_SIZE * sizeof(U8));
+ memcpy(materialIDBinary.data(), mID, MATERIAL_ID_SIZE * sizeof(U8));
+
+ LLSD materialID = materialIDBinary;
+ return materialID;
+}
+
+std::string LLMaterialID::asString() const
+{
+ std::string materialIDString;
+ for (unsigned int i = 0U; i < static_cast<unsigned int>(MATERIAL_ID_SIZE / sizeof(U32)); ++i)
+ {
+ if (i != 0U)
+ {
+ materialIDString += "-";
+ }
+ const U32 *value = reinterpret_cast<const U32*>(&get()[i * sizeof(U32)]);
+ materialIDString += llformat("%08x", *value);
+ }
+ return materialIDString;
+}
+
+void LLMaterialID::parseFromBinary (const LLSD::Binary& pMaterialID)
+{
+ llassert(pMaterialID.size() == (MATERIAL_ID_SIZE * sizeof(U8)));
+ memcpy(mID, &pMaterialID[0], MATERIAL_ID_SIZE * sizeof(U8));
+}
+
+void LLMaterialID::copyFromOtherMaterialID(const LLMaterialID& pOtherMaterialID)
+{
+ memcpy(mID, pOtherMaterialID.get(), MATERIAL_ID_SIZE * sizeof(U8));
+}
+
+int LLMaterialID::compareToOtherMaterialID(const LLMaterialID& pOtherMaterialID) const
+{
+ int retVal = 0;
+
+ for (unsigned int i = 0U; (retVal == 0) && (i < static_cast<unsigned int>(MATERIAL_ID_SIZE / sizeof(U32))); ++i)
+ {
+ const U32 *thisValue = reinterpret_cast<const U32*>(&get()[i * sizeof(U32)]);
+ const U32 *otherValue = reinterpret_cast<const U32*>(&pOtherMaterialID.get()[i * sizeof(U32)]);
+ retVal = ((*thisValue < *otherValue) ? -1 : ((*thisValue > *otherValue) ? 1 : 0));
+ }
+
+ return retVal;
+}
diff --git a/indra/llprimitive/llmaterialid.h b/indra/llprimitive/llmaterialid.h
new file mode 100644
index 0000000000..9db4065302
--- /dev/null
+++ b/indra/llprimitive/llmaterialid.h
@@ -0,0 +1,74 @@
+/**
+* @file llmaterialid.h
+* @brief Header file for llmaterialid
+* @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_LLMATERIALID_H
+#define LL_LLMATERIALID_H
+
+#define MATERIAL_ID_SIZE 16
+
+#include <string>
+
+class LLMaterialID
+{
+public:
+ LLMaterialID();
+ LLMaterialID(const LLSD& pMaterialID);
+ LLMaterialID(const LLSD::Binary& pMaterialID);
+ LLMaterialID(const void* pMemory);
+ LLMaterialID(const LLMaterialID& pOtherMaterialID);
+ ~LLMaterialID();
+
+ bool operator == (const LLMaterialID& pOtherMaterialID) const;
+ bool operator != (const LLMaterialID& pOtherMaterialID) const;
+
+ bool operator < (const LLMaterialID& pOtherMaterialID) const;
+ bool operator <= (const LLMaterialID& pOtherMaterialID) const;
+ bool operator > (const LLMaterialID& pOtherMaterialID) const;
+ bool operator >= (const LLMaterialID& pOtherMaterialID) const;
+
+ LLMaterialID& operator = (const LLMaterialID& pOtherMaterialID);
+
+ bool isNull() const;
+
+ const U8* get() const;
+ void set(const void* pMemory);
+ void clear();
+
+ LLSD asLLSD() const;
+ std::string asString() const;
+
+ static const LLMaterialID null;
+
+private:
+ void parseFromBinary(const LLSD::Binary& pMaterialID);
+ void copyFromOtherMaterialID(const LLMaterialID& pOtherMaterialID);
+ int compareToOtherMaterialID(const LLMaterialID& pOtherMaterialID) const;
+
+ U8 mID[MATERIAL_ID_SIZE];
+} ;
+
+#endif // LL_LLMATERIALID_H
+
diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp
index 6dee192783..86aa371368 100755
--- a/indra/llprimitive/llprimitive.cpp
+++ b/indra/llprimitive/llprimitive.cpp
@@ -39,6 +39,7 @@
#include "lldatapacker.h"
#include "llsdutil_math.h"
#include "llprimtexturelist.h"
+#include "llmaterialid.h"
/**
* exported constants
@@ -366,6 +367,11 @@ S32 LLPrimitive::setTEGlow(const U8 index, const F32 glow)
return mTextureList.setGlow(index, glow);
}
+S32 LLPrimitive::setTEMaterialID(const U8 index, const LLMaterialID& pMaterialID)
+{
+ return mTextureList.setMaterialID(index, pMaterialID);
+}
+
LLPCode LLPrimitive::legacyToPCode(const U8 legacy)
{
@@ -1091,6 +1097,7 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const
U8 bump[MAX_TES];
U8 media_flags[MAX_TES];
U8 glow[MAX_TES];
+ U8 material_data[MAX_TES*16];
const U32 MAX_TE_BUFFER = 4096;
U8 packed_buffer[MAX_TE_BUFFER];
@@ -1128,6 +1135,9 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const
bump[face_index] = te->getBumpShinyFullbright();
media_flags[face_index] = te->getMediaTexGen();
glow[face_index] = (U8) llround((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF));
+
+ // Directly sending material_ids is not safe!
+ memcpy(&material_data[face_index*16],getTE(face_index)->getMaterialID().get(),16); /* Flawfinder: ignore */
}
cur_ptr += packTEField(cur_ptr, (U8 *)image_ids, sizeof(LLUUID),last_face_index, MVT_LLUUID);
@@ -1149,6 +1159,8 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const
cur_ptr += packTEField(cur_ptr, (U8 *)media_flags, 1 ,last_face_index, MVT_U8);
*cur_ptr++ = 0;
cur_ptr += packTEField(cur_ptr, (U8 *)glow, 1 ,last_face_index, MVT_U8);
+ *cur_ptr++ = 0;
+ cur_ptr += packTEField(cur_ptr, (U8 *)material_data, 16, last_face_index, MVT_LLUUID);
}
mesgsys->addBinaryDataFast(_PREHASH_TextureEntry, packed_buffer, (S32)(cur_ptr - packed_buffer));
@@ -1170,6 +1182,7 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const
U8 bump[MAX_TES];
U8 media_flags[MAX_TES];
U8 glow[MAX_TES];
+ U8 material_data[MAX_TES*16];
const U32 MAX_TE_BUFFER = 4096;
U8 packed_buffer[MAX_TE_BUFFER];
@@ -1207,6 +1220,9 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const
bump[face_index] = te->getBumpShinyFullbright();
media_flags[face_index] = te->getMediaTexGen();
glow[face_index] = (U8) llround((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF));
+
+ // Directly sending material_ids is not safe!
+ memcpy(&material_data[face_index*16],getTE(face_index)->getMaterialID().get(),16); /* Flawfinder: ignore */
}
cur_ptr += packTEField(cur_ptr, (U8 *)image_ids, sizeof(LLUUID),last_face_index, MVT_LLUUID);
@@ -1228,6 +1244,8 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const
cur_ptr += packTEField(cur_ptr, (U8 *)media_flags, 1 ,last_face_index, MVT_U8);
*cur_ptr++ = 0;
cur_ptr += packTEField(cur_ptr, (U8 *)glow, 1 ,last_face_index, MVT_U8);
+ *cur_ptr++ = 0;
+ cur_ptr += packTEField(cur_ptr, (U8 *)material_data, 16, last_face_index, MVT_LLUUID);
}
dp.packBinaryData(packed_buffer, (S32)(cur_ptr - packed_buffer), "TextureEntry");
@@ -1246,6 +1264,7 @@ S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_nam
const U32 MAX_TES = 32;
// Avoid construction of 32 UUIDs per call. JC
+ static LLMaterialID material_ids[MAX_TES];
U8 image_data[MAX_TES*16];
U8 colors[MAX_TES*4];
@@ -1257,6 +1276,7 @@ S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_nam
U8 bump[MAX_TES];
U8 media_flags[MAX_TES];
U8 glow[MAX_TES];
+ U8 material_data[MAX_TES*16];
const U32 MAX_TE_BUFFER = 4096;
U8 packed_buffer[MAX_TE_BUFFER];
@@ -1309,6 +1329,13 @@ S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_nam
cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)media_flags, 1, face_count, MVT_U8);
cur_ptr++;
cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)glow, 1, face_count, MVT_U8);
+ cur_ptr++;
+ cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)material_data, 16, face_count, MVT_LLUUID);
+
+ for (U32 i = 0; i < face_count; i++)
+ {
+ material_ids[i].set(&material_data[i * 16]);
+ }
LLColor4 color;
LLColor4U coloru;
@@ -1321,6 +1348,7 @@ S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_nam
retval |= setTEBumpShinyFullbright(i, bump[i]);
retval |= setTEMediaTexGen(i, media_flags[i]);
retval |= setTEGlow(i, (F32)glow[i] / (F32)0xFF);
+ retval |= setTEMaterialID(i, material_ids[i]);
coloru = LLColor4U(colors + 4*i);
// Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)
@@ -1346,6 +1374,7 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
// Avoid construction of 32 UUIDs per call
static LLUUID image_ids[MAX_TES];
+ static LLMaterialID material_ids[MAX_TES];
U8 image_data[MAX_TES*16];
U8 colors[MAX_TES*4];
@@ -1357,6 +1386,7 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
U8 bump[MAX_TES];
U8 media_flags[MAX_TES];
U8 glow[MAX_TES];
+ U8 material_data[MAX_TES*16];
const U32 MAX_TE_BUFFER = 4096;
U8 packed_buffer[MAX_TE_BUFFER];
@@ -1399,10 +1429,13 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)media_flags, 1, face_count, MVT_U8);
cur_ptr++;
cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)glow, 1, face_count, MVT_U8);
+ cur_ptr++;
+ cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)material_data, 16, face_count, MVT_LLUUID);
for (i = 0; i < face_count; i++)
{
memcpy(image_ids[i].mData,&image_data[i*16],16); /* Flawfinder: ignore */
+ material_ids[i].set(&material_data[i * 16]);
}
LLColor4 color;
@@ -1416,6 +1449,7 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
retval |= setTEBumpShinyFullbright(i, bump[i]);
retval |= setTEMediaTexGen(i, media_flags[i]);
retval |= setTEGlow(i, (F32)glow[i] / (F32)0xFF);
+ retval |= setTEMaterialID(i, material_ids[i]);
coloru = LLColor4U(colors + 4*i);
// Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)
diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h
index 8dcaa8c740..e1635740ef 100644
--- a/indra/llprimitive/llprimitive.h
+++ b/indra/llprimitive/llprimitive.h
@@ -42,6 +42,7 @@ class LLMessageSystem;
class LLVolumeParams;
class LLColor4;
class LLColor3;
+class LLMaterialID;
class LLTextureEntry;
class LLDataPacker;
class LLVolumeMgr;
@@ -353,6 +354,7 @@ public:
virtual S32 setTEFullbright(const U8 te, const U8 fullbright);
virtual S32 setTEMediaFlags(const U8 te, const U8 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); // returns TRUE if material changed
void copyTEs(const LLPrimitive *primitive);
diff --git a/indra/llprimitive/llprimtexturelist.cpp b/indra/llprimitive/llprimtexturelist.cpp
index 36e04df7b7..20438578b3 100644
--- a/indra/llprimitive/llprimtexturelist.cpp
+++ b/indra/llprimitive/llprimtexturelist.cpp
@@ -27,6 +27,7 @@
#include "linden_common.h"
#include "llprimtexturelist.h"
+#include "llmaterialid.h"
#include "lltextureentry.h"
#include "llmemtype.h"
@@ -359,6 +360,15 @@ S32 LLPrimTextureList::setGlow(const U8 index, const F32 glow)
return TEM_CHANGE_NONE;
}
+S32 LLPrimTextureList::setMaterialID(const U8 index, const LLMaterialID& pMaterialID)
+{
+ if (index < mEntryList.size())
+ {
+ return mEntryList[index]->setMaterialID(pMaterialID);
+ }
+ return TEM_CHANGE_NONE;
+}
+
S32 LLPrimTextureList::size() const
{
return mEntryList.size();
diff --git a/indra/llprimitive/llprimtexturelist.h b/indra/llprimitive/llprimtexturelist.h
index 3cfa52f1d5..691df44c18 100644
--- a/indra/llprimitive/llprimtexturelist.h
+++ b/indra/llprimitive/llprimtexturelist.h
@@ -34,6 +34,7 @@
class LLTextureEntry;
+class LLMaterialID;
// this is a list of LLTextureEntry*'s because in practice the list's elements
// are of some derived class: LLFooTextureEntry
@@ -102,6 +103,7 @@ public:
S32 setFullbright(const U8 index, const U8 t);
S32 setMediaFlags(const U8 index, const U8 media_flags);
S32 setGlow(const U8 index, const F32 glow);
+ S32 setMaterialID(const U8 index, const LLMaterialID& pMaterialID);
S32 size() const;
diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp
index 34eff17519..b04fa809d2 100644
--- a/indra/llprimitive/lltextureentry.cpp
+++ b/indra/llprimitive/lltextureentry.cpp
@@ -29,6 +29,7 @@
#include "lluuid.h"
#include "llmediaentry.h"
#include "lltextureentry.h"
+#include "llmaterialid.h"
#include "llsdutil_math.h"
#include "v4color.h"
@@ -83,6 +84,8 @@ LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs)
mBump = rhs.mBump;
mMediaFlags = rhs.mMediaFlags;
mGlow = rhs.mGlow;
+ mMaterialID = rhs.mMaterialID;
+
if (rhs.mMediaEntry != NULL) {
// Make a copy
mMediaEntry = new LLMediaEntry(*rhs.mMediaEntry);
@@ -103,6 +106,7 @@ LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs)
mBump = rhs.mBump;
mMediaFlags = rhs.mMediaFlags;
mGlow = rhs.mGlow;
+ mMaterialID = rhs.mMaterialID;
if (mMediaEntry != NULL) {
delete mMediaEntry;
}
@@ -130,6 +134,7 @@ void LLTextureEntry::init(const LLUUID& tex_id, F32 scale_s, F32 scale_t, F32 of
mBump = bump;
mMediaFlags = 0x0;
mGlow = 0;
+ mMaterialID.clear();
setColor(LLColor4(1.f, 1.f, 1.f, 1.f));
if (mMediaEntry != NULL) {
@@ -159,6 +164,7 @@ bool LLTextureEntry::operator!=(const LLTextureEntry &rhs) const
if (mBump != rhs.mBump) return (true);
if (mMediaFlags != rhs.mMediaFlags) return (true);
if (mGlow != rhs.mGlow) return (true);
+ if (mMaterialID != rhs.mMaterialID) return (true);
return(false);
}
@@ -174,6 +180,7 @@ bool LLTextureEntry::operator==(const LLTextureEntry &rhs) const
if (mBump != rhs.mBump) return (false);
if (mMediaFlags != rhs.mMediaFlags) return false;
if (mGlow != rhs.mGlow) return false;
+ if (mMaterialID != rhs.mMaterialID) return (false);
return(true);
}
@@ -523,6 +530,16 @@ S32 LLTextureEntry::setGlow(F32 glow)
return TEM_CHANGE_NONE;
}
+S32 LLTextureEntry::setMaterialID(const LLMaterialID& pMaterialID)
+{
+ if (mMaterialID != pMaterialID)
+ {
+ mMaterialID = pMaterialID;
+ return TEM_CHANGE_TEXTURE;
+ }
+ return TEM_CHANGE_NONE;
+}
+
void LLTextureEntry::setMediaData(const LLMediaEntry &media_entry)
{
mMediaFlags |= MF_HAS_MEDIA;
diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h
index 437b85e03f..b681ce8ca7 100644
--- a/indra/llprimitive/lltextureentry.h
+++ b/indra/llprimitive/lltextureentry.h
@@ -30,6 +30,7 @@
#include "lluuid.h"
#include "v4color.h"
#include "llsd.h"
+#include "llmaterialid.h"
// These bits are used while unpacking TEM messages to tell which aspects of
// the texture entry changed.
@@ -121,6 +122,7 @@ public:
S32 setTexGen(U8 texGen);
S32 setMediaTexGen(U8 media);
S32 setGlow(F32 glow);
+ S32 setMaterialID(const LLMaterialID& pMaterialID);
virtual const LLUUID &getID() const { return mID; }
const LLColor4 &getColor() const { return mColor; }
@@ -139,6 +141,7 @@ public:
U8 getTexGen() const { return mMediaFlags & TEM_TEX_GEN_MASK; }
U8 getMediaTexGen() const { return mMediaFlags; }
F32 getGlow() const { return mGlow; }
+ const LLMaterialID& getMaterialID() const { return mMaterialID; };
// *NOTE: it is possible for hasMedia() to return true, but getMediaData() to return NULL.
// CONVERSELY, it is also possible for hasMedia() to return false, but getMediaData()
@@ -193,6 +196,7 @@ protected:
U8 mBump; // Bump map, shiny, and fullbright
U8 mMediaFlags; // replace with web page, movie, etc.
F32 mGlow;
+ LLMaterialID mMaterialID;
// Note the media data is not sent via the same message structure as the rest of the TE
LLMediaEntry* mMediaEntry; // The media data for the face
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 7cbf39096e..39e81c4bfc 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -150,7 +150,7 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,
vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin();
for ( ; fileIter != mShaderFiles.end(); fileIter++ )
{
- GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, mFeatures.mIndexedTextureChannels);
+ GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, mDefines, mFeatures.mIndexedTextureChannels);
LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL;
if (shaderhandle > 0)
{
@@ -372,7 +372,17 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)
}
}
}
- }
+}
+
+void LLGLSLShader::addPermutation(std::string name, std::string value)
+{
+ mDefines[name] = value;
+}
+
+void LLGLSLShader::removePermutation(std::string name)
+{
+ mDefines[name].erase();
+}
GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type)
{
@@ -471,6 +481,58 @@ void LLGLSLShader::bindNoShader(void)
}
}
+S32 LLGLSLShader::bindTexture(const std::string &uniform, LLTexture *texture, LLTexUnit::eTextureType mode)
+{
+ S32 channel = 0;
+ channel = getUniformLocation(uniform);
+
+ return bindTexture(channel, texture, mode);
+}
+
+S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode)
+{
+ if (uniform < 0 || uniform >= (S32)mTexture.size())
+ {
+ UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
+ return -1;
+ }
+
+ uniform = mTexture[uniform];
+
+ if (uniform > -1)
+ {
+ gGL.getTexUnit(uniform)->bind(texture, mode);
+ }
+
+ return uniform;
+}
+
+S32 LLGLSLShader::unbindTexture(const std::string &uniform, LLTexUnit::eTextureType mode)
+{
+ S32 channel = 0;
+ channel = getUniformLocation(uniform);
+
+ return unbindTexture(channel);
+}
+
+S32 LLGLSLShader::unbindTexture(S32 uniform, LLTexUnit::eTextureType mode)
+{
+ if (uniform < 0 || uniform >= (S32)mTexture.size())
+ {
+ UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
+ return -1;
+ }
+
+ uniform = mTexture[uniform];
+
+ if (uniform > -1)
+ {
+ gGL.getTexUnit(uniform)->unbind(mode);
+ }
+
+ return uniform;
+}
+
S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode)
{
if (uniform < 0 || uniform >= (S32)mTexture.size())
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index 5c68cb46eb..2af74c20ff 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -123,12 +123,22 @@ public:
GLint getAttribLocation(U32 attrib);
GLint mapUniformTextureChannel(GLint location, GLenum type);
+ void addPermutation(std::string name, std::string value);
+ void removePermutation(std::string name);
+
//enable/disable texture channel for specified uniform
//if given texture uniform is active in the shader,
//the corresponding channel will be active upon return
//returns channel texture is enabled in from [0-MAX)
S32 enableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
- S32 disableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
+ S32 disableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
+
+ // bindTexture returns the texture unit we've bound the texture to.
+ // You can reuse the return value to unbind a texture when required.
+ S32 bindTexture(const std::string& uniform, LLTexture *texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
+ S32 bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
+ S32 unbindTexture(const std::string& uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
+ S32 unbindTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
BOOL link(BOOL suppress_errors = FALSE);
void bind();
@@ -153,6 +163,7 @@ public:
LLShaderFeatures mFeatures;
std::vector< std::pair< std::string, GLenum > > mShaderFiles;
std::string mName;
+ boost::unordered_map<std::string, std::string> mDefines;
};
//UI shader (declared here so llui_libtest will link properly)
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index b6a9a6b653..3b1ec281c9 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -521,7 +521,7 @@ void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns)
}
}
-GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, S32 texture_index_channels)
+GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, boost::unordered_map<std::string, std::string> defines, S32 texture_index_channels)
{
GLenum error = GL_NO_ERROR;
if (gDebugGL)
@@ -657,6 +657,12 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
std::string define = "#define " + iter->first + " " + iter->second + "\n";
text[count++] = (GLcharARB *) strdup(define.c_str());
}
+
+ for (boost::unordered_map<std::string,std::string>::iterator iter = defines.begin(); iter != defines.end(); ++iter)
+ {
+ std::string define = "#define " + iter->first + " " + iter->second + "\n";
+ text[count++] = (GLcharARB *) strdup(define.c_str());
+ }
if (texture_index_channels > 0 && type == GL_FRAGMENT_SHADER_ARB)
{
@@ -854,7 +860,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
if (shader_level > 1)
{
shader_level--;
- return loadShaderFile(filename,shader_level,type,texture_index_channels);
+ return loadShaderFile(filename,shader_level,type, defines, texture_index_channels);
}
LL_WARNS("ShaderLoading") << "Failed to load " << filename << LL_ENDL;
}
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index 7a16b7c20f..4b93aae735 100644
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -176,7 +176,7 @@ public:
void dumpObjectLog(GLhandleARB ret, BOOL warns = TRUE);
BOOL linkProgramObject(GLhandleARB obj, BOOL suppress_errors = FALSE);
BOOL validateProgramObject(GLhandleARB obj);
- GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, S32 texture_index_channels = -1);
+ GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, boost::unordered_map<std::string, std::string> defines, S32 texture_index_channels = -1);
// Implemented in the application to actually point to the shader directory.
virtual std::string getShaderDirPrefix(void) = 0; // Pure Virtual
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..d5ed667c4d
--- /dev/null
+++ b/indra/newview/llfloaterdebugmaterials.cpp
@@ -0,0 +1,1957 @@
+/**
+* @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 = objectMaterialID.asString();
+ 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 &materialIdLLSD = material.get(MATERIALS_CAP_OBJECT_ID_FIELD);
+ LLMaterialID materialID(materialIdLLSD);
+ std::string materialIDString = materialID.asString();
+
+ 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());
+ LLMaterialID materialID(face.get(MATERIALS_CAP_MATERIAL_ID_FIELD));
+ std::string materialIDString = materialID.asString();
+
+ 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 &materialIdLLSD = material.get(MATERIALS_CAP_OBJECT_ID_FIELD);
+ LLMaterialID materialID(materialIdLLSD);
+ std::string materialIDString = materialID.asString();
+
+ 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;
+ }
+}
+
+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..c5179ef6b0
--- /dev/null
+++ b/indra/newview/llfloaterdebugmaterials.h
@@ -0,0 +1,214 @@
+/**
+* @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();
+
+ 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/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 202be9671b..e74c8509ce 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -71,14 +71,14 @@
BOOL LLPanelFace::postBuild()
{
+ childSetCommitCallback("combobox matmedia",&LLPanelFace::onCommitMaterialsMedia,this);
+ childSetCommitCallback("combobox mattype",&LLPanelFace::onCommitMaterialType,this);
childSetCommitCallback("combobox shininess",&LLPanelFace::onCommitShiny,this);
childSetCommitCallback("combobox bumpiness",&LLPanelFace::onCommitBump,this);
childSetCommitCallback("TexScaleU",&LLPanelFace::onCommitTextureInfo, this);
- childSetCommitCallback("checkbox flip s",&LLPanelFace::onCommitTextureInfo, this);
childSetCommitCallback("TexScaleV",&LLPanelFace::onCommitTextureInfo, this);
- childSetCommitCallback("checkbox flip t",&LLPanelFace::onCommitTextureInfo, this);
childSetCommitCallback("TexRot",&LLPanelFace::onCommitTextureInfo, this);
- childSetAction("button apply",&LLPanelFace::onClickApply,this);
+ childSetCommitCallback("rptctrl",&LLPanelFace::onCommitRepeatsPerMeter, this);
childSetCommitCallback("checkbox planar align",&LLPanelFace::onCommitPlanarAlign, this);
childSetCommitCallback("TexOffsetU",LLPanelFace::onCommitTextureInfo, this);
childSetCommitCallback("TexOffsetV",LLPanelFace::onCommitTextureInfo, this);
@@ -98,6 +98,7 @@ BOOL LLPanelFace::postBuild()
LLSpinCtrl* mCtrlGlow;
setMouseOpaque(FALSE);
+
mTextureCtrl = getChild<LLTextureCtrl>("texture control");
if(mTextureCtrl)
{
@@ -269,22 +270,20 @@ struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor
LLSpinCtrl* ctrlTexOffsetS = mPanel->getChild<LLSpinCtrl>("TexOffsetU");
LLSpinCtrl* ctrlTexOffsetT = mPanel->getChild<LLSpinCtrl>("TexOffsetV");
LLSpinCtrl* ctrlTexRotation = mPanel->getChild<LLSpinCtrl>("TexRot");
- LLCheckBoxCtrl* checkFlipScaleS = mPanel->getChild<LLCheckBoxCtrl>("checkbox flip s");
- LLCheckBoxCtrl* checkFlipScaleT = mPanel->getChild<LLCheckBoxCtrl>("checkbox flip t");
LLComboBox* comboTexGen = mPanel->getChild<LLComboBox>("combobox texgen");
llassert(comboTexGen);
llassert(object);
if (ctrlTexScaleS)
{
- valid = !ctrlTexScaleS->getTentative() || !checkFlipScaleS->getTentative();
+ valid = !ctrlTexScaleS->getTentative(); // || !checkFlipScaleS->getTentative();
if (valid)
{
value = ctrlTexScaleS->get();
- if( checkFlipScaleS->get() )
- {
- value = -value;
- }
+ //if( checkFlipScaleS->get() )
+ //{
+ // value = -value;
+ //}
if (comboTexGen &&
comboTexGen->getCurrentIndex() == 1)
{
@@ -296,14 +295,14 @@ struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor
if (ctrlTexScaleT)
{
- valid = !ctrlTexScaleT->getTentative() || !checkFlipScaleT->getTentative();
+ valid = !ctrlTexScaleT->getTentative(); // || !checkFlipScaleT->getTentative();
if (valid)
{
value = ctrlTexScaleT->get();
- if( checkFlipScaleT->get() )
- {
- value = -value;
- }
+ //if( checkFlipScaleT->get() )
+ //{
+ // value = -value;
+ //}
if (comboTexGen &&
comboTexGen->getCurrentIndex() == 1)
{
@@ -495,6 +494,31 @@ void LLPanelFace::getState()
// only turn on auto-adjust button if there is a media renderer and the media is loaded
getChildView("textbox autofix")->setEnabled(editable);
getChildView("button align")->setEnabled(editable);
+
+ LLCtrlSelectionInterface* combobox_matmedia =
+ childGetSelectionInterface("combobox matmedia");
+ if (combobox_matmedia)
+ {
+ combobox_matmedia->selectNthItem(0);
+ }
+ else
+ {
+ llwarns << "failed childGetSelectionInterface for 'combobox matmedia'" << llendl;
+ }
+ getChildView("combobox matmedia")->setEnabled(editable);
+
+ LLCtrlSelectionInterface* combobox_mattype =
+ childGetSelectionInterface("combobox mattype");
+ if (combobox_mattype)
+ {
+ combobox_mattype->selectNthItem(0);
+ }
+ else
+ {
+ llwarns << "failed childGetSelectionInterface for 'combobox mattype'" << llendl;
+ }
+ getChildView("combobox mattype")->setEnabled(editable);
+ onCommitMaterialsMedia(NULL, this);
//if ( LLMediaEngine::getInstance()->getMediaRenderer () )
// if ( LLMediaEngine::getInstance()->getMediaRenderer ()->isLoaded () )
@@ -504,7 +528,6 @@ void LLPanelFace::getState()
//
// //mBtnAutoFix->setEnabled ( editable );
// }
- getChildView("button apply")->setEnabled(editable);
bool identical;
LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("texture control");
@@ -630,12 +653,9 @@ void LLPanelFace::getState()
} func;
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, scale_s );
identical = align_planar ? identical_planar_aligned : identical;
- getChild<LLUICtrl>("TexScaleU")->setValue(editable ? llabs(scale_s) : 0);
+ getChild<LLUICtrl>("TexScaleU")->setValue(editable ? scale_s : 0);
getChild<LLUICtrl>("TexScaleU")->setTentative(LLSD((BOOL)(!identical)));
getChildView("TexScaleU")->setEnabled(editable);
- getChild<LLUICtrl>("checkbox flip s")->setValue(LLSD((BOOL)(scale_s < 0 ? TRUE : FALSE )));
- getChild<LLUICtrl>("checkbox flip s")->setTentative(LLSD((BOOL)((!identical) ? TRUE : FALSE )));
- getChildView("checkbox flip s")->setEnabled(editable);
}
{
@@ -650,12 +670,9 @@ void LLPanelFace::getState()
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, scale_t );
identical = align_planar ? identical_planar_aligned : identical;
- getChild<LLUICtrl>("TexScaleV")->setValue(llabs(editable ? llabs(scale_t) : 0));
+ getChild<LLUICtrl>("TexScaleV")->setValue(editable ? scale_t : 0);
getChild<LLUICtrl>("TexScaleV")->setTentative(LLSD((BOOL)(!identical)));
getChildView("TexScaleV")->setEnabled(editable);
- getChild<LLUICtrl>("checkbox flip t")->setValue(LLSD((BOOL)(scale_t< 0 ? TRUE : FALSE )));
- getChild<LLUICtrl>("checkbox flip t")->setTentative(LLSD((BOOL)((!identical) ? TRUE : FALSE )));
- getChildView("checkbox flip t")->setEnabled(editable);
}
// Texture offset
@@ -710,6 +727,9 @@ void LLPanelFace::getState()
}
// Color swatch
+ {
+ getChildView("color label")->setEnabled(editable);
+ }
LLColorSwatchCtrl* mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
LLColor4 color = LLColor4::white;
if(mColorSwatch)
@@ -895,7 +915,6 @@ void LLPanelFace::getState()
{
BOOL enabled = editable && (!mComboTexGen || mComboTexGen->getCurrentIndex() != 1);
getChildView("rptctrl")->setEnabled(enabled);
- getChildView("button apply")->setEnabled(enabled);
}
}
@@ -939,7 +958,6 @@ void LLPanelFace::getState()
getChildView("textbox autofix")->setEnabled(FALSE);
getChildView("button align")->setEnabled(FALSE);
- getChildView("button apply")->setEnabled(FALSE);
//getChildView("has media")->setEnabled(FALSE);
//getChildView("media info set")->setEnabled(FALSE);
@@ -995,6 +1013,44 @@ void LLPanelFace::onSelectColor(const LLSD& data)
}
// static
+void LLPanelFace::onCommitMaterialsMedia(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ LLComboBox* mComboMaterialsMedia = self->getChild<LLComboBox>("combobox matmedia");
+ if (!mComboMaterialsMedia)
+ {
+ return;
+ }
+ U32 materials_media = mComboMaterialsMedia->getCurrentIndex();
+ LLComboBox* mComboMaterialType = self->getChild<LLComboBox>("combobox mattype");
+ if (!mComboMaterialType)
+ {
+ return;
+ }
+ U32 material_type = mComboMaterialType->getCurrentIndex();
+ bool show_media = (materials_media == 1);
+ bool show_texture = (!show_media) && (material_type == 0);
+ bool show_bumpiness = (!show_media) && (material_type == 1);
+ bool show_shininess = (!show_media) && (material_type == 2);
+ self->getChildView("combobox mattype")->setVisible(!show_media);
+ self->getChildView("media_info")->setVisible(show_media);
+ self->getChildView("add_media")->setVisible(show_media);
+ self->getChildView("delete_media")->setVisible(show_media);
+ self->getChildView("button align")->setVisible(show_media);
+ self->getChildView("texture control")->setVisible(show_texture);
+ self->getChildView("combobox shininess")->setVisible(show_shininess);
+ self->getChildView("label shininess")->setVisible(show_shininess);
+ self->getChildView("combobox bumpiness")->setVisible(show_bumpiness);
+ self->getChildView("label bumpiness")->setVisible(show_bumpiness);
+}
+
+// static
+void LLPanelFace::onCommitMaterialType(LLUICtrl* ctrl, void* userdata)
+{
+ onCommitMaterialsMedia(ctrl, userdata);
+}
+
+// static
void LLPanelFace::onCommitBump(LLUICtrl* ctrl, void* userdata)
{
LLPanelFace* self = (LLPanelFace*) userdata;
@@ -1074,7 +1130,7 @@ void LLPanelFace::onCommitTextureInfo( LLUICtrl* ctrl, void* userdata )
// Commit the number of repeats per meter
// static
-void LLPanelFace::onClickApply(void* userdata)
+void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* ctrl, void* userdata)
{
LLPanelFace* self = (LLPanelFace*) userdata;
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index 3b5a9b1398..acac2c1bf5 100644
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -80,6 +80,8 @@ protected:
void onSelectColor(const LLSD& data);
static void onCommitTextureInfo( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialsMedia( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialType( LLUICtrl* ctrl, void* userdata);
static void onCommitBump( LLUICtrl* ctrl, void* userdata);
static void onCommitTexGen( LLUICtrl* ctrl, void* userdata);
static void onCommitShiny( LLUICtrl* ctrl, void* userdata);
@@ -87,7 +89,7 @@ protected:
static void onCommitGlow( LLUICtrl* ctrl, void *userdata);
static void onCommitPlanarAlign( LLUICtrl* ctrl, void* userdata);
- static void onClickApply(void*);
+ static void onCommitRepeatsPerMeter( LLUICtrl* ctrl, void* userinfo);
static void onClickAutoFix(void*);
static F32 valueGlow(LLViewerObject* object, S32 face);
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..afa93c3618
--- /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="770"
+ width="1040"
+ min_height="795"
+ 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="670"
+ 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="457"
+ 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/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
index 5204efbf65..3b501e1ece 100644
--- a/indra/newview/skins/default/xui/en/floater_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -2,7 +2,7 @@
<floater
positioning="cascading"
legacy_header_height="18"
- height="590"
+ height="615"
layout="topleft"
bg_opaque_image="Window_NoTitle_Foreground"
bg_alpha_image="Window_NoTitle_Background"
@@ -830,7 +830,7 @@
width="282"/>
<tab_container
follows="left|top"
- height="410"
+ height="435"
halign="center"
left="0"
name="Object Info Tabs"
@@ -1353,7 +1353,7 @@ even though the user gets a free copy.
<panel
border="false"
follows="all"
- height="567"
+ height="592"
label="Object"
layout="topleft"
left_delta="0"
@@ -2110,7 +2110,7 @@ even though the user gets a free copy.
<panel
border="false"
follows="all"
- height="367"
+ height="392"
label="Features"
layout="topleft"
left_delta="0"
@@ -2491,534 +2491,10 @@ even though the user gets a free copy.
width="132" />
</panel>
<panel
- border="false"
- follows="all"
- height="367"
label="Texture"
- layout="topleft"
- left_delta="0"
- mouse_opaque="false"
help_topic="toolbox_texture_tab"
name="Texture"
- top_delta="0"
- width="295">
- <panel.string
- name="string repeats per meter">
- Repeats Per Meter
- </panel.string>
- <panel.string
- name="string repeats per face">
- Repeats Per Face
- </panel.string>
- <texture_picker
- can_apply_immediately="true"
- default_image_name="Default"
- fallback_image="locked_image.j2c"
- follows="left|top"
- height="80"
- label="Texture"
- layout="topleft"
- left="10"
- name="texture control"
- tool_tip="Click to choose a picture"
- top="8"
- width="64" />
- <color_swatch
- can_apply_immediately="true"
- follows="left|top"
- height="80"
- label="Color"
- layout="topleft"
- left_pad="15"
- name="colorswatch"
- tool_tip="Click to open color picker"
- top_delta="0"
- width="64" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left_pad="15"
- name="color trans"
- text_readonly_color="LabelDisabledColor"
- top="6"
- width="110">
- Transparency %
- </text>
- <spinner
- decimal_digits="0"
- follows="left|top"
- height="19"
- increment="2"
- initial_value="0"
- layout="topleft"
- left_delta="0"
- max_val="100"
- name="ColorTrans"
- top_pad="4"
- width="80" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left_delta="0"
- name="glow label"
- text_readonly_color="LabelDisabledColor"
- top_pad="8"
- width="80">
- Glow
- </text>
- <spinner
- decimal_digits="2"
- follows="left|top"
- height="19"
- initial_value="0"
- layout="topleft"
- left_delta="0"
- name="glow"
- top_pad="4"
- width="80" />
- <check_box
- height="19"
- label="Full Bright"
- layout="topleft"
- left_delta="-5"
- name="checkbox fullbright"
- top_pad="4"
- width="81" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left="10"
- name="tex gen"
- text_readonly_color="LabelDisabledColor"
- top_pad="5"
- width="90">
- Mapping
- </text>
- <combo_box
- height="23"
- layout="topleft"
- left_delta="0"
- name="combobox texgen"
- top_pad="4"
- width="90">
- <combo_box.item
- label="Default"
- name="Default"
- value="Default" />
- <combo_box.item
- label="Planar"
- name="Planar"
- value="Planar" />
- </combo_box>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- name="label shininess"
- left_pad="4"
- text_readonly_color="LabelDisabledColor"
- top_pad="-37"
- width="90">
- Shininess
- </text>
- <combo_box
- height="23"
- layout="topleft"
- left_delta="0"
- name="combobox shininess"
- top_pad="4"
- width="90">
- <combo_box.item
- label="None"
- name="None"
- value="None" />
- <combo_box.item
- label="Low"
- name="Low"
- value="Low" />
- <combo_box.item
- label="Medium"
- name="Medium"
- value="Medium" />
- <combo_box.item
- label="High"
- name="High"
- value="High" />
- </combo_box>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left_pad="4"
- name="label bumpiness"
- text_readonly_color="LabelDisabledColor"
- top_pad="-37"
- width="90">
- Bumpiness
- </text>
- <combo_box
- height="23"
- layout="topleft"
- left_delta="0"
- name="combobox bumpiness"
- top_pad="4"
- width="90">
- <combo_box.item
- label="None"
- name="None"
- value="None" />
- <combo_box.item
- label="Brightness"
- name="Brightness"
- value="Brightness" />
- <combo_box.item
- label="Darkness"
- name="Darkness"
- value="Darkness" />
- <combo_box.item
- label="woodgrain"
- name="woodgrain"
- value="woodgrain" />
- <combo_box.item
- label="bark"
- name="bark"
- value="bark" />
- <combo_box.item
- label="bricks"
- name="bricks"
- value="bricks" />
- <combo_box.item
- label="checker"
- name="checker"
- value="checker" />
- <combo_box.item
- label="concrete"
- name="concrete"
- value="concrete" />
- <combo_box.item
- label="crustytile"
- name="crustytile"
- value="crustytile" />
- <combo_box.item
- label="cutstone"
- name="cutstone"
- value="cutstone" />
- <combo_box.item
- label="discs"
- name="discs"
- value="discs" />
- <combo_box.item
- label="gravel"
- name="gravel"
- value="gravel" />
- <combo_box.item
- label="petridish"
- name="petridish"
- value="petridish" />
- <combo_box.item
- label="siding"
- name="siding"
- value="siding" />
- <combo_box.item
- label="stonetile"
- name="stonetile"
- value="stonetile" />
- <combo_box.item
- label="stucco"
- name="stucco"
- value="stucco" />
- <combo_box.item
- label="suction"
- name="suction"
- value="suction" />
- <combo_box.item
- label="weave"
- name="weave"
- value="weave" />
- </combo_box>
- <!--
- <line_editor
- bevel_style="in"
- border_style="line"
- border_thickness="1"
- follows="left|top"
- height="16"
- layout="topleft"
- left="10"
- max_length_bytes="63"
- name="Home Url"
- select_on_focus="true"
- top="134"
- width="250" />
- <check_box
- height="16"
- label="Media Face"
- layout="topleft"
- left_delta="0"
- name="has media"
- top_pad="6"
- width="70" />
- <button
- follows="left|top"
- font="SansSerifSmall"
- height="20"
- label="Set Media Info"
- label_selected="Set Media Info"
- layout="topleft"
- left_pad="60"
- name="media info set"
- top_delta="-4"
- width="120" />
--->
- <check_box
- follows="top|left"
- height="16"
- initial_value="false"
- label="Align planar faces"
- layout="topleft"
- left="17"
- name="checkbox planar align"
- tool_tip="Align textures on all selected faces with the last selected face. Requires Planar texture mapping."
- top_delta="26"
- width="140" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left="10"
- name="rpt"
- text_readonly_color="LabelDisabledColor"
- top_pad="2"
- width="140">
- Repeats / Face
- </text>
- <spinner
- follows="left|top"
- height="19"
- initial_value="0"
- label="Horizontal (U)"
- label_width="125"
- layout="topleft"
- left="20"
- max_val="100"
- name="TexScaleU"
- top_pad="5"
- width="185" />
- <check_box
- height="19"
- label="Flip"
- layout="topleft"
- left_pad="5"
- name="checkbox flip s"
- top_delta="0"
- width="70" />
- <spinner
- follows="left|top"
- height="19"
- initial_value="0"
- label="Vertical (V)"
- label_width="125"
- layout="topleft"
- left="20"
- max_val="100"
- name="TexScaleV"
- width="185" />
- <check_box
- height="19"
- label="Flip"
- layout="topleft"
- left_pad="5"
- name="checkbox flip t"
- top_delta="0"
- width="70" />
- <spinner
- decimal_digits="2"
- follows="left|top"
- height="19"
- increment="1"
- initial_value="0"
- label="RotationĖš"
- layout="topleft"
- label_width="135"
- left="10"
- max_val="9999"
- min_val="-9999"
- name="TexRot"
- width="195" />
-
- <spinner
- decimal_digits="1"
- follows="left|top"
- height="23"
- initial_value="1"
- label="Repeats / Meter"
- layout="topleft"
- label_width="135"
- left="10"
- max_val="10"
- min_val="0.1"
- name="rptctrl"
- width="195" />
- <button
- follows="left|top"
- height="23"
- label="Apply"
- label_selected="Apply"
- layout="topleft"
- left_pad="5"
- name="button apply"
- width="75" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left="10"
- name="tex offset"
- text_readonly_color="LabelDisabledColor"
- width="200">
- Texture Offset
- </text>
- <spinner
- follows="left|top"
- height="19"
- initial_value="0"
- label="Horizontal (U)"
- label_width="125"
- layout="topleft"
- left="20"
- min_val="-1"
- name="TexOffsetU"
- width="185" />
- <spinner
- follows="left|top"
- height="19"
- initial_value="0"
- label="Vertical (V)"
- label_width="125"
- layout="topleft"
- left_delta="0"
- min_val="-1"
- name="TexOffsetV"
- top_pad="1"
- width="185" />
- <panel
- border="false"
- follows="left|top"
- layout="topleft"
- mouse_opaque="false"
- background_visible="true"
- bg_alpha_color="DkGray"
- name="Add_Media"
- left="0"
- height="47"
- width="290">
- <text
- type="string"
- length="1"
- follows="left|top"
- height="18"
- layout="topleft"
- left="10"
- top_pad="3"
- name="media_tex"
- width="190">
- Media
- </text>
- <button
- follows="top|left"
- height="18"
- image_selected="AddItem_Press"
- image_unselected="AddItem_Off"
- image_disabled="AddItem_Disabled"
- layout="topleft"
- left_pad="0"
- name="add_media"
- tab_stop="false"
- top_delta="0"
- tool_tip="Add Media"
- width="18">
- <button.commit_callback
- function="BuildTool.AddMedia"/>
- </button>
- <button
- follows="top|left"
- height="18"
- image_selected="TrashItem_Press"
- image_unselected="TrashItem_Off"
- layout="topleft"
- left_pad="5"
- name="delete_media"
- tool_tip="Delete this media texture"
- top_delta="0"
- width="18">
- <button.commit_callback
- function="BuildTool.DeleteMedia"/>
- </button>
- <button
- follows="top|left"
- tool_tip="Edit this Media"
- height="12"
- image_disabled="Icon_Gear_Background"
- image_selected="Icon_Gear_Press"
- image_unselected="Icon_Gear_Foreground"
- layout="topleft"
- left_pad="10"
- name="edit_media"
- top_delta="3"
- width="12">
- <button.commit_callback
- function="BuildTool.EditMedia"/>
- </button>
- <text
- follows="left|top|right"
- height="9"
- layout="topleft"
- left="10"
- use_ellipses="true"
- read_only="true"
- name="media_info"
- width="280" />
- <web_browser
- visible="false"
- enabled="false"
- border_visible="true"
- bottom_delta="0"
- follows="top|left"
- left="0"
- name="title_media"
- width="4"
- height="4"
- start_url="about:blank"
- decouple_texture_size="true" />
- <button
- follows="right|top"
- height="22"
- label="Align"
- label_selected="Align Media"
- layout="topleft"
- right="-16"
- name="button align"
- top_delta="-4"
- tool_tip="Align media texture (must load first)"
- width="80" />
- </panel>
+ filename="panel_tools_texture.xml">
</panel>
<panel
border="false"
@@ -3054,7 +2530,7 @@ even though the user gets a free copy.
border_visible="true"
bevel_style="in"
follows="left|top|right"
- height="325"
+ height="350"
layout="topleft"
left="10"
name="contents_inventory"
@@ -3064,7 +2540,7 @@ even though the user gets a free copy.
</tab_container>
<panel
follows="left|top"
- height="384"
+ height="409"
layout="topleft"
left_delta="0"
name="land info panel"
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/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml
new file mode 100644
index 0000000000..26b2d83351
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml
@@ -0,0 +1,483 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ border="false"
+ follows="all"
+ height="400"
+ label="Texture"
+ layout="topleft"
+ left="0"
+ mouse_opaque="false"
+ help_topic="toolbox_texture_tab"
+ name="Texture"
+ top="0"
+ width="295">
+ <panel.string
+ name="string repeats per meter">
+ Repeats Per Meter
+ </panel.string>
+ <panel.string
+ name="string repeats per face">
+ Repeats Per Face
+ </panel.string>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ name="color label"
+ text_readonly_color="LabelDisabledColor"
+ top="6"
+ width="64">
+ Color
+ </text>
+ <!-- label is blank because control places it below the box -->
+ <color_swatch
+ can_apply_immediately="true"
+ follows="left|top"
+ height="45"
+ label=""
+ layout="topleft"
+ left="10"
+ name="colorswatch"
+ tool_tip="Click to open color picker"
+ top="20"
+ width="64" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="15"
+ name="color trans"
+ text_readonly_color="LabelDisabledColor"
+ top="6"
+ width="110">
+ Transparency %
+ </text>
+ <spinner
+ decimal_digits="0"
+ follows="left|top"
+ height="19"
+ increment="2"
+ initial_value="0"
+ layout="topleft"
+ left_delta="0"
+ max_val="100"
+ name="ColorTrans"
+ top_pad="4"
+ width="80" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="15"
+ name="glow label"
+ text_readonly_color="LabelDisabledColor"
+ top="6"
+ width="80">
+ Glow
+ </text>
+ <spinner
+ decimal_digits="2"
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ layout="topleft"
+ left_delta="0"
+ name="glow"
+ top_pad="4"
+ width="80" />
+ <check_box
+ height="19"
+ label="Full Bright"
+ layout="topleft"
+ left="7"
+ name="checkbox fullbright"
+ top_pad="4"
+ width="81" />
+ <combo_box
+ height="23"
+ layout="topleft"
+ left="10"
+ name="combobox matmedia"
+ top_pad="5"
+ width="100">
+ <combo_box.item
+ label="Materials"
+ name="Materials"
+ value="Materials" />
+ <combo_box.item
+ label="Media"
+ name="Media"
+ value="Media" />
+ </combo_box>
+ <combo_box
+ height="23"
+ layout="topleft"
+ left_pad="10"
+ name="combobox mattype"
+ top_delta="0"
+ width="155">
+ <combo_box.item
+ label="Texture (diffuse)"
+ name="Texture (diffuse)"
+ value="Texture (diffuse)" />
+ <combo_box.item
+ label="Bumpiness (normal)"
+ name="Bumpiness (normal)"
+ value="Bumpiness (normal)" />
+ <combo_box.item
+ label="Shininess (specular)"
+ name="Shininess (specular)"
+ value="Shininess (specular)" />
+ </combo_box>
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ fallback_image="locked_image.j2c"
+ follows="left|top"
+ height="80"
+ label="Texture "
+ layout="topleft"
+ left="10"
+ name="texture control"
+ tool_tip="Click to choose a picture"
+ top_pad="8"
+ width="64" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ name="label shininess"
+ left_pad="10"
+ text_readonly_color="LabelDisabledColor"
+ top_delta="6"
+ width="90">
+ Shininess
+ </text>
+ <combo_box
+ height="23"
+ layout="topleft"
+ left_pad="10"
+ name="combobox shininess"
+ top_delta="-6"
+ width="90">
+ <combo_box.item
+ label="None"
+ name="None"
+ value="None" />
+ <combo_box.item
+ label="Low"
+ name="Low"
+ value="Low" />
+ <combo_box.item
+ label="Medium"
+ name="Medium"
+ value="Medium" />
+ <combo_box.item
+ label="High"
+ name="High"
+ value="High" />
+ </combo_box>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-100"
+ name="label bumpiness"
+ text_readonly_color="LabelDisabledColor"
+ top_delta="0"
+ width="90">
+ Bumpiness
+ </text>
+ <combo_box
+ height="23"
+ layout="topleft"
+ left_delta="0"
+ name="combobox bumpiness"
+ top_pad="4"
+ width="90">
+ <combo_box.item
+ label="None"
+ name="None"
+ value="None" />
+ <combo_box.item
+ label="Brightness"
+ name="Brightness"
+ value="Brightness" />
+ <combo_box.item
+ label="Darkness"
+ name="Darkness"
+ value="Darkness" />
+ <combo_box.item
+ label="woodgrain"
+ name="woodgrain"
+ value="woodgrain" />
+ <combo_box.item
+ label="bark"
+ name="bark"
+ value="bark" />
+ <combo_box.item
+ label="bricks"
+ name="bricks"
+ value="bricks" />
+ <combo_box.item
+ label="checker"
+ name="checker"
+ value="checker" />
+ <combo_box.item
+ label="concrete"
+ name="concrete"
+ value="concrete" />
+ <combo_box.item
+ label="crustytile"
+ name="crustytile"
+ value="crustytile" />
+ <combo_box.item
+ label="cutstone"
+ name="cutstone"
+ value="cutstone" />
+ <combo_box.item
+ label="discs"
+ name="discs"
+ value="discs" />
+ <combo_box.item
+ label="gravel"
+ name="gravel"
+ value="gravel" />
+ <combo_box.item
+ label="petridish"
+ name="petridish"
+ value="petridish" />
+ <combo_box.item
+ label="siding"
+ name="siding"
+ value="siding" />
+ <combo_box.item
+ label="stonetile"
+ name="stonetile"
+ value="stonetile" />
+ <combo_box.item
+ label="stucco"
+ name="stucco"
+ value="stucco" />
+ <combo_box.item
+ label="suction"
+ name="suction"
+ value="suction" />
+ <combo_box.item
+ label="weave"
+ name="weave"
+ value="weave" />
+ </combo_box>
+ <text
+ follows="left|top|right"
+ height="9"
+ layout="topleft"
+ left="10"
+ top_delta="-8"
+ use_ellipses="true"
+ read_only="true"
+ name="media_info"
+ width="280">
+ URL of chosen media, if any, goes here
+ </text>
+ <button
+ follows="top|left"
+ height="18"
+ layout="topleft"
+ left="10"
+ name="add_media"
+ top_pad="4"
+ tool_tip="Add Media"
+ label="Choose..."
+ width="85">
+ <button.commit_callback
+ function="BuildTool.AddMedia"/>
+ </button>
+ <button
+ follows="top|left"
+ height="18"
+ layout="topleft"
+ left_pad="5"
+ name="delete_media"
+ tool_tip="Delete this media texture"
+ top_delta="0"
+ label="Remove"
+ width="85">
+ <button.commit_callback
+ function="BuildTool.DeleteMedia"/>
+ </button>
+ <button
+ follows="left|top"
+ height="18"
+ label="Align"
+ label_selected="Align Media"
+ layout="topleft"
+ left_pad="5"
+ name="button align"
+ top_delta="0"
+ tool_tip="Align media texture (must load first)"
+ width="85" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ name="tex gen"
+ text_readonly_color="LabelDisabledColor"
+ top_pad="60"
+ width="140">
+ Mapping
+ </text>
+ <combo_box
+ height="23"
+ layout="topleft"
+ left_pad="0"
+ name="combobox texgen"
+ top_pad="-13"
+ width="125">
+ <combo_box.item
+ label="Default"
+ name="Default"
+ value="Default" />
+ <combo_box.item
+ label="Planar"
+ name="Planar"
+ value="Planar" />
+ </combo_box>
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Horizontal scale"
+ label_width="205"
+ layout="topleft"
+ left="10"
+ min_val="-100"
+ max_val="100"
+ name="TexScaleU"
+ top_pad="5"
+ width="265" />
+ <!-- <check_box
+ height="19"
+ label="Flip"
+ layout="topleft"
+ left_pad="5"
+ name="checkbox flip s"
+ top_delta="0"
+ width="70" /> -->
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Vertical scale"
+ label_width="205"
+ layout="topleft"
+ left="10"
+ min_val="-100"
+ max_val="100"
+ name="TexScaleV"
+ width="265" />
+ <!-- <check_box
+ height="19"
+ label="Flip"
+ layout="topleft"
+ left_pad="5"
+ name="checkbox flip t"
+ top_delta="0"
+ width="70" /> -->
+ <spinner
+ decimal_digits="1"
+ follows="left|top"
+ height="19"
+ initial_value=""
+ label="Repeats per meter"
+ layout="topleft"
+ label_width="205"
+ left="10"
+ max_val="10"
+ min_val="0.1"
+ name="rptctrl"
+ width="265" />
+ <!-- <button
+ follows="left|top"
+ height="19"
+ label="Apply"
+ label_selected="Apply"
+ layout="topleft"
+ left_pad="5"
+ name="button apply"
+ width="75" /> -->
+ <spinner
+ decimal_digits="2"
+ follows="left|top"
+ height="19"
+ increment="1"
+ initial_value="0"
+ label="Rotation degrees"
+ layout="topleft"
+ label_width="205"
+ left="10"
+ max_val="9999"
+ min_val="-9999"
+ name="TexRot"
+ width="265" />
+
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Horizontal offset"
+ label_width="205"
+ layout="topleft"
+ left="10"
+ min_val="-1"
+ name="TexOffsetU"
+ width="265" />
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Vertical offset"
+ label_width="205"
+ layout="topleft"
+ left="10"
+ min_val="-1"
+ name="TexOffsetV"
+ width="265" />
+ <check_box
+ follows="top|left"
+ height="16"
+ initial_value="false"
+ label="Align planar faces"
+ layout="topleft"
+ left="7"
+ name="checkbox planar align"
+ tool_tip="Align textures on all selected faces with the last selected face. Requires Planar texture mapping."
+ top_delta="26"
+ width="260" />
+ <web_browser
+ visible="false"
+ enabled="false"
+ border_visible="true"
+ bottom_delta="0"
+ follows="top|left"
+ left="0"
+ name="title_media"
+ width="4"
+ height="4"
+ start_url="about:blank"
+ decouple_texture_size="true" />
+ </panel>
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