diff options
38 files changed, 4361 insertions, 614 deletions
diff --git a/BuildParams b/BuildParams index c8edfeaa2f..bb8e2c52a0 100644 --- a/BuildParams +++ b/BuildParams @@ -127,6 +127,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/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 ab45bd3d3b..24144382dc 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() : @@ -901,7 +901,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) { @@ -1246,6 +1246,11 @@ void LLPipeline::createGLBuffers() gBumpImageList.restoreGL(); } +F32 lerpf(F32 a, F32 b, F32 w) +{ + return a + w * (b - a); +} + void LLPipeline::createLUTBuffers() { if (sRenderDeferred) @@ -1254,45 +1259,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 |