summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorKitty Barnett <develop@catznip.com>2012-12-03 01:46:26 +0100
committerKitty Barnett <develop@catznip.com>2012-12-03 01:46:26 +0100
commit1e26dbdcd27a1f29fe249cc7e074e5ede284bac8 (patch)
tree8580d1b1919b5b350adea0480aa88e7569bd78cc /indra
parenta0392ec5ec5703bd54bc4e091820d1c1423bbad4 (diff)
Started LLMaterialMgr to handle viewer<->region materials communication
* refactored LLFloaterDebugMaterials::requestPutMaterials() to use LLMaterialMgr instead * replaced "Object editing" results list with information about the active selection instead
Diffstat (limited to 'indra')
-rw-r--r--indra/llprimitive/llmaterial.cpp18
-rw-r--r--indra/llprimitive/llmaterial.h3
-rwxr-xr-xindra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/llfloaterdebugmaterials.cpp182
-rw-r--r--indra/newview/llfloaterdebugmaterials.h4
-rw-r--r--indra/newview/llmaterialmgr.cpp270
-rw-r--r--indra/newview/llmaterialmgr.h53
-rw-r--r--indra/newview/skins/default/xui/en/floater_debug_materials.xml8
8 files changed, 402 insertions, 138 deletions
diff --git a/indra/llprimitive/llmaterial.cpp b/indra/llprimitive/llmaterial.cpp
index b07b4ce72d..da518b6916 100644
--- a/indra/llprimitive/llmaterial.cpp
+++ b/indra/llprimitive/llmaterial.cpp
@@ -82,6 +82,8 @@ template<typename T> T getMaterialField(const LLSD& data, const std::string& fie
* LLMaterial class
*/
+const LLMaterial LLMaterial::null;
+
LLMaterial::LLMaterial()
: mSpecularLightColor(MATERIALS_DEFAULT_SPECULAR_COLOR)
, mSpecularLightExponent(MATERIALS_DEFAULT_SPECULAR_EXP)
@@ -117,8 +119,8 @@ LLSD LLMaterial::asLLSD() const
material_data[MATERIALS_CAP_SPECULAR_COLOR_FIELD] = mSpecularLightColor.getValue();
material_data[MATERIALS_CAP_SPECULAR_EXP_FIELD] = mSpecularLightExponent;
material_data[MATERIALS_CAP_ENV_INTENSITY_FIELD] = mEnvironmentIntensity;
- material_data[MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD] = mDiffuseAlphaMode;
- material_data[MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD] = mAlphaMaskCutoff;
+ material_data[MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD] = mDiffuseAlphaMode;
+ material_data[MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD] = mAlphaMaskCutoff;
return material_data;
}
@@ -142,6 +144,14 @@ void LLMaterial::fromLLSD(const LLSD& material_data)
mSpecularLightColor.setValue(getMaterialField<LLSD>(material_data, MATERIALS_CAP_SPECULAR_COLOR_FIELD, LLSD::TypeArray));
mSpecularLightExponent = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_EXP_FIELD, LLSD::TypeInteger);
mEnvironmentIntensity = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_ENV_INTENSITY_FIELD, LLSD::TypeInteger);
- mDiffuseAlphaMode = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD, LLSD::TypeInteger);
- mAlphaMaskCutoff = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD, LLSD::TypeInteger);
+ mDiffuseAlphaMode = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD, LLSD::TypeInteger);
+ mAlphaMaskCutoff = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD, LLSD::TypeInteger);
+}
+
+bool LLMaterial::isNull() const
+{
+ // *TODO: find a better way of defining a 'null' material?
+ return
+ (mNormalID.isNull()) && (.0f == mNormalOffsetX) && (.0f == mNormalOffsetY) && (.0f == mNormalRepeatX) && (.0f == mNormalRepeatY) &&
+ (mSpecularID.isNull()) && (.0f == mSpecularOffsetX) && (.0f == mSpecularOffsetY) && (.0f == mSpecularRepeatX) && (.0f == mSpecularRepeatY);
}
diff --git a/indra/llprimitive/llmaterial.h b/indra/llprimitive/llmaterial.h
index d50ab30195..42e3dd04b9 100644
--- a/indra/llprimitive/llmaterial.h
+++ b/indra/llprimitive/llmaterial.h
@@ -69,6 +69,9 @@ public:
U8 getAlphaMaskCutoff() const { return mAlphaMaskCutoff; }
void setAlphaMaskCutoff(U8 cutoff) { mAlphaMaskCutoff = cutoff; }
+ bool isNull() const;
+ static const LLMaterial null;
+
protected:
LLUUID mNormalID;
F32 mNormalOffsetX;
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 746703db66..3e99bd2551 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -335,6 +335,7 @@ set(viewer_SOURCE_FILES
llmaniptranslate.cpp
llmarketplacefunctions.cpp
llmarketplacenotifications.cpp
+ llmaterialmgr.cpp
llmediactrl.cpp
llmediadataclient.cpp
llmemoryview.cpp
@@ -913,6 +914,7 @@ set(viewer_HEADER_FILES
llmaniptranslate.h
llmarketplacefunctions.h
llmarketplacenotifications.h
+ llmaterialmgr.h
llmediactrl.h
llmediadataclient.h
llmemoryview.h
diff --git a/indra/newview/llfloaterdebugmaterials.cpp b/indra/newview/llfloaterdebugmaterials.cpp
index 7b3ad7aa13..f69dd6214c 100644
--- a/indra/newview/llfloaterdebugmaterials.cpp
+++ b/indra/newview/llfloaterdebugmaterials.cpp
@@ -48,6 +48,7 @@
#include "lllineeditor.h"
#include "llmaterial.h"
#include "llmaterialid.h"
+#include "llmaterialmgr.h"
#include "llresmgr.h"
#include "llscrolllistcell.h"
#include "llscrolllistctrl.h"
@@ -76,11 +77,8 @@
#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 MULTI_MATERIALS_STATUS_FIELD "status"
#define MULTI_MATERIALS_DATA_FIELD "data"
@@ -292,7 +290,6 @@ void LLFloaterDebugMaterials::onOpen(const LLSD& pKey)
checkRegionMaterialStatus();
resetObjectEditInputs();
clearGetResults();
- clearPutResults();
clearViewableObjectsResults();
clearPostResults();
}
@@ -301,7 +298,6 @@ void LLFloaterDebugMaterials::onClose(bool pIsAppQuitting)
{
resetObjectEditInputs();
clearGetResults();
- clearPutResults();
clearViewableObjectsResults();
clearPostResults();
@@ -333,6 +329,10 @@ void LLFloaterDebugMaterials::draw()
{
parseQueryViewableObjects();
}
+ if (LLSelectMgr::instance().getSelection().notNull())
+ {
+ refreshObjectEdit();
+ }
LLFloater::draw();
}
@@ -446,7 +446,6 @@ void LLFloaterDebugMaterials::onRegionCross()
{
checkRegionMaterialStatus();
clearGetResults();
- clearPutResults();
clearViewableObjectsResults();
clearPostResults();
}
@@ -580,19 +579,6 @@ void LLFloaterDebugMaterials::onGetResponse(bool pRequestStatus, const LLSD& pCo
}
}
-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)
@@ -717,16 +703,9 @@ void LLFloaterDebugMaterials::requestPutMaterials(bool pIsDoSet)
}
else
{
- setState(kRequestStarted);
+ setState(kReady);
- LLSD facesData = LLSD::emptyArray();
-
- LLSD materialData = LLSD::emptyMap();
- if (pIsDoSet)
- {
- LLMaterial material = getMaterial();
- materialData = material.asLLSD();
- }
+ LLMaterial material = (pIsDoSet) ? getMaterial() : LLMaterial::null;
LLObjectSelectionHandle selectionHandle = LLSelectMgr::getInstance()->getEditSelection();
for (LLObjectSelection::valid_iterator objectIter = selectionHandle->valid_begin();
@@ -747,41 +726,13 @@ void LLFloaterDebugMaterials::requestPutMaterials(bool pIsDoSet)
{
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);
+ LLMaterialMgr::instance().put(viewerObject->getID(), curTEIndex, material);
}
}
}
}
- 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);
- }
+ LLMaterialMgr::instance().processPutQueue();
}
}
}
@@ -1149,70 +1100,6 @@ void LLFloaterDebugMaterials::parseGetResponse()
}
}
-void LLFloaterDebugMaterials::parsePutResponse(const LLSD& pContent)
-{
- clearPutResults();
-
- LLScrollListCell::Params cellParams;
- LLScrollListItem::Params rowParams;
-
- llassert(pContent.isMap());
- llassert(pContent.has(MATERIALS_CAP_ZIP_FIELD));
- llassert(pContent.get(MATERIALS_CAP_ZIP_FIELD).isBinary());
-
- LLSD::Binary responseBinary = pContent.get(MATERIALS_CAP_ZIP_FIELD).asBinary();
- S32 responseSize = static_cast<S32>(responseBinary.size());
- std::string responseString(reinterpret_cast<const char*>(responseBinary.data()), responseSize);
-
- std::istringstream responseStream(responseString);
-
- LLSD responseContent;
- if (!unzip_llsd(responseContent, responseStream, responseSize))
- {
- LL_ERRS("debugMaterials") << "cannot unzip LLSD binary content" << LL_ENDL;
- }
- else
- {
- llassert(responseContent.isArray());
- for (LLSD::array_const_iterator faceIter = responseContent.beginArray(); faceIter != responseContent.endArray();
- ++faceIter)
- {
- const LLSD &face = *faceIter;
- llassert(face.isMap());
-
- llassert(face.has(MATERIALS_CAP_FACE_FIELD));
- llassert(face.get(MATERIALS_CAP_FACE_FIELD).isInteger());
- S32 faceId = face.get(MATERIALS_CAP_FACE_FIELD).asInteger();
-
- llassert(face.has(MATERIALS_CAP_OBJECT_ID_FIELD));
- llassert(face.get(MATERIALS_CAP_OBJECT_ID_FIELD).isInteger());
- S32 objectId = face.get(MATERIALS_CAP_OBJECT_ID_FIELD).asInteger();
-
- llassert(face.has(MATERIALS_CAP_MATERIAL_ID_FIELD));
- llassert(face.get(MATERIALS_CAP_MATERIAL_ID_FIELD).isBinary());
- std::string materialIDString = convertToPrintableMaterialID(face.get(MATERIALS_CAP_MATERIAL_ID_FIELD));
-
- cellParams.font = LLFontGL::getFontMonospace();
-
- cellParams.column = "material_id";
- cellParams.value = materialIDString;
- rowParams.columns.add(cellParams);
-
- cellParams.font = LLFontGL::getFontSansSerif();
-
- cellParams.column = "object_id";
- cellParams.value = llformat("%d", objectId);
- rowParams.columns.add(cellParams);
-
- cellParams.column = "face_index";
- cellParams.value = llformat("%d", faceId);
- rowParams.columns.add(cellParams);
-
- mPutScrollList->addRow(rowParams);
- }
- }
-}
-
void LLFloaterDebugMaterials::parsePostResponse(const LLSD& pMultiContent)
{
clearPostResults();
@@ -1374,6 +1261,52 @@ void LLFloaterDebugMaterials::setState(EState pState)
updateControls();
}
+void LLFloaterDebugMaterials::refreshObjectEdit()
+{
+ mPutScrollList->deleteAllItems();
+
+ LLScrollListCell::Params cellParams;
+ LLScrollListItem::Params rowParams;
+
+ LLObjectSelectionHandle selectionHandle = LLSelectMgr::getInstance()->getEditSelection();
+ for (LLObjectSelection::valid_iterator objectIter = selectionHandle->valid_begin();
+ objectIter != selectionHandle->valid_end(); ++objectIter)
+ {
+ LLSelectNode* nodep = *objectIter;
+
+ LLViewerObject* objectp = nodep->getObject();
+ if (objectp != NULL)
+ {
+ S32 numTEs = llmin(static_cast<S32>(objectp->getNumTEs()), objectp->getNumFaces());
+ for (S32 curTEIndex = 0; curTEIndex < numTEs; ++curTEIndex)
+ {
+ if (nodep->isTESelected(curTEIndex))
+ {
+ const LLTextureEntry* tep = objectp->getTE(curTEIndex);
+
+ cellParams.font = LLFontGL::getFontMonospace();
+
+ cellParams.column = "material_id";
+ cellParams.value = tep->getMaterialID().asString();
+ rowParams.columns.add(cellParams);
+
+ cellParams.font = LLFontGL::getFontSansSerif();
+
+ cellParams.column = "object_id";
+ cellParams.value = objectp->getID().asString();
+ rowParams.columns.add(cellParams);
+
+ cellParams.column = "face_index";
+ cellParams.value = llformat("%d", curTEIndex);
+ rowParams.columns.add(cellParams);
+
+ mPutScrollList->addRow(rowParams);
+ }
+ }
+ }
+ }
+}
+
void LLFloaterDebugMaterials::resetObjectEditInputs()
{
const LLSD zeroValue = static_cast<LLSD::Integer>(0);
@@ -1409,11 +1342,6 @@ void LLFloaterDebugMaterials::clearGetResults()
clearUnparsedGetData();
}
-void LLFloaterDebugMaterials::clearPutResults()
-{
- mPutScrollList->deleteAllItems();
-}
-
void LLFloaterDebugMaterials::clearPostResults()
{
mPostNormalMapScrollList->deleteAllItems();
diff --git a/indra/newview/llfloaterdebugmaterials.h b/indra/newview/llfloaterdebugmaterials.h
index 572b17af27..920bc4ae6d 100644
--- a/indra/newview/llfloaterdebugmaterials.h
+++ b/indra/newview/llfloaterdebugmaterials.h
@@ -96,7 +96,6 @@ private:
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();
@@ -111,16 +110,15 @@ private:
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 refreshObjectEdit();
void resetObjectEditInputs();
void clearGetResults();
- void clearPutResults();
void clearPostResults();
void clearViewableObjectsResults();
diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp
new file mode 100644
index 0000000000..5ba7ad5a05
--- /dev/null
+++ b/indra/newview/llmaterialmgr.cpp
@@ -0,0 +1,270 @@
+/**
+ * @file llmaterialmgr.cpp
+ * @brief Material manager
+ *
+ * $LicenseInfo:firstyear=2006&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, 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 "llsdserialize.h"
+
+#include "llmaterialmgr.h"
+#include "llviewerobject.h"
+#include "llviewerobjectlist.h"
+#include "llviewerregion.h"
+
+/**
+ * Materials cap parameters
+ */
+
+#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"
+
+/**
+ * LLMaterialsResponder helper class
+ */
+
+class LLMaterialsResponder : public LLHTTPClient::Responder
+{
+public:
+ typedef boost::function<void (bool, const LLSD&)> CallbackFunction;
+
+ LLMaterialsResponder(const std::string& pMethod, const std::string& pCapabilityURL, CallbackFunction pCallback);
+ virtual ~LLMaterialsResponder();
+
+ virtual void result(const LLSD& pContent);
+ virtual void error(U32 pStatus, const std::string& pReason);
+
+private:
+ std::string mMethod;
+ std::string mCapabilityURL;
+ CallbackFunction mCallback;
+};
+
+LLMaterialsResponder::LLMaterialsResponder(const std::string& pMethod, const std::string& pCapabilityURL, CallbackFunction pCallback)
+ : LLHTTPClient::Responder()
+ , mMethod(pMethod)
+ , mCapabilityURL(pCapabilityURL)
+ , mCallback(pCallback)
+{
+}
+
+LLMaterialsResponder::~LLMaterialsResponder()
+{
+}
+
+void LLMaterialsResponder::result(const LLSD& pContent)
+{
+ mCallback(true, pContent);
+}
+
+void LLMaterialsResponder::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);
+}
+
+/**
+ * LLMaterialMgr class
+ */
+
+LLMaterialMgr::LLMaterialMgr()
+{
+}
+
+LLMaterialMgr::~LLMaterialMgr()
+{
+}
+
+void LLMaterialMgr::put(const LLUUID& object_id, const U8 te, const LLMaterial& material)
+{
+ put_queue_t::iterator itQueue = mPutQueue.find(object_id);
+ if (mPutQueue.end() == itQueue)
+ {
+ mPutQueue.insert(std::pair<LLUUID, facematerial_map_t>(object_id, facematerial_map_t()));
+ itQueue = mPutQueue.find(object_id);
+ }
+
+ facematerial_map_t::iterator itFace = itQueue->second.find(te);
+ if (itQueue->second.end() == itFace)
+ {
+ itQueue->second.insert(std::pair<U8, LLMaterial>(te, material));
+ }
+ else
+ {
+ itFace->second = material;
+ }
+}
+
+void LLMaterialMgr::onPutResponse(bool success, const LLSD& content, const LLUUID& object_id)
+{
+ if (!success)
+ {
+ // *TODO: is there any kind of error handling we can do here?
+ return;
+ }
+
+ LLViewerObject* objectp = gObjectList.findObject(object_id);
+ if (!objectp)
+ {
+ LL_WARNS("debugMaterials") << "Received PUT response for unknown object" << LL_ENDL;
+ return;
+ }
+
+ llassert(content.isMap());
+ llassert(content.has(MATERIALS_CAP_ZIP_FIELD));
+ llassert(content.get(MATERIALS_CAP_ZIP_FIELD).isBinary());
+
+ LLSD::Binary content_binary = content.get(MATERIALS_CAP_ZIP_FIELD).asBinary();
+ std::string content_string(reinterpret_cast<const char*>(content_binary.data()), content_binary.size());
+ std::istringstream content_stream(content_string);
+
+ LLSD response_data;
+ if (!unzip_llsd(response_data, content_stream, content_binary.size()))
+ {
+ LL_ERRS("debugMaterials") << "Cannot unzip LLSD binary content" << LL_ENDL;
+ return;
+ }
+ else
+ {
+ llassert(response_data.isArray());
+
+ for (LLSD::array_const_iterator faceIter = response_data.beginArray(); faceIter != response_data.endArray(); ++faceIter)
+ {
+ const LLSD& face_data = *faceIter;
+ llassert(face_data.isMap());
+
+ llassert(face_data.has(MATERIALS_CAP_OBJECT_ID_FIELD));
+ llassert(face_data.get(MATERIALS_CAP_OBJECT_ID_FIELD).isInteger());
+ U32 local_id = face_data.get(MATERIALS_CAP_OBJECT_ID_FIELD).asInteger();
+ if (objectp->getLocalID() != local_id)
+ {
+ LL_ERRS("debugMaterials") << "Received PUT response for wrong object" << LL_ENDL;
+ continue;
+ }
+
+ llassert(face_data.has(MATERIALS_CAP_FACE_FIELD));
+ llassert(face_data.get(MATERIALS_CAP_FACE_FIELD).isInteger());
+ S32 te = face_data.get(MATERIALS_CAP_FACE_FIELD).asInteger();
+
+ llassert(face_data.has(MATERIALS_CAP_MATERIAL_ID_FIELD));
+ llassert(face_data.get(MATERIALS_CAP_MATERIAL_ID_FIELD).isBinary());
+ LLMaterialID material_id(face_data.get(MATERIALS_CAP_MATERIAL_ID_FIELD).asBinary());
+
+ LL_INFOS("debugMaterials") << "Setting material '" << material_id.asString() << "' on object '" << local_id
+ << "' face " << te << LL_ENDL;
+
+ objectp->setTEMaterialID(te, material_id);
+ }
+ }
+}
+
+void LLMaterialMgr::processPutQueue()
+{
+ put_queue_t::iterator itQueue = mPutQueue.begin();
+ while (itQueue != mPutQueue.end())
+ {
+ put_queue_t::iterator curQueue = itQueue++;
+
+ const LLUUID& object_id = curQueue->first;
+ const LLViewerObject* objectp = gObjectList.findObject(object_id);
+ if ( (!objectp) || (!objectp->getRegion()) )
+ {
+ LL_WARNS("debugMaterials") << "Object or object region is NULL" << LL_ENDL;
+
+ mPutQueue.erase(curQueue);
+ continue;
+ }
+
+ const LLViewerRegion* regionp = objectp->getRegion();
+ if (!regionp->capabilitiesReceived())
+ {
+ continue;
+ }
+
+ std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME);
+ if (capURL.empty())
+ {
+ LL_WARNS("debugMaterials") << "Capability '" << MATERIALS_CAPABILITY_NAME
+ << "' is not defined on region '" << regionp->getName() << "'" << LL_ENDL;
+
+ mPutQueue.erase(curQueue);
+ continue;
+ }
+
+ LLSD facesData = LLSD::emptyArray();
+ for (facematerial_map_t::const_iterator itFace = curQueue->second.begin(); itFace != curQueue->second.end(); ++itFace)
+ {
+ LLSD faceData = LLSD::emptyMap();
+ faceData[MATERIALS_CAP_FACE_FIELD] = static_cast<LLSD::Integer>(itFace->first);
+ faceData[MATERIALS_CAP_OBJECT_ID_FIELD] = static_cast<LLSD::Integer>(objectp->getLocalID());
+ if (!itFace->second.isNull())
+ {
+ faceData[MATERIALS_CAP_MATERIAL_FIELD] = itFace->second.asLLSD();
+ }
+ facesData.append(faceData);
+
+ LL_INFOS("debugMaterials") << "Requesting material change on object '" << faceData[MATERIALS_CAP_OBJECT_ID_FIELD].asInteger()
+ << "' face " << faceData[MATERIALS_CAP_FACE_FIELD].asInteger() << LL_ENDL;
+ }
+
+ 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;
+
+ mPutQueue.erase(curQueue);
+ continue;
+ }
+ else
+ {
+ LLSD::Binary materialBinary;
+ materialBinary.resize(materialSize);
+ memcpy(materialBinary.data(), materialString.data(), materialSize);
+
+ LLSD putData = LLSD::emptyMap();
+ putData[MATERIALS_CAP_ZIP_FIELD] = materialBinary;
+
+ // *HACK: the viewer can't lookup the local object id the cap returns so we'll pass the object's uuid along
+ LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("PUT", capURL, boost::bind(&LLMaterialMgr::onPutResponse, this, _1, _2, object_id));
+ LLHTTPClient::put(capURL, putData, materialsResponder);
+ }
+ }
+}
diff --git a/indra/newview/llmaterialmgr.h b/indra/newview/llmaterialmgr.h
new file mode 100644
index 0000000000..c4e1c01389
--- /dev/null
+++ b/indra/newview/llmaterialmgr.h
@@ -0,0 +1,53 @@
+/**
+ * @file llmaterialmgr.h
+ * @brief Material manager
+ *
+ * $LicenseInfo:firstyear=2006&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, 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_LLMATERIALMGR_H
+#define LL_LLMATERIALMGR_H
+
+#include "llmaterial.h"
+#include "llsingleton.h"
+
+class LLMaterialMgr : public LLSingleton<LLMaterialMgr>
+{
+ friend LLSingleton<LLMaterialMgr>;
+protected:
+ LLMaterialMgr();
+ virtual ~LLMaterialMgr();
+
+public:
+ void put(const LLUUID& object_id, const U8 te, const LLMaterial& material);
+ void processPutQueue();
+
+protected:
+ void onPutResponse(bool success, const LLSD& content, const LLUUID& object_id);
+
+protected:
+ typedef std::map<U8, LLMaterial> facematerial_map_t;
+ typedef std::map<LLUUID, facematerial_map_t> put_queue_t;
+ put_queue_t mPutQueue;
+};
+
+#endif // LL_LLMATERIALMGR_H
diff --git a/indra/newview/skins/default/xui/en/floater_debug_materials.xml b/indra/newview/skins/default/xui/en/floater_debug_materials.xml
index b6c105e19a..3a450fdeff 100644
--- a/indra/newview/skins/default/xui/en/floater_debug_materials.xml
+++ b/indra/newview/skins/default/xui/en/floater_debug_materials.xml
@@ -720,24 +720,24 @@
left="0"
top_pad="0"
width="160">
- Results
+ Active selection
</text>
<scroll_list
column_padding="0"
draw_heading="true"
follows="left|top|right"
- height="100"
+ height="300"
layout="topleft"
left="0"
top_pad="10"
tab_stop="false"
multi_select="true"
name="put_scroll_list"
- width="400">
+ width="600">
<scroll_list.columns
label="Object ID"
name="object_id"
- width="80" />
+ width="225" />
<scroll_list.columns
label="Face Index"
name="face_index"