diff options
author | Dave Parks <davep@lindenlab.com> | 2022-10-26 16:08:28 -0500 |
---|---|---|
committer | Dave Parks <davep@lindenlab.com> | 2022-10-26 16:08:28 -0500 |
commit | 8f47657d646c06dbba8d44497c0f81fd00730cc8 (patch) | |
tree | eec5702e7dc4d83a8bf00c0c7a87272870fcec42 /indra | |
parent | ed1e5214cefc5f0aeb630bf2fbcda9dff9ed8d61 (diff) |
SL-18443 Allow nulling out of override data and implement new override message protocol.
Diffstat (limited to 'indra')
-rw-r--r-- | indra/llprimitive/lltextureentry.cpp | 14 | ||||
-rw-r--r-- | indra/llprimitive/lltextureentry.h | 2 | ||||
-rw-r--r-- | indra/newview/llgltfmateriallist.cpp | 116 | ||||
-rw-r--r-- | indra/newview/llgltfmateriallist.h | 7 | ||||
-rw-r--r-- | indra/newview/llmaterialeditor.cpp | 29 | ||||
-rw-r--r-- | indra/newview/llmaterialeditor.h | 2 | ||||
-rw-r--r-- | indra/newview/llselectmgr.cpp | 38 | ||||
-rw-r--r-- | indra/newview/llviewerobject.cpp | 14 |
8 files changed, 138 insertions, 84 deletions
diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp index d810c6ed25..7640dd70bd 100644 --- a/indra/llprimitive/lltextureentry.cpp +++ b/indra/llprimitive/lltextureentry.cpp @@ -512,13 +512,25 @@ S32 LLTextureEntry::setBumpShiny(U8 bump_shiny) void LLTextureEntry::setGLTFMaterial(LLGLTFMaterial* material) { - mGLTFMaterial = material; + // assert on precondtion: + // whether or not mGLTFMaterial is null, any existing override should have been nulled out + // before calling setGLTFMaterial + // NOTE: if you're hitting this assert, try to make sure calling code is using LLViewerObject::setRenderMaterialID + llassert(getGLTFMaterialOverride() == nullptr); + + mGLTFMaterial = material; if (mGLTFMaterial == nullptr) { setGLTFRenderMaterial(nullptr); } } +void LLTextureEntry::setGLTFMaterialOverride(LLGLTFMaterial* mat) +{ + llassert(mat == nullptr || getGLTFMaterial() != nullptr); // if override is not null, base material must not be null + mGLTFMaterialOverrides = mat; +} + LLGLTFMaterial* LLTextureEntry::getGLTFRenderMaterial() const { if (mGLTFRenderMaterial.notNull()) diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h index e37bc9a3b6..d94e14bd73 100644 --- a/indra/llprimitive/lltextureentry.h +++ b/indra/llprimitive/lltextureentry.h @@ -200,7 +200,7 @@ public: // GLTF override LLGLTFMaterial* getGLTFMaterialOverride() const { return mGLTFMaterialOverrides; } - void setGLTFMaterialOverride(LLGLTFMaterial* mat) { mGLTFMaterialOverrides = mat; } + void setGLTFMaterialOverride(LLGLTFMaterial* mat); // GLTF render material // nuanced behavior here -- if there is no render material, fall back to getGLTFMaterial, but ONLY for the getter, not the setter diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index cd60d34d2f..3b4e9406bb 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -36,13 +36,15 @@ #include "llviewercontrol.h" #include "llviewergenericmessage.h" #include "llviewerobjectlist.h" - +#include "llcorehttputil.h" #include "tinygltf/tiny_gltf.h" #include <strstream> #include "json/reader.h" #include "json/value.h" +#include <unordered_set> + LLGLTFMaterialList gGLTFMaterialList; namespace @@ -77,27 +79,80 @@ namespace LLUUID object_id = message["object_id"].asUUID(); - LLViewerObject * obj = gObjectList.findObject(object_id); - S32 side = message["side"].asInteger(); - std::string gltf_json = message["gltf_json"].asString(); - - std::string warn_msg, error_msg; - LLPointer<LLGLTFMaterial> override_data = new LLGLTFMaterial(); - bool success = override_data->fromJSON(gltf_json, warn_msg, error_msg); + LLViewerObject * obj = gObjectList.findObject(object_id); // NOTE: null object here does NOT mean nothing to do, parse message and queue results for later + bool clear_all = true; - if (!success) + if (message.has("sides") && message.has("gltf_json")) { - LL_WARNS() << "failed to parse GLTF override data. errors: " << error_msg << " | warnings: " << warn_msg << LL_ENDL; + LLSD& sides = message["sides"]; + LLSD& gltf_json = message["gltf_json"]; + + if (sides.isArray() && gltf_json.isArray() && + sides.size() != 0 && + sides.size() == gltf_json.size()) + { + clear_all = false; + + // message should be interpreted thusly: + /// sides is a list of face indices + // gltf_json is a list of corresponding json + // any side not represented in "sides" has no override + + // parse json + std::unordered_set<S32> side_set; + + for (int i = 0; i < sides.size(); ++i) + { + LLPointer<LLGLTFMaterial> override_data = new LLGLTFMaterial(); + + std::string gltf_json = message["gltf_json"][i].asString(); + + std::string warn_msg, error_msg; + + bool success = override_data->fromJSON(gltf_json, warn_msg, error_msg); + + if (!success) + { + LL_WARNS() << "failed to parse GLTF override data. errors: " << error_msg << " | warnings: " << warn_msg << LL_ENDL; + } + else + { + S32 side = sides[i].asInteger(); + // flag this side to not be nulled out later + side_set.insert(sides); + + if (!obj || !obj->setTEGLTFMaterialOverride(side, override_data)) + { + // object not ready to receive override data, queue for later + gGLTFMaterialList.queueOverrideUpdate(object_id, side, override_data); + } + } + } + + if (obj && side_set.size() != obj->getNumTEs()) + { // object exists and at least one texture entry needs to have its override data nulled out + for (int i = 0; i < obj->getNumTEs(); ++i) + { + if (side_set.find(i) == side_set.end()) + { + obj->setTEGLTFMaterialOverride(i, nullptr); + } + } + } + } + else + { + LL_WARNS() << "Malformed GLTF override message data: " << message << LL_ENDL; + } } - else - { - if (!obj || !obj->setTEGLTFMaterialOverride(side, override_data)) + + if (clear_all && obj) + { // override list was empty or an error occurred, null out all overrides for this object + for (int i = 0; i < obj->getNumTEs(); ++i) { - // object not ready to receive override data, queue for later - gGLTFMaterialList.queueOverrideUpdate(object_id, side, override_data); + obj->setTEGLTFMaterialOverride(i, nullptr); } } - return true; } }; @@ -296,3 +351,32 @@ void LLGLTFMaterialList::registerCallbacks() { gGenericDispatcher.addHandler("GLTFMaterialOverride", &handle_gltf_override_message); } + +// static +void LLGLTFMaterialList::modifyMaterialCoro(std::string cap_url, LLSD overrides) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("modifyMaterialCoro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); + LLCore::HttpHeaders::ptr_t httpHeaders; + + httpOpts->setFollowRedirects(true); + + LL_DEBUGS() << "Applying override via ModifyMaterialParams cap: " << overrides << LL_ENDL; + + LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, overrides, httpOpts, httpHeaders); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status) + { + LL_WARNS() << "Failed to modify material." << LL_ENDL; + } + else if (!result["success"].asBoolean()) + { + LL_WARNS() << "Failed to modify material: " << result["message"] << LL_ENDL; + } +} diff --git a/indra/newview/llgltfmateriallist.h b/indra/newview/llgltfmateriallist.h index ee32dc8825..f770f6ecc8 100644 --- a/indra/newview/llgltfmateriallist.h +++ b/indra/newview/llgltfmateriallist.h @@ -49,6 +49,13 @@ public: static void registerCallbacks(); + // apply given override data via given cap url + // cap_url -- should be gAgent.getRegionCapability("ModifyMaterialParams") + // overrides -- LLSD map in the format + // "object_id": LLUUID - object to be modified + // "side": integer - index of face to be modified + // "gltf_json" : string - GLTF compliant json of override data (optional, if omitted any existing override data will be cleared) + static void modifyMaterialCoro(std::string cap_url, LLSD overrides); // save an override update for later (for example, if an override arrived for an unknown object) void queueOverrideUpdate(const LLUUID& id, S32 side, LLGLTFMaterial* override_data); diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 06705a277b..5ae16db1f6 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1994,7 +1994,7 @@ public: "side", te, "gltf_json", overrides_json ); - LLCoros::instance().launch("modifyMaterialCoro", std::bind(&LLMaterialEditor::modifyMaterialCoro, mEditor, mCapUrl, overrides)); + LLCoros::instance().launch("modifyMaterialCoro", std::bind(&LLGLTFMaterialList::modifyMaterialCoro, mCapUrl, overrides)); } return true; } @@ -2452,30 +2452,3 @@ void LLMaterialEditor::loadDefaults() setFromGltfModel(model_in, 0, true); } -void LLMaterialEditor::modifyMaterialCoro(std::string cap_url, LLSD overrides) -{ - LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); - LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t - httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("modifyMaterialCoro", httpPolicy)); - LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); - LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); - LLCore::HttpHeaders::ptr_t httpHeaders; - - httpOpts->setFollowRedirects(true); - - LL_DEBUGS() << "Applying override via ModifyMaterialParams cap: " << overrides << LL_ENDL; - - LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, overrides, httpOpts, httpHeaders); - - LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; - LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); - - if (!status) - { - LL_WARNS() << "Failed to modify material." << LL_ENDL; - } - else if (!result["success"].asBoolean()) - { - LL_WARNS() << "Failed to modify material: " << result["message"] << LL_ENDL; - } -} diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index 60907b18ba..53f19d877b 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -219,8 +219,6 @@ public: // initialize the UI from a default GLTF material void loadDefaults(); - void modifyMaterialCoro(std::string cap_url, LLSD overrides); - private: void setFromGLTFMaterial(LLGLTFMaterial* mat); bool setFromSelection(); diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 2475900d0e..ac508c4e8a 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -1950,48 +1950,14 @@ void LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id) if (te != -1) { - LLTextureEntry* tep = objectp->getTE(te); - if (asset_id.notNull()) - { - tep->setGLTFMaterial(gGLTFMaterialList.getMaterial(asset_id)); - } - else - { - tep->setGLTFMaterial(nullptr); - } - - objectp->faceMappingChanged(); - gPipeline.markTextured(objectp->mDrawable); - - LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)objectp->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL); - if (param_block) - { - param_block->setMaterial(te, asset_id); - } + objectp->setRenderMaterialID(te, asset_id); } else // Shouldn't happen? { S32 num_faces = objectp->getNumTEs(); for (S32 face = 0; face < num_faces; face++) { - LLTextureEntry* tep = objectp->getTE(face); - if (asset_id.notNull()) - { - tep->setGLTFMaterial(gGLTFMaterialList.getMaterial(asset_id)); - } - else - { - tep->setGLTFMaterial(nullptr); - } - - objectp->faceMappingChanged(); - gPipeline.markTextured(objectp->mDrawable); - - LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)objectp->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL); - if (param_block) - { - param_block->setMaterial(face, asset_id); - } + objectp->setRenderMaterialID(te, asset_id); } } diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index ac519970b7..7dbe0652b1 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -7115,6 +7115,20 @@ const LLUUID& LLViewerObject::getRenderMaterialID(U8 te) const void LLViewerObject::setRenderMaterialID(U8 te, const LLUUID& id, bool update_server) { + if (update_server) + { + // clear out any existing override data and render material + getTE(te)->setGLTFMaterialOverride(nullptr); + getTE(te)->setGLTFRenderMaterial(nullptr); + + LLCoros::instance().launch("modifyMaterialCoro", + std::bind(&LLGLTFMaterialList::modifyMaterialCoro, + gAgent.getRegionCapability("ModifyMaterialParams"), + llsd::map( + "object_id", getID(), + "side", te))); + } + if (id.notNull()) { getTE(te)->setGLTFMaterial(gGLTFMaterialList.getMaterial(id)); |