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 insteadmeow-7.2.2
parent
a0392ec5ec
commit
1e26dbdcd2
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Reference in New Issue