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 | 
