summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BuildParams11
-rwxr-xr-xindra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/llfloaterstinson.cpp701
-rw-r--r--indra/newview/llfloaterstinson.h118
-rw-r--r--indra/newview/llviewerfloaterreg.cpp2
-rw-r--r--indra/newview/llviewerregion.cpp1
-rw-r--r--indra/newview/skins/default/colors.xml9
-rw-r--r--indra/newview/skins/default/xui/en/floater_stinson.xml158
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml10
9 files changed, 1012 insertions, 0 deletions
diff --git a/BuildParams b/BuildParams
index ebfc640023..258dd43b41 100644
--- a/BuildParams
+++ b/BuildParams
@@ -136,6 +136,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/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 0031362210..776ddb9f08 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -246,6 +246,7 @@ set(viewer_SOURCE_FILES
llfloatersnapshot.cpp
llfloatersounddevices.cpp
llfloaterspellchecksettings.cpp
+ llfloaterstinson.cpp
llfloatertelehub.cpp
llfloatertestinspectors.cpp
llfloatertestlistview.cpp
@@ -822,6 +823,7 @@ set(viewer_HEADER_FILES
llfloatersnapshot.h
llfloatersounddevices.h
llfloaterspellchecksettings.h
+ llfloaterstinson.h
llfloatertelehub.h
llfloatertestinspectors.h
llfloatertestlistview.h
diff --git a/indra/newview/llfloaterstinson.cpp b/indra/newview/llfloaterstinson.cpp
new file mode 100644
index 0000000000..5da1d9b242
--- /dev/null
+++ b/indra/newview/llfloaterstinson.cpp
@@ -0,0 +1,701 @@
+/**
+* @file llfloaterstinson.cpp
+* @brief Implementation of llfloaterstinson
+* @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 "llfloaterstinson.h"
+
+#include <string>
+
+#include <boost/bind.hpp>
+#include <boost/function.hpp>
+#include <boost/signals2.hpp>
+
+#include "llagent.h"
+#include "llbutton.h"
+#include "llenvmanager.h"
+#include "llfloater.h"
+#include "llfontgl.h"
+#include "llhttpclient.h"
+#include "llscrolllistcell.h"
+#include "llscrolllistctrl.h"
+#include "llscrolllistitem.h"
+#include "llsd.h"
+#include "llselectmgr.h"
+#include "llstring.h"
+#include "llstyle.h"
+#include "lltextbase.h"
+#include "lluicolortable.h"
+#include "llviewerobject.h"
+#include "llviewerparcelmgr.h"
+#include "llviewerregion.h"
+#include "v4color.h"
+#include "v4coloru.h"
+
+#define MATERIALS_CAPABILITY_NAME "RenderMaterials"
+
+#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_NORMAL_MAP_FIELD "NormMap"
+#define MATERIALS_CAP_SPECULAR_MAP_FIELD "SpecMap"
+#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_IS_MASK_FIELD "DiffAlphaIsMask"
+
+class MaterialsGetResponder : public LLHTTPClient::Responder
+{
+public:
+ typedef boost::function<void (bool, const LLSD&)> CallbackFunction;
+
+ MaterialsGetResponder(const std::string& pCapabilityURL, CallbackFunction pCallback);
+ virtual ~MaterialsGetResponder();
+
+ virtual void result(const LLSD& pContent);
+ virtual void error(U32 pStatus, const std::string& pReason);
+
+protected:
+
+private:
+ std::string mCapabilityURL;
+ CallbackFunction mCallback;
+};
+
+class MaterialsPutResponder : public LLHTTPClient::Responder
+{
+public:
+ typedef boost::function<void (bool, const LLSD&)> CallbackFunction;
+
+ MaterialsPutResponder(const std::string& pCapabilityURL, CallbackFunction pCallback);
+ virtual ~MaterialsPutResponder();
+
+ virtual void result(const LLSD& pContent);
+ virtual void error(U32 pStatus, const std::string& pReason);
+
+protected:
+
+private:
+ std::string mCapabilityURL;
+ CallbackFunction mCallback;
+};
+
+BOOL LLFloaterStinson::postBuild()
+{
+ mStatusText = findChild<LLTextBase>("material_status");
+ llassert(mStatusText != NULL);
+
+ mGetButton = findChild<LLButton>("get_button");
+ llassert(mGetButton != NULL);
+ mGetButton->setCommitCallback(boost::bind(&LLFloaterStinson::onGetClicked, this));
+
+ mPutButton = findChild<LLButton>("put_button");
+ llassert(mPutButton != NULL);
+ mPutButton->setCommitCallback(boost::bind(&LLFloaterStinson::onPutClicked, this));
+
+ mMaterialsScrollList = findChild<LLScrollListCtrl>("materials_scroll_list");
+ llassert(mMaterialsScrollList != NULL);
+
+ mWarningColor = LLUIColorTable::instance().getColor("MaterialWarningColor");
+ mErrorColor = LLUIColorTable::instance().getColor("MaterialErrorColor");
+
+ setState(kNoRegion);
+
+ return LLFloater::postBuild();
+}
+
+void LLFloaterStinson::onOpen(const LLSD& pKey)
+{
+ LLFloater::onOpen(pKey);
+
+ if (!mRegionCrossConnection.connected())
+ {
+ mRegionCrossConnection = LLEnvManagerNew::instance().setRegionChangeCallback(boost::bind(&LLFloaterStinson::onRegionCross, this));
+ }
+
+ if (!mTeleportFailedConnection.connected())
+ {
+ mTeleportFailedConnection = LLViewerParcelMgr::getInstance()->setTeleportFailedCallback(boost::bind(&LLFloaterStinson::onRegionCross, this));
+ }
+
+ if (!mSelectionUpdateConnection.connected())
+ {
+ mSelectionUpdateConnection = LLSelectMgr::getInstance()->mUpdateSignal.connect(boost::bind(&LLFloaterStinson::onInWorldSelectionChange, this));
+ }
+
+ checkRegionMaterialStatus();
+ clearMaterialsList();
+}
+
+void LLFloaterStinson::onClose(bool pIsAppQuitting)
+{
+ clearMaterialsList();
+
+ if (mSelectionUpdateConnection.connected())
+ {
+ mSelectionUpdateConnection.disconnect();
+ }
+
+ if (mTeleportFailedConnection.connected())
+ {
+ mTeleportFailedConnection.disconnect();
+ }
+
+ if (mRegionCrossConnection.connected())
+ {
+ mRegionCrossConnection.disconnect();
+ }
+
+ LLFloater::onClose(pIsAppQuitting);
+}
+
+LLFloaterStinson::LLFloaterStinson(const LLSD& pParams)
+ : LLFloater(pParams),
+ mStatusText(NULL),
+ mGetButton(NULL),
+ mPutButton(NULL),
+ mState(kNoRegion),
+ mWarningColor(),
+ mErrorColor(),
+ mRegionCrossConnection(),
+ mTeleportFailedConnection(),
+ mSelectionUpdateConnection()
+{
+}
+
+LLFloaterStinson::~LLFloaterStinson()
+{
+}
+
+void LLFloaterStinson::onGetClicked()
+{
+ requestGetMaterials();
+}
+
+void LLFloaterStinson::onPutClicked()
+{
+ requestPutMaterials();
+}
+
+void LLFloaterStinson::onRegionCross()
+{
+ checkRegionMaterialStatus();
+}
+
+void LLFloaterStinson::onInWorldSelectionChange()
+{
+ updateControls();
+}
+
+void LLFloaterStinson::onDeferredCheckRegionMaterialStatus(LLUUID regionId)
+{
+ checkRegionMaterialStatus(regionId);
+}
+
+void LLFloaterStinson::onDeferredRequestGetMaterials(LLUUID regionId)
+{
+ requestGetMaterials(regionId);
+}
+
+void LLFloaterStinson::onDeferredRequestPutMaterials(LLUUID regionId)
+{
+ requestPutMaterials(regionId);
+}
+
+void LLFloaterStinson::onGetResponse(bool pRequestStatus, const LLSD& pContent)
+{
+ if (pRequestStatus)
+ {
+ setState(kRequestCompleted);
+ parseGetResponse(pContent);
+ }
+ else
+ {
+ setState(kError);
+ }
+}
+
+void LLFloaterStinson::onPutResponse(bool pRequestStatus, const LLSD& pContent)
+{
+ if (pRequestStatus)
+ {
+ setState(kRequestCompleted);
+ printResponse("PUT", pContent);
+ }
+ else
+ {
+ setState(kError);
+ }
+}
+
+void LLFloaterStinson::checkRegionMaterialStatus()
+{
+ LLViewerRegion *region = gAgent.getRegion();
+
+ if (region == NULL)
+ {
+ llwarns << "Region is NULL" << llendl;
+ setState(kNoRegion);
+ }
+ else if (!region->capabilitiesReceived())
+ {
+ setState(kCapabilitiesLoading);
+ region->setCapabilitiesReceivedCallback(boost::bind(&LLFloaterStinson::onDeferredRequestGetMaterials, this, region->getRegionID()));
+ }
+ else
+ {
+ std::string capURL = region->getCapability(MATERIALS_CAPABILITY_NAME);
+
+ if (capURL.empty())
+ {
+ llwarns << "Capability '" << MATERIALS_CAPABILITY_NAME << "' is not defined on the current region '"
+ << region->getName() << "'" << llendl;
+ setState(kNotEnabled);
+ }
+ else
+ {
+ setState(kReady);
+ }
+ }
+}
+
+void LLFloaterStinson::checkRegionMaterialStatus(const LLUUID& regionId)
+{
+ const LLViewerRegion *region = gAgent.getRegion();
+
+ if ((region != NULL) && (region->getRegionID() == regionId))
+ {
+ checkRegionMaterialStatus();
+ }
+}
+
+void LLFloaterStinson::requestGetMaterials()
+{
+ LLViewerRegion *region = gAgent.getRegion();
+
+ if (region == NULL)
+ {
+ llwarns << "Region is NULL" << llendl;
+ setState(kNoRegion);
+ }
+ else if (!region->capabilitiesReceived())
+ {
+ setState(kCapabilitiesLoading);
+ region->setCapabilitiesReceivedCallback(boost::bind(&LLFloaterStinson::onDeferredRequestGetMaterials, this, region->getRegionID()));
+ }
+ else
+ {
+ std::string capURL = region->getCapability(MATERIALS_CAPABILITY_NAME);
+
+ if (capURL.empty())
+ {
+ llwarns << "Capability '" << MATERIALS_CAPABILITY_NAME << "' is not defined on the current region '"
+ << region->getName() << "'" << llendl;
+ setState(kNotEnabled);
+ }
+ else
+ {
+ setState(kRequestStarted);
+ LLHTTPClient::ResponderPtr materialsResponder = new MaterialsGetResponder(capURL, boost::bind(&LLFloaterStinson::onGetResponse, this, _1, _2));
+ llinfos << "STINSON DEBUG: sending request GET to capability '" << MATERIALS_CAPABILITY_NAME
+ << "' with url '" << capURL << "'" << llendl;
+ LLHTTPClient::get(capURL, materialsResponder);
+ }
+ }
+}
+
+void LLFloaterStinson::requestGetMaterials(const LLUUID& regionId)
+{
+ const LLViewerRegion *region = gAgent.getRegion();
+
+ if ((region != NULL) && (region->getRegionID() == regionId))
+ {
+ requestGetMaterials();
+ }
+}
+
+void LLFloaterStinson::requestPutMaterials()
+{
+ LLViewerRegion *region = gAgent.getRegion();
+
+ if (region == NULL)
+ {
+ llwarns << "Region is NULL" << llendl;
+ setState(kNoRegion);
+ }
+ else if (!region->capabilitiesReceived())
+ {
+ setState(kCapabilitiesLoading);
+ region->setCapabilitiesReceivedCallback(boost::bind(&LLFloaterStinson::onDeferredRequestPutMaterials, this, region->getRegionID()));
+ }
+ else
+ {
+ std::string capURL = region->getCapability(MATERIALS_CAPABILITY_NAME);
+
+ if (capURL.empty())
+ {
+ llwarns << "Capability '" << MATERIALS_CAPABILITY_NAME << "' is not defined on the current region '"
+ << region->getName() << "'" << llendl;
+ setState(kNotEnabled);
+ }
+ else
+ {
+ setState(kRequestStarted);
+
+ LLSD facesData = LLSD::emptyArray();
+
+
+ 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();
+
+ S32 numFaces = viewerObject->getNumFaces();
+ for (S32 curFaceIndex = 0; curFaceIndex < numFaces; ++curFaceIndex)
+ {
+ LLSD materialData = LLSD::emptyMap();
+
+#define FACE_MODULATOR 4
+ if ((curFaceIndex % FACE_MODULATOR) == 0)
+ {
+ materialData[MATERIALS_CAP_NORMAL_MAP_FIELD] = LLUUID("dd88438d-895e-4cc4-3557-f8b6870be6e5"); // Library > Textures > Rock > Rock - Rippling
+ materialData[MATERIALS_CAP_SPECULAR_MAP_FIELD] = LLUUID("c7f1beb3-4c5f-f70e-6d96-7668ff8aea0a"); // Library > Textures > Rock > Rock - Granite
+ LLColor4U specularColor(255, 255, 255, 255);
+ materialData[MATERIALS_CAP_SPECULAR_COLOR_FIELD] = specularColor.getValue();
+ materialData[MATERIALS_CAP_SPECULAR_EXP_FIELD] = static_cast<LLSD::Integer>(100);
+ materialData[MATERIALS_CAP_ENV_INTENSITY_FIELD] = static_cast<LLSD::Integer>(25);
+ materialData[MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD] = static_cast<LLSD::Integer>(37);
+ materialData[MATERIALS_CAP_DIFFUSE_ALPHA_IS_MASK_FIELD] = static_cast<LLSD::Boolean>(false);
+ }
+ else if ((curFaceIndex % FACE_MODULATOR) == 1)
+ {
+ materialData[MATERIALS_CAP_NORMAL_MAP_FIELD] = LLUUID("cfcd9d0b-f04b-f01a-8b29-519e27078896"); // Library > Textures > Terrain Textures > Terrain Textures - Winter > Primitive Island - Base Ice-rock
+ materialData[MATERIALS_CAP_SPECULAR_MAP_FIELD] = LLUUID("fcad96ba-3495-d426-9713-21cf721332a4"); // Library > Textures > Terrain Textures > Terrain Textures - Winter > Primitive Island - Ice-rock
+ LLColor4U specularColor(100, 50, 200, 128);
+ materialData[MATERIALS_CAP_SPECULAR_COLOR_FIELD] = specularColor.getValue();
+ materialData[MATERIALS_CAP_SPECULAR_EXP_FIELD] = static_cast<LLSD::Integer>(255);
+ materialData[MATERIALS_CAP_ENV_INTENSITY_FIELD] = static_cast<LLSD::Integer>(0);
+ materialData[MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD] = static_cast<LLSD::Integer>(5);
+ materialData[MATERIALS_CAP_DIFFUSE_ALPHA_IS_MASK_FIELD] = static_cast<LLSD::Boolean>(true);
+ }
+ else if ((curFaceIndex % FACE_MODULATOR) == 2)
+ {
+ materialData[MATERIALS_CAP_NORMAL_MAP_FIELD] = LLUUID("6ed3abd3-527a-856d-3771-2a04ea4c16e1"); // Library > Textures > Waterfalls > Water - ripple layer 1
+ materialData[MATERIALS_CAP_SPECULAR_MAP_FIELD] = LLUUID("e7c01539-4836-cd47-94ac-55af7502e4db"); // Library > Textures > Waterfalls > Water - ripple layer 2
+ LLColor4U specularColor(128, 128, 128, 255);
+ materialData[MATERIALS_CAP_SPECULAR_COLOR_FIELD] = specularColor.getValue();
+ materialData[MATERIALS_CAP_SPECULAR_EXP_FIELD] = static_cast<LLSD::Integer>(1);
+ materialData[MATERIALS_CAP_ENV_INTENSITY_FIELD] = static_cast<LLSD::Integer>(255);
+ materialData[MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD] = static_cast<LLSD::Integer>(75);
+ materialData[MATERIALS_CAP_DIFFUSE_ALPHA_IS_MASK_FIELD] = static_cast<LLSD::Boolean>(false);
+ }
+ else if ((curFaceIndex % FACE_MODULATOR) == 3)
+ {
+ // do nothing
+ }
+
+ if ((curFaceIndex % FACE_MODULATOR) != 3)
+ {
+ LLSD faceData = LLSD::emptyMap();
+ faceData[MATERIALS_CAP_FACE_FIELD] = static_cast<LLSD::Integer>(curFaceIndex);
+ faceData[MATERIALS_CAP_OBJECT_ID_FIELD] = static_cast<LLSD::Integer>(viewerObject->getLocalID());
+ faceData[MATERIALS_CAP_MATERIAL_FIELD] = materialData;
+ facesData.append(faceData);
+ }
+ }
+ }
+
+ LLSD putData = LLSD::emptyMap();
+ putData[MATERIALS_CAP_FULL_PER_FACE_FIELD] = facesData;
+
+ LLHTTPClient::ResponderPtr materialsResponder = new MaterialsPutResponder(capURL, boost::bind(&LLFloaterStinson::onPutResponse, this, _1, _2));
+ llinfos << "STINSON DEBUG: sending request PUT to capability '" << MATERIALS_CAPABILITY_NAME
+ << "' with url '" << capURL << "' and with data " << putData << llendl;
+ LLHTTPClient::put(capURL, putData, materialsResponder);
+ }
+ }
+}
+
+void LLFloaterStinson::requestPutMaterials(const LLUUID& regionId)
+{
+ const LLViewerRegion *region = gAgent.getRegion();
+
+ if ((region != NULL) && (region->getRegionID() == regionId))
+ {
+ requestPutMaterials();
+ }
+}
+
+void LLFloaterStinson::parseGetResponse(const LLSD& pContent)
+{
+ printResponse("GET", pContent);
+ clearMaterialsList();
+
+ LLScrollListCell::Params cellParams;
+ LLScrollListItem::Params rowParams;
+
+ llassert(pContent.isArray());
+ for (LLSD::array_const_iterator materialIter = pContent.beginArray(); materialIter != pContent.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::Binary &materialIDValue = material.get(MATERIALS_CAP_OBJECT_ID_FIELD).asBinary();
+ unsigned int valueSize = materialIDValue.size();
+
+ std::string materialID(reinterpret_cast<const char *>(&materialIDValue[0]), valueSize);
+ std::string materialIDString;
+ for (unsigned int i = 0; i < valueSize; ++i)
+ {
+ materialIDString += llformat("%02x", materialID.c_str()[i]);
+ }
+
+ 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_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_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_IS_MASK_FIELD));
+ llassert(materialData.get(MATERIALS_CAP_DIFFUSE_ALPHA_IS_MASK_FIELD).isInteger());
+ BOOL isDiffuseAlphaMask = static_cast<BOOL>(materialData.get(MATERIALS_CAP_DIFFUSE_ALPHA_IS_MASK_FIELD).asInteger());
+
+
+ cellParams.font = LLFontGL::getFontMonospace();
+
+ cellParams.column = "id";
+ cellParams.value = materialIDString;
+ rowParams.columns.add(cellParams);
+
+ cellParams.column = "normal_map";
+ cellParams.value = normalMapID.asString();
+ rowParams.columns.add(cellParams);
+
+ cellParams.column = "specular_map";
+ cellParams.value = specularMapID.asString();
+ rowParams.columns.add(cellParams);
+
+ cellParams.font = LLFontGL::getFontSansSerif();
+
+ cellParams.column = "specular_color";
+ cellParams.value = llformat("(%d, %d, %d, %d)", specularColor.mV[0],
+ specularColor.mV[1], specularColor.mV[2], specularColor.mV[3]);
+ rowParams.columns.add(cellParams);
+
+ cellParams.column = "specular_exponent";
+ cellParams.value = llformat("%d", specularExp);
+ rowParams.columns.add(cellParams);
+
+ cellParams.column = "env_intensity";
+ cellParams.value = llformat("%d", envIntensity);
+ rowParams.columns.add(cellParams);
+
+ cellParams.column = "alpha_mask_cutoff";
+ cellParams.value = llformat("%d", alphaMaskCutoff);
+ rowParams.columns.add(cellParams);
+
+ cellParams.column = "is_diffuse_alpha_mask";
+ cellParams.value = (isDiffuseAlphaMask ? "True" : "False");
+ rowParams.columns.add(cellParams);
+
+ mMaterialsScrollList->addRow(rowParams);
+ }
+}
+
+void LLFloaterStinson::printResponse(const std::string& pRequestType, const LLSD& pContent) const
+{
+ llinfos << "--------------------------------------------------------------------------" << llendl;
+ llinfos << pRequestType << " Response: '" << pContent << "'" << llendl;
+ llinfos << "--------------------------------------------------------------------------" << llendl;
+}
+
+void LLFloaterStinson::setState(EState pState)
+{
+ mState = pState;
+ updateStatusMessage();
+ updateControls();
+}
+
+void LLFloaterStinson::clearMaterialsList()
+{
+ mMaterialsScrollList->deleteAllItems();
+}
+
+void LLFloaterStinson::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 LLFloaterStinson::updateControls()
+{
+ LLObjectSelectionHandle selectionHandle = LLSelectMgr::getInstance()->getEditSelection();
+ bool isPutEnabled = (selectionHandle->valid_begin() != selectionHandle->valid_end());
+
+ switch (getState())
+ {
+ case kNoRegion :
+ case kCapabilitiesLoading :
+ case kRequestStarted :
+ case kNotEnabled :
+ mGetButton->setEnabled(FALSE);
+ mPutButton->setEnabled(FALSE);
+ break;
+ case kReady :
+ case kRequestCompleted :
+ case kError :
+ mGetButton->setEnabled(TRUE);
+ mPutButton->setEnabled(isPutEnabled);
+ break;
+ default :
+ mGetButton->setEnabled(TRUE);
+ mPutButton->setEnabled(isPutEnabled);
+ llassert(0);
+ break;
+ }
+}
+
+MaterialsGetResponder::MaterialsGetResponder(const std::string& pCapabilityURL, CallbackFunction pCallback)
+ : LLHTTPClient::Responder(),
+ mCapabilityURL(pCapabilityURL),
+ mCallback(pCallback)
+{
+}
+
+MaterialsGetResponder::~MaterialsGetResponder()
+{
+}
+
+void MaterialsGetResponder::result(const LLSD& pContent)
+{
+ mCallback(true, pContent);
+}
+
+void MaterialsGetResponder::error(U32 pStatus, const std::string& pReason)
+{
+ llwarns << "--------------------------------------------------------------------------" << llendl;
+ llwarns << "GET Error[" << pStatus << "] cannot access cap '" << MATERIALS_CAPABILITY_NAME
+ << "' with url '" << mCapabilityURL << "' because " << pReason << llendl;
+ llwarns << "--------------------------------------------------------------------------" << llendl;
+
+ LLSD emptyResult;
+ mCallback(false, emptyResult);
+}
+
+MaterialsPutResponder::MaterialsPutResponder(const std::string& pCapabilityURL, CallbackFunction pCallback)
+ : LLHTTPClient::Responder(),
+ mCapabilityURL(pCapabilityURL),
+ mCallback(pCallback)
+{
+}
+
+MaterialsPutResponder::~MaterialsPutResponder()
+{
+}
+
+void MaterialsPutResponder::result(const LLSD& pContent)
+{
+ mCallback(true, pContent);
+}
+
+void MaterialsPutResponder::error(U32 pStatus, const std::string& pReason)
+{
+ llwarns << "--------------------------------------------------------------------------" << llendl;
+ llwarns << "PUT Error[" << pStatus << "] cannot access cap '" << MATERIALS_CAPABILITY_NAME
+ << "' with url '" << mCapabilityURL << "' because " << pReason << llendl;
+ llwarns << "--------------------------------------------------------------------------" << llendl;
+
+ LLSD emptyResult;
+ mCallback(false, emptyResult);
+}
diff --git a/indra/newview/llfloaterstinson.h b/indra/newview/llfloaterstinson.h
new file mode 100644
index 0000000000..5b8f157cd0
--- /dev/null
+++ b/indra/newview/llfloaterstinson.h
@@ -0,0 +1,118 @@
+/**
+* @file llfloaterstinson.h
+* @brief Header file for llfloaterstinson
+* @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_LLFLOATERSTINSON_H
+#define LL_LLFLOATERSTINSON_H
+
+#include <boost/signals2.hpp>
+
+#include "llfloater.h"
+#include "lluuid.h"
+#include "v4color.h"
+
+class LLButton;
+class LLScrollListCtrl;
+class LLSD;
+class LLTextBase;
+
+class LLFloaterStinson : public LLFloater
+{
+public:
+ virtual BOOL postBuild();
+
+ virtual void onOpen(const LLSD& pKey);
+ virtual void onClose(bool pIsAppQuitting);
+
+protected:
+
+private:
+ friend class LLFloaterReg;
+
+ typedef enum {
+ kNoRegion,
+ kCapabilitiesLoading,
+ kReady,
+ kRequestStarted,
+ kRequestCompleted,
+ kNotEnabled,
+ kError
+ } EState;
+
+ LLFloaterStinson(const LLSD& pParams);
+ virtual ~LLFloaterStinson();
+
+ void onGetClicked();
+ void onPutClicked();
+ void onRegionCross();
+ void onInWorldSelectionChange();
+ void onDeferredCheckRegionMaterialStatus(LLUUID regionId);
+ void onDeferredRequestGetMaterials(LLUUID regionId);
+ void onDeferredRequestPutMaterials(LLUUID regionId);
+ void onGetResponse(bool pRequestStatus, const LLSD& pContent);
+ void onPutResponse(bool pRequestStatus, const LLSD& pContent);
+
+ void checkRegionMaterialStatus();
+ void checkRegionMaterialStatus(const LLUUID& regionId);
+
+ void requestGetMaterials();
+ void requestGetMaterials(const LLUUID& regionId);
+
+ void requestPutMaterials();
+ void requestPutMaterials(const LLUUID& regionId);
+
+ void parseGetResponse(const LLSD& pContent);
+ void printResponse(const std::string& pRequestType, const LLSD& pContent) const;
+
+ void setState(EState pState);
+ inline EState getState() const;
+
+ void clearMaterialsList();
+
+ void updateStatusMessage();
+ void updateControls();
+
+ LLTextBase* mStatusText;
+ LLButton* mGetButton;
+ LLButton* mPutButton;
+ LLScrollListCtrl* mMaterialsScrollList;
+
+ EState mState;
+ LLColor4 mWarningColor;
+ LLColor4 mErrorColor;
+
+ boost::signals2::connection mRegionCrossConnection;
+ boost::signals2::connection mTeleportFailedConnection;
+ boost::signals2::connection mSelectionUpdateConnection;
+};
+
+
+
+LLFloaterStinson::EState LLFloaterStinson::getState() const
+{
+ return mState;
+}
+
+#endif // LL_LLFLOATERSTINSON_H
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 1f7cf0cdd4..9314a3794b 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -103,6 +103,7 @@
#include "llfloatersnapshot.h"
#include "llfloatersounddevices.h"
#include "llfloaterspellchecksettings.h"
+#include "llfloaterstinson.h"
#include "llfloatertelehub.h"
#include "llfloatertestinspectors.h"
#include "llfloatertestlistview.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_stinson", "floater_stinson.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterStinson>);
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/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index effa368b7a..755879f591 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1558,6 +1558,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/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_stinson.xml b/indra/newview/skins/default/xui/en/floater_stinson.xml
new file mode 100644
index 0000000000..559e6eb48f
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_stinson.xml
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ positioning="cascading"
+ can_tear_off="false"
+ can_resize="true"
+ height="315"
+ width="1194"
+ min_height="315"
+ min_width="1100"
+ layout="topleft"
+ name="floater_stinson"
+ help_topic="floater_stinson"
+ reuse_instance="true"
+ save_rect="false"
+ single_instance="true"
+ title="Stinson Test">
+ <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>
+ <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>
+ <view_border
+ bevel_style="none"
+ follows="left|right|top"
+ height="0"
+ layout="topleft"
+ name="horiz_separator"
+ top_pad="0"
+ left="12"
+ width="1170"/>
+ <panel
+ border="false"
+ bevel_style="none"
+ follows="left|top|right"
+ layout="topleft"
+ height="167"
+ top_pad="10"
+ width="1170">
+ <button
+ follows="left|top"
+ height="22"
+ label="Get"
+ layout="topleft"
+ name="get_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"
+ tab_stop="false"
+ multi_select="true"
+ name="materials_scroll_list"
+ width="1170">
+ <scroll_list.columns
+ label="ID"
+ name="id"
+ dynamic_width="true" />
+ <scroll_list.columns
+ label="Normal Map"
+ name="normal_map"
+ width="230" />
+ <scroll_list.columns
+ label="Specular Map"
+ name="specular_map"
+ width="230" />
+ <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="Is Diffuse Alpha Mask"
+ name="is_diffuse_alpha_mask"
+ width="128" />
+ </scroll_list>
+ </panel>
+ <view_border
+ bevel_style="none"
+ follows="left|right|top"
+ height="0"
+ layout="topleft"
+ name="horiz_separator"
+ top_pad="10"
+ left="12"
+ width="1170"/>
+ <panel
+ border="false"
+ bevel_style="none"
+ follows="left|top"
+ layout="topleft"
+ left="12"
+ top_pad="10"
+ height="22"
+ width="214">
+ <button
+ follows="left|top"
+ height="22"
+ label="Put"
+ layout="topleft"
+ name="put_button"
+ top_pad="0"
+ width="214"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 1aa55acf2d..e94253fcf6 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -989,6 +989,16 @@
<menu_item_separator/>
+ <menu_item_call
+ label="Stinson"
+ name="StinsonMenu">
+ <menu_item_call.on_click
+ function="Floater.ToggleOrBringToFront"
+ parameter="floater_stinson" />
+ </menu_item_call>
+
+ <menu_item_separator/>
+
<menu
create_jump_keys="true"
label="Options"