From 4a1397c621eec2deb90d4953762fea6187c0a270 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 24 Oct 2022 23:35:28 +0300 Subject: [PATCH 1/8] SL-18414 Smarter material editor's cancel for overrides --- indra/newview/llmaterialeditor.cpp | 97 ++++++++++++++++++++++++++++-- indra/newview/llmaterialeditor.h | 3 + 2 files changed, 96 insertions(+), 4 deletions(-) diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 8086bcf402..06705a277b 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -302,10 +302,6 @@ void LLMaterialEditor::onClickCloseBtn(bool app_quitting) void LLMaterialEditor::onClose(bool app_quitting) { - // todo: will only revert whatever was recently selected, - // Later should work based of tools floater - LLSelectMgr::getInstance()->selectionRevertGLTFMaterials(); - LLPreview::onClose(app_quitting); } @@ -1265,6 +1261,73 @@ void LLMaterialEditor::onCancelMsgCallback(const LLSD& notification, const LLSD& S32 option = LLNotificationsUtil::getSelectedOption(notification, response); if (0 == option) { + if (mIsOverride && !mObjectOverridesSavedValues.empty()) + { + // Reapply ids back onto selection. + // TODO: monitor selection changes and resave on selection changes + struct g : public LLSelectedObjectFunctor + { + g(LLMaterialEditor* me) : mEditor(me) {} + virtual bool apply(LLViewerObject* objectp) + { + if (!objectp || !objectp->permModify()) + { + return false; + } + + U32 local_id = objectp->getLocalID(); + if (mEditor->mObjectOverridesSavedValues.find(local_id) == mEditor->mObjectOverridesSavedValues.end()) + { + return false; + } + + S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); + for (U8 te = 0; te < num_tes; te++) + { + if (mEditor->mObjectOverridesSavedValues[local_id].size() > te + && objectp->getTE(te)->isSelected()) + { + objectp->setRenderMaterialID( + te, + mEditor->mObjectOverridesSavedValues[local_id][te], + false /*wait for bulk update*/); + } + } + return true; + } + LLMaterialEditor* mEditor; + } restorefunc(this); + LLSelectMgr::getInstance()->getSelection()->applyToObjects(&restorefunc); + + struct f : public LLSelectedObjectFunctor + { + virtual bool apply(LLViewerObject* object) + { + if (object && !object->permModify()) + { + return false; + } + + LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)object->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL); + if (param_block) + { + if (param_block->isEmpty()) + { + object->setHasRenderMaterialParams(false); + } + else + { + object->parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, true); + } + } + + object->sendTEUpdate(); + return true; + } + } sendfunc; + LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc); + } + closeFloater(); } } @@ -1410,6 +1473,32 @@ void LLMaterialEditor::loadLive() me->setTitle(me->getString("material_override_title")); me->childSetVisible("save", false); me->childSetVisible("save_as", false); + me->mObjectOverridesSavedValues.clear(); + + // Collect ids to be able to revert overrides. + // TODO: monitor selection changes and resave on selection changes + struct g : public LLSelectedObjectFunctor + { + g(LLMaterialEditor* me) : mEditor(me) {} + virtual bool apply(LLViewerObject* objectp) + { + if (!objectp) + { + return false; + } + + U32 local_id = objectp->getLocalID(); + S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); + for (U8 te = 0; te < num_tes; te++) + { + LLUUID mat_id = objectp->getRenderMaterialID(te); + mEditor->mObjectOverridesSavedValues[local_id].push_back(mat_id); + } + return true; + } + LLMaterialEditor* mEditor; + } savefunc(me); + LLSelectMgr::getInstance()->getSelection()->applyToObjects(&savefunc); me->openFloater(); me->setFocus(TRUE); diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index 23cb32aacf..60907b18ba 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -276,5 +276,8 @@ private: // if true, this instance is live instance editing overrides bool mIsOverride = false; + // local id, texture ids per face for object overrides + // for "cancel" support + std::map mObjectOverridesSavedValues; }; From 5c86ec6a6130bef9348d6155c6a7404914c20418 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 24 Oct 2022 16:26:42 -0500 Subject: [PATCH 2/8] SL-18105 Add mechanism for applying overrides that were received before associated ViewerObject was ready to receive them. --- indra/llprimitive/lltextureentry.cpp | 11 +++++++ indra/llprimitive/lltextureentry.h | 4 +-- indra/newview/llgltfmateriallist.cpp | 49 +++++++++++++++++++++++++--- indra/newview/llgltfmateriallist.h | 10 ++++++ indra/newview/llviewerobject.cpp | 5 +-- indra/newview/llvovolume.cpp | 4 +++ 6 files changed, 74 insertions(+), 9 deletions(-) diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp index 68de480d87..d810c6ed25 100644 --- a/indra/llprimitive/lltextureentry.cpp +++ b/indra/llprimitive/lltextureentry.cpp @@ -519,6 +519,17 @@ void LLTextureEntry::setGLTFMaterial(LLGLTFMaterial* material) } } +LLGLTFMaterial* LLTextureEntry::getGLTFRenderMaterial() const +{ + if (mGLTFRenderMaterial.notNull()) + { + return mGLTFRenderMaterial; + } + + llassert(getGLTFMaterialOverride() == nullptr); + return getGLTFMaterial(); +} + S32 LLTextureEntry::setGLTFRenderMaterial(LLGLTFMaterial* mat) { if (mGLTFRenderMaterial != mat) diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h index 8dc3434a01..e37bc9a3b6 100644 --- a/indra/llprimitive/lltextureentry.h +++ b/indra/llprimitive/lltextureentry.h @@ -199,12 +199,12 @@ public: LLGLTFMaterial* getGLTFMaterial() const { return mGLTFMaterial; } // GLTF override - LLGLTFMaterial* getGLTFMaterialOverride() { return mGLTFMaterialOverrides; } + LLGLTFMaterial* getGLTFMaterialOverride() const { return mGLTFMaterialOverrides; } void setGLTFMaterialOverride(LLGLTFMaterial* mat) { mGLTFMaterialOverrides = 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 - LLGLTFMaterial* getGLTFRenderMaterial() const { return mGLTFRenderMaterial.notNull() ? mGLTFRenderMaterial.get() : getGLTFMaterial(); } + LLGLTFMaterial* getGLTFRenderMaterial() const; S32 setGLTFRenderMaterial(LLGLTFMaterial* mat); public: diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index 4861c2a33b..cd60d34d2f 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -43,6 +43,8 @@ #include "json/reader.h" #include "json/value.h" +LLGLTFMaterialList gGLTFMaterialList; + namespace { class LLGLTFMaterialOverrideDispatchHandler : public LLDispatchHandler @@ -72,24 +74,27 @@ namespace LL_WARNS() << "LLGLTFMaterialOverrideDispatchHandler: Attempted to read parameter data into LLSD but failed:" << llsdRaw << LL_ENDL; } } + + LLUUID object_id = message["object_id"].asUUID(); - LLViewerObject * obj = gObjectList.findObject(message["object_id"].asUUID()); - llassert(obj); // should never get an override for an object we don't know about + 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 override_data = new LLGLTFMaterial(); 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 { - if (obj) + if (!obj || !obj->setTEGLTFMaterialOverride(side, override_data)) { - obj->setTEGLTFMaterialOverride(side, override_data); + // object not ready to receive override data, queue for later + gGLTFMaterialList.queueOverrideUpdate(object_id, side, override_data); } } @@ -99,7 +104,41 @@ namespace LLGLTFMaterialOverrideDispatchHandler handle_gltf_override_message; } -LLGLTFMaterialList gGLTFMaterialList; +void LLGLTFMaterialList::queueOverrideUpdate(const LLUUID& id, S32 side, LLGLTFMaterial* override_data) +{ + override_list_t& overrides = mQueuedOverrides[id]; + + if (overrides.size() < side + 1) + { + overrides.resize(side + 1); + } + + overrides[side] = override_data; +} + +void LLGLTFMaterialList::applyQueuedOverrides(LLViewerObject* obj) +{ + const LLUUID& id = obj->getID(); + auto& iter = mQueuedOverrides.find(id); + + if (iter != mQueuedOverrides.end()) + { + override_list_t& overrides = iter->second; + for (int i = 0; i < overrides.size(); ++i) + { + if (overrides[i].notNull()) + { + if (!obj->getTE(i)->getGLTFMaterial()) + { // object doesn't have its base GLTF material yet, don't apply override (yet) + return; + } + obj->setTEGLTFMaterialOverride(i, overrides[i]); + } + } + + mQueuedOverrides.erase(iter); + } +} LLGLTFMaterial* LLGLTFMaterialList::getMaterial(const LLUUID& id) { diff --git a/indra/newview/llgltfmateriallist.h b/indra/newview/llgltfmateriallist.h index 4b905e32c9..ee32dc8825 100644 --- a/indra/newview/llgltfmateriallist.h +++ b/indra/newview/llgltfmateriallist.h @@ -48,10 +48,20 @@ public: void flushMaterials(); static void registerCallbacks(); + + // 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); + + void applyQueuedOverrides(LLViewerObject* obj); + private: typedef std::unordered_map > uuid_mat_map_t; uuid_mat_map_t mList; + typedef std::vector > override_list_t; + typedef std::unordered_map queued_override_map_t; + queued_override_map_t mQueuedOverrides; + LLUUID mLastUpdateKey; }; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 603dcc4fa7..ac519970b7 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -247,6 +247,7 @@ LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pco LL_WARNS() << "Unknown object pcode " << (S32)pcode << LL_ENDL; res = NULL; break; } + return res; } @@ -5324,8 +5325,8 @@ S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_ma LLTextureEntry* tep = getTE(te); if (!tep) - { - LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL; + { // this could happen if the object is not fully formed yet + // returning TEM_CHANGE_NONE here signals to LLGLTFMaterialList to queue the override for later return retval; } diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index cb58c173d9..aea4353bc8 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -88,6 +88,7 @@ #include "llcallstack.h" #include "llsculptidsize.h" #include "llavatarappearancedefines.h" +#include "llgltfmateriallist.h" const F32 FORCE_SIMPLE_RENDER_AREA = 512.f; const F32 FORCE_CULL_AREA = 8.f; @@ -5823,6 +5824,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) continue; } + // apply any pending material overrides + gGLTFMaterialList.applyQueuedOverrides(vobj); + std::string vobj_name = llformat("Vol%p", vobj); bool is_mesh = vobj->isMesh(); From 687a012a695bb7da55fc2b9b220f48de658cb8b6 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 25 Oct 2022 19:55:59 +0300 Subject: [PATCH 3/8] SL-18008 Add "Save/Edit Materials" buttons to attachment's right click menu --- .../default/xui/en/menu_attachment_self.xml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/indra/newview/skins/default/xui/en/menu_attachment_self.xml b/indra/newview/skins/default/xui/en/menu_attachment_self.xml index 3b91b9df7a..630a1981df 100644 --- a/indra/newview/skins/default/xui/en/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/en/menu_attachment_self.xml @@ -12,6 +12,22 @@ + + + + + + + + Date: Tue, 25 Oct 2022 10:11:21 -0700 Subject: [PATCH 4/8] Xcode build fixes for DRTVWR-559 --- indra/newview/llgltfmateriallist.cpp | 2 +- indra/newview/llviewerobject.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index cd60d34d2f..05ed7a2019 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -119,7 +119,7 @@ void LLGLTFMaterialList::queueOverrideUpdate(const LLUUID& id, S32 side, LLGLTFM void LLGLTFMaterialList::applyQueuedOverrides(LLViewerObject* obj) { const LLUUID& id = obj->getID(); - auto& iter = mQueuedOverrides.find(id); + auto iter = mQueuedOverrides.find(id); if (iter != mQueuedOverrides.end()) { diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index ac519970b7..ac76ad7272 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -5335,7 +5335,7 @@ S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_ma tep->setGLTFMaterialOverride(override_mat); // if override mat exists, we must also have a source mat - llassert(override_mat ? src_mat : true); + llassert(override_mat ? bool(src_mat) : true); if (override_mat && src_mat) { From ca53f265b45b01378748039d2345005688545114 Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink Date: Tue, 25 Oct 2022 14:28:35 -0700 Subject: [PATCH 5/8] Bump Teamcity for new Project Viewer build of DRTVWR-559 --- indra/cmake/00-Common.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index 572422d080..d81d3ac1f0 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -232,3 +232,4 @@ else (USESYSTEMLIBS) endif (USESYSTEMLIBS) endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED) + From 89625f92473bd2894acd287caeeb1d20673f8ddb Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 26 Oct 2022 00:41:35 +0300 Subject: [PATCH 6/8] SL-18444 Live Material Editor updating with selection --- indra/newview/llinspectobject.cpp | 15 ++++- indra/newview/llmaterialeditor.cpp | 93 ++++++++++++++++++--------- indra/newview/llmaterialeditor.h | 4 ++ indra/newview/llsidepaneltaskinfo.cpp | 7 +- indra/newview/llsidepaneltaskinfo.h | 2 + 5 files changed, 87 insertions(+), 34 deletions(-) diff --git a/indra/newview/llinspectobject.cpp b/indra/newview/llinspectobject.cpp index 5329f10612..42bf416efb 100644 --- a/indra/newview/llinspectobject.cpp +++ b/indra/newview/llinspectobject.cpp @@ -116,6 +116,7 @@ private: viewer_media_t mMediaImpl; LLMediaEntry* mMediaEntry; LLSafeHandle mObjectSelection; + boost::signals2::connection mSelectionUpdateSlot; }; LLInspectObject::LLInspectObject(const LLSD& sd) @@ -175,9 +176,12 @@ BOOL LLInspectObject::postBuild(void) getChild("more_info_btn")->setCommitCallback( boost::bind(&LLInspectObject::onClickMoreInfo, this)); - // Watch for updates to selection properties off the network - LLSelectMgr::getInstance()->mUpdateSignal.connect( - boost::bind(&LLInspectObject::update, this) ); + if (!mSelectionUpdateSlot.connected()) + { + // Watch for updates to selection properties off the network + mSelectionUpdateSlot = LLSelectMgr::getInstance()->mUpdateSignal.connect( + boost::bind(&LLInspectObject::update, this)); + } return TRUE; } @@ -243,6 +247,11 @@ void LLInspectObject::onClose(bool app_quitting) mObjectSelection = NULL; mPreviousObjectID = mObjectID; + if (mSelectionUpdateSlot.connected()) + { + mSelectionUpdateSlot.disconnect(); + } + getChild("gear_btn")->hideMenu(); } diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 06705a277b..1e75216079 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -302,6 +302,11 @@ void LLMaterialEditor::onClickCloseBtn(bool app_quitting) void LLMaterialEditor::onClose(bool app_quitting) { + if (mSelectionUpdateSlot.connected()) + { + mSelectionUpdateSlot.disconnect(); + } + LLPreview::onClose(app_quitting); } @@ -1463,42 +1468,61 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind ); } } +void LLMaterialEditor::onSelectionChanged() +{ + mHasUnsavedChanges = false; + clearTextures(); + setFromSelection(); + saveLiveValues(); +} + +void LLMaterialEditor::saveLiveValues() +{ + // Collect ids to be able to revert overrides. + // TODO: monitor selection changes and resave on selection changes + mObjectOverridesSavedValues.clear(); + struct g : public LLSelectedObjectFunctor + { + g(LLMaterialEditor* me) : mEditor(me) {} + virtual bool apply(LLViewerObject* objectp) + { + if (!objectp) + { + return false; + } + + U32 local_id = objectp->getLocalID(); + S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); + for (U8 te = 0; te < num_tes; te++) + { + LLUUID mat_id = objectp->getRenderMaterialID(te); + mEditor->mObjectOverridesSavedValues[local_id].push_back(mat_id); + } + return true; + } + LLMaterialEditor* mEditor; + } savefunc(this); + LLSelectMgr::getInstance()->getSelection()->applyToObjects(&savefunc); +} void LLMaterialEditor::loadLive() { LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", LLSD(LIVE_MATERIAL_EDITOR_KEY)); - if (me->setFromSelection()) + if (me) { + me->setFromSelection(); me->mIsOverride = true; me->setTitle(me->getString("material_override_title")); me->childSetVisible("save", false); me->childSetVisible("save_as", false); - me->mObjectOverridesSavedValues.clear(); - // Collect ids to be able to revert overrides. - // TODO: monitor selection changes and resave on selection changes - struct g : public LLSelectedObjectFunctor + // Set up for selection changes updates + if (!me->mSelectionUpdateSlot.connected()) { - g(LLMaterialEditor* me) : mEditor(me) {} - virtual bool apply(LLViewerObject* objectp) - { - if (!objectp) - { - return false; - } - - U32 local_id = objectp->getLocalID(); - S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); - for (U8 te = 0; te < num_tes; te++) - { - LLUUID mat_id = objectp->getRenderMaterialID(te); - mEditor->mObjectOverridesSavedValues[local_id].push_back(mat_id); - } - return true; - } - LLMaterialEditor* mEditor; - } savefunc(me); - LLSelectMgr::getInstance()->getSelection()->applyToObjects(&savefunc); + me->mSelectionUpdateSlot = LLSelectMgr::instance().mUpdateSignal.connect(boost::bind(&LLMaterialEditor::onSelectionChanged, me)); + } + // Collect ids to be able to revert overrides on cancel. + me->saveLiveValues(); me->openFloater(); me->setFocus(TRUE); @@ -2095,6 +2119,10 @@ bool LLMaterialEditor::setFromSelection() return true; } + // pick defaults from a blank material; + LLGLTFMaterial blank_mat; + setFromGLTFMaterial(&blank_mat); + return false; } @@ -2424,6 +2452,16 @@ S32 LLMaterialEditor::saveTextures() } // discard upload buffers once textures have been saved + clearTextures(); + + // asset storage can callback immediately, causing a decrease + // of mUploadingTexturesCount, report amount of work scheduled + // not amount of work remaining + return work_count; +} + +void LLMaterialEditor::clearTextures() +{ mBaseColorJ2C = nullptr; mNormalJ2C = nullptr; mEmissiveJ2C = nullptr; @@ -2438,11 +2476,6 @@ S32 LLMaterialEditor::saveTextures() mNormalTextureUploadId.setNull(); mMetallicTextureUploadId.setNull(); mEmissiveTextureUploadId.setNull(); - - // asset storage can callback immediately, causing a decrease - // of mUploadingTexturesCount, report amount of work scheduled - // not amount of work remaining - return work_count; } void LLMaterialEditor::loadDefaults() diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index 60907b18ba..438acb532b 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -103,6 +103,8 @@ public: // will promt to select specific one static void loadMaterialFromFile(const std::string& filename, S32 index = -1); + void onSelectionChanged(); // // live overrides selection changes + void saveLiveValues(); // for restoration on cancel static void loadLive(); static void loadObjectSave(); @@ -118,6 +120,7 @@ public: // save textures to inventory if needed // returns amount of scheduled uploads S32 saveTextures(); + void clearTextures(); void onClickSave(); @@ -279,5 +282,6 @@ private: // local id, texture ids per face for object overrides // for "cancel" support std::map mObjectOverridesSavedValues; + boost::signals2::connection mSelectionUpdateSlot; }; diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp index 7fa06f51e3..6216057c17 100644 --- a/indra/newview/llsidepaneltaskinfo.cpp +++ b/indra/newview/llsidepaneltaskinfo.cpp @@ -77,7 +77,7 @@ static LLPanelInjector t_task_info("sidepanel_task_info"); LLSidepanelTaskInfo::LLSidepanelTaskInfo() { setMouseOpaque(FALSE); - LLSelectMgr::instance().mUpdateSignal.connect(boost::bind(&LLSidepanelTaskInfo::refreshAll, this)); + mSelectionUpdateSlot = LLSelectMgr::instance().mUpdateSignal.connect(boost::bind(&LLSidepanelTaskInfo::refreshAll, this)); } @@ -85,6 +85,11 @@ LLSidepanelTaskInfo::~LLSidepanelTaskInfo() { if (sActivePanel == this) sActivePanel = NULL; + + if (mSelectionUpdateSlot.connected()) + { + mSelectionUpdateSlot.disconnect(); + } } // virtual diff --git a/indra/newview/llsidepaneltaskinfo.h b/indra/newview/llsidepaneltaskinfo.h index dc259cb22d..ac9c57f2e2 100644 --- a/indra/newview/llsidepaneltaskinfo.h +++ b/indra/newview/llsidepaneltaskinfo.h @@ -154,6 +154,8 @@ private: LLView* mDAE; LLView* mDAN; LLView* mDAF; + + boost::signals2::connection mSelectionUpdateSlot; }; From 631b7de4b2262855984ed1d35ae7859507b12e9e Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 26 Oct 2022 15:03:55 +0300 Subject: [PATCH 7/8] SL-18444 Either connection should be create in onOpen or disconnect happen in destructor --- indra/newview/llinspectobject.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/indra/newview/llinspectobject.cpp b/indra/newview/llinspectobject.cpp index 42bf416efb..3d13985f08 100644 --- a/indra/newview/llinspectobject.cpp +++ b/indra/newview/llinspectobject.cpp @@ -142,6 +142,10 @@ LLInspectObject::LLInspectObject(const LLSD& sd) LLInspectObject::~LLInspectObject() { + if (mSelectionUpdateSlot.connected()) + { + mSelectionUpdateSlot.disconnect(); + } } /*virtual*/ @@ -247,11 +251,6 @@ void LLInspectObject::onClose(bool app_quitting) mObjectSelection = NULL; mPreviousObjectID = mObjectID; - if (mSelectionUpdateSlot.connected()) - { - mSelectionUpdateSlot.disconnect(); - } - getChild("gear_btn")->hideMenu(); } From d69c814db94c907a1a772e4e63a8b82a293985d2 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 26 Oct 2022 20:18:33 +0300 Subject: [PATCH 8/8] SL-18446 Terse-update selection set from live material editor #1 --- indra/newview/llmaterialeditor.cpp | 169 +++++++++++++++++++++-------- indra/newview/llmaterialeditor.h | 8 +- indra/newview/llviewermenu.cpp | 24 ++-- 3 files changed, 139 insertions(+), 62 deletions(-) diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 1e75216079..58804a901f 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -67,6 +67,24 @@ const std::string MATERIAL_EMISSIVE_DEFAULT_NAME = "Emissive"; const LLUUID LIVE_MATERIAL_EDITOR_KEY("6cf97162-8b68-49eb-b627-79886c9fd17d"); +// Dirty flags +static const U32 MATERIAL_BASE_COLOR_DIRTY = 0x1 << 0; +static const U32 MATERIAL_BASE_TRANSPARENCY_DIRTY = 0x1 << 1; +static const U32 MATERIAL_BASE_COLOR_TEX_DIRTY = 0x1 << 2; + +static const U32 MATERIAL_NORMAL_TEX_DIRTY = 0x1 << 3; + +static const U32 MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY = 0x1 << 4; +static const U32 MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY = 0x1 << 5; +static const U32 MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY = 0x1 << 6; + +static const U32 MATERIAL_EMISIVE_COLOR_DIRTY = 0x1 << 7; +static const U32 MATERIAL_EMISIVE_TEX_DIRTY = 0x1 << 8; + +static const U32 MATERIAL_DOUBLE_SIDED_DIRTY = 0x1 << 9; +static const U32 MATERIAL_ALPHA_MODE_DIRTY = 0x1 << 10; +static const U32 MATERIAL_ALPHA_CUTOFF_DIRTY = 0x1 << 11; + LLFloaterComboOptions::LLFloaterComboOptions() : LLFloater(LLSD()) { @@ -199,7 +217,7 @@ private: // Default constructor LLMaterialEditor::LLMaterialEditor(const LLSD& key) : LLPreview(key) - , mHasUnsavedChanges(false) + , mUnsavedChanges(0) , mExpectedUploadCost(0) , mUploadingTexturesCount(0) { @@ -251,33 +269,30 @@ BOOL LLMaterialEditor::postBuild() getChild("emissive_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); getChild("normal_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); - boost::function changes_callback = [this](LLUICtrl * ctrl, void*) + boost::function changes_callback = [this](LLUICtrl * ctrl, void* userData) { - setHasUnsavedChanges(true); + const U32 *flag = (const U32*)userData; + markChangesUnsaved(*flag); // Apply changes to object live applyToSelection(); }; - childSetCommitCallback("double sided", changes_callback, NULL); + childSetCommitCallback("double sided", changes_callback, (void*)&MATERIAL_DOUBLE_SIDED_DIRTY); // BaseColor - childSetCommitCallback("base color", changes_callback, NULL); - childSetCommitCallback("transparency", changes_callback, NULL); - childSetCommitCallback("alpha mode", changes_callback, NULL); - childSetCommitCallback("alpha cutoff", changes_callback, NULL); + childSetCommitCallback("base color", changes_callback, (void*)&MATERIAL_BASE_COLOR_DIRTY); + childSetCommitCallback("transparency", changes_callback, (void*)&MATERIAL_BASE_TRANSPARENCY_DIRTY); + childSetCommitCallback("alpha mode", changes_callback, (void*)&MATERIAL_ALPHA_MODE_DIRTY); + childSetCommitCallback("alpha cutoff", changes_callback, (void*)&MATERIAL_ALPHA_CUTOFF_DIRTY); // Metallic-Roughness - childSetCommitCallback("metalness factor", changes_callback, NULL); - childSetCommitCallback("roughness factor", changes_callback, NULL); - - // Metallic-Roughness - childSetCommitCallback("metalness factor", changes_callback, NULL); - childSetCommitCallback("roughness factor", changes_callback, NULL); + childSetCommitCallback("metalness factor", changes_callback, (void*)&MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY); + childSetCommitCallback("roughness factor", changes_callback, (void*)&MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY); // Emissive - childSetCommitCallback("emissive color", changes_callback, NULL); + childSetCommitCallback("emissive color", changes_callback, (void*)&MATERIAL_EMISIVE_COLOR_DIRTY); - childSetVisible("unsaved_changes", mHasUnsavedChanges); + childSetVisible("unsaved_changes", mUnsavedChanges); getChild("total_upload_fee")->setTextArg("[FEE]", llformat("%d", 0)); @@ -333,7 +348,7 @@ void LLMaterialEditor::setBaseColorUploadId(const LLUUID& id) // Only set if we will need to upload this texture mBaseColorTextureUploadId = id; } - setHasUnsavedChanges(true); + markChangesUnsaved(MATERIAL_BASE_COLOR_TEX_DIRTY); } LLColor4 LLMaterialEditor::getBaseColor() @@ -405,7 +420,7 @@ void LLMaterialEditor::setMetallicRoughnessUploadId(const LLUUID& id) childSetValue("metallic_upload_fee", getString("upload_fee_string")); mMetallicTextureUploadId = id; } - setHasUnsavedChanges(true); + markChangesUnsaved(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY); } F32 LLMaterialEditor::getMetalnessFactor() @@ -448,7 +463,7 @@ void LLMaterialEditor::setEmissiveUploadId(const LLUUID& id) childSetValue("emissive_upload_fee", getString("upload_fee_string")); mEmissiveTextureUploadId = id; } - setHasUnsavedChanges(true); + markChangesUnsaved(MATERIAL_EMISIVE_TEX_DIRTY); } LLColor4 LLMaterialEditor::getEmissiveColor() @@ -481,7 +496,7 @@ void LLMaterialEditor::setNormalUploadId(const LLUUID& id) childSetValue("normal_upload_fee", getString("upload_fee_string")); mNormalTextureUploadId = id; } - setHasUnsavedChanges(true); + markChangesUnsaved(MATERIAL_NORMAL_TEX_DIRTY); } bool LLMaterialEditor::getDoubleSided() @@ -494,12 +509,22 @@ void LLMaterialEditor::setDoubleSided(bool double_sided) childSetValue("double sided", double_sided); } -void LLMaterialEditor::setHasUnsavedChanges(bool value) +void LLMaterialEditor::resetUnsavedChanges() { - mHasUnsavedChanges = value; - childSetVisible("unsaved_changes", value); + mUnsavedChanges = 0; + childSetVisible("unsaved_changes", false); + setCanSave(false); - if (mHasUnsavedChanges) + mExpectedUploadCost = 0; + getChild("total_upload_fee")->setTextArg("[FEE]", llformat("%d", mExpectedUploadCost)); +} + +void LLMaterialEditor::markChangesUnsaved(U32 dirty_flag) +{ + mUnsavedChanges |= dirty_flag; + childSetVisible("unsaved_changes", mUnsavedChanges); + + if (mUnsavedChanges) { const LLInventoryItem* item = getItem(); if (item) @@ -594,7 +619,7 @@ void LLMaterialEditor::onCommitBaseColorTexture(LLUICtrl * ctrl, const LLSD & da // the texture that is not in use childSetValue("base_color_upload_fee", getString("no_upload_fee_string")); } - setHasUnsavedChanges(true); + markChangesUnsaved(MATERIAL_BASE_COLOR_TEX_DIRTY); applyToSelection(); } @@ -609,7 +634,7 @@ void LLMaterialEditor::onCommitMetallicTexture(LLUICtrl * ctrl, const LLSD & dat { childSetValue("metallic_upload_fee", getString("no_upload_fee_string")); } - setHasUnsavedChanges(true); + markChangesUnsaved(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY); applyToSelection(); } @@ -624,7 +649,7 @@ void LLMaterialEditor::onCommitEmissiveTexture(LLUICtrl * ctrl, const LLSD & dat { childSetValue("emissive_upload_fee", getString("no_upload_fee_string")); } - setHasUnsavedChanges(true); + markChangesUnsaved(MATERIAL_EMISIVE_TEX_DIRTY); applyToSelection(); } @@ -639,7 +664,7 @@ void LLMaterialEditor::onCommitNormalTexture(LLUICtrl * ctrl, const LLSD & data) { childSetValue("normal_upload_fee", getString("no_upload_fee_string")); } - setHasUnsavedChanges(true); + markChangesUnsaved(MATERIAL_NORMAL_TEX_DIRTY); applyToSelection(); } @@ -1223,7 +1248,7 @@ void LLMaterialEditor::onSaveAsMsgCallback(const LLSD& notification, const LLSD& else { std::string buffer = getEncodedAsset(); - LLPointer cb = new LLMaterialEditorCopiedCallback(buffer, getKey(), mHasUnsavedChanges); + LLPointer cb = new LLMaterialEditorCopiedCallback(buffer, getKey(), mUnsavedChanges); copy_inventory_item( gAgent.getID(), item->getPermissions().getOwner(), @@ -1251,7 +1276,7 @@ void LLMaterialEditor::onSaveAsMsgCallback(const LLSD& notification, const LLSD& void LLMaterialEditor::onClickCancel() { - if (mHasUnsavedChanges) + if (mUnsavedChanges) { LLNotificationsUtil::add("UsavedMaterialChanges", LLSD(), LLSD(), boost::bind(&LLMaterialEditor::onCancelMsgCallback, this, _1, _2)); } @@ -1470,7 +1495,7 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind } void LLMaterialEditor::onSelectionChanged() { - mHasUnsavedChanges = false; + mUnsavedChanges = 0; clearTextures(); setFromSelection(); saveLiveValues(); @@ -1551,7 +1576,6 @@ void LLMaterialEditor::loadFromGLTFMaterial(LLUUID &asset_id) LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor"); me->mMaterialName = LLTrans::getString("New Material"); me->setTitle(me->mMaterialName); - me->setHasUnsavedChanges(true); me->setFromGLTFMaterial(gGLTFMaterialList.getMaterial(asset_id)); me->openFloater(); me->setFocus(TRUE); @@ -1653,7 +1677,7 @@ void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std:: setFromGltfMetaData(filename_lc, model_in, index); - setHasUnsavedChanges(true); + markChangesUnsaved(U32_MAX); openFloater(); setFocus(TRUE); @@ -1991,8 +2015,8 @@ private: class LLRenderMaterialOverrideFunctor : public LLSelectedTEFunctor { public: - LLRenderMaterialOverrideFunctor(LLMaterialEditor * me, std::string const & url, LLUUID const & asset_id) - : mEditor(me), mCapUrl(url), mAssetID(asset_id) + LLRenderMaterialOverrideFunctor(LLMaterialEditor * me, std::string const & url) + : mEditor(me), mCapUrl(url) { } @@ -2007,9 +2031,69 @@ public: if (objectp && objectp->permModify() && objectp->getVolume()) { - LLPointer material = new LLGLTFMaterial(); - - mEditor->getGLTFMaterial(material); + // Get material from object + // Selection can cover multiple objects, and live editor is + // supposed to overwrite changed values only + LLTextureEntry* tep = objectp->getTE(te); + LLPointer material = tep->getGLTFMaterial(); + if (material.isNull()) + { + material = new LLGLTFMaterial(); + } + + // Override object's values with values from editor where appropriate + if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_COLOR_DIRTY) + { + material->mBaseColor = mEditor->getBaseColor(); + } + if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_TRANSPARENCY_DIRTY) + { + material->mBaseColor.mV[3] = mEditor->getTransparency(); + } + if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_COLOR_TEX_DIRTY) + { + material->mBaseColorId = mEditor->getBaseColorId(); + } + + if (mEditor->getUnsavedChangesFlags() & MATERIAL_NORMAL_TEX_DIRTY) + { + material->mNormalId = mEditor->getNormalId(); + } + + if (mEditor->getUnsavedChangesFlags() & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) + { + material->mMetallicRoughnessId = mEditor->getMetallicRoughnessId(); + } + if (mEditor->getUnsavedChangesFlags() & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY) + { + material->mMetallicFactor = mEditor->getMetalnessFactor(); + } + if (mEditor->getUnsavedChangesFlags() & MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY) + { + material->mRoughnessFactor = mEditor->getRoughnessFactor(); + } + + if (mEditor->getUnsavedChangesFlags() & MATERIAL_EMISIVE_COLOR_DIRTY) + { + material->mEmissiveColor = mEditor->getEmissiveColor(); + } + if (mEditor->getUnsavedChangesFlags() & MATERIAL_EMISIVE_TEX_DIRTY) + { + material->mEmissiveId = mEditor->getEmissiveId(); + } + + if (mEditor->getUnsavedChangesFlags() & MATERIAL_DOUBLE_SIDED_DIRTY) + { + material->mDoubleSided = mEditor->getDoubleSided(); + } + if (mEditor->getUnsavedChangesFlags() & MATERIAL_ALPHA_MODE_DIRTY) + { + material->setAlphaMode(mEditor->getAlphaMode()); + } + if (mEditor->getUnsavedChangesFlags() & MATERIAL_ALPHA_CUTOFF_DIRTY) + { + material->mAlphaCutoff = mEditor->getAlphaCutoff(); + } std::string overrides_json = material->asJSON(); @@ -2026,7 +2110,6 @@ public: private: LLMaterialEditor * mEditor; std::string mCapUrl; - LLUUID mAssetID; }; void LLMaterialEditor::applyToSelection() @@ -2045,7 +2128,7 @@ void LLMaterialEditor::applyToSelection() { LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); // TODO figure out how to get the right asset id in cases where we don't have a good one - LLRenderMaterialOverrideFunctor override_func(this, url, mAssetID); + LLRenderMaterialOverrideFunctor override_func(this, url); selected_objects->applyToTEs(&override_func); } else @@ -2162,7 +2245,7 @@ void LLMaterialEditor::loadAsset() { mAssetStatus = PREVIEW_ASSET_LOADED; loadDefaults(); - setHasUnsavedChanges(false); + resetUnsavedChanges(); setEnableEditing(allow_modify && !source_library); } else @@ -2187,7 +2270,7 @@ void LLMaterialEditor::loadAsset() LL_WARNS() << "Can't find object " << mObjectUUID << " associated with notecard." << LL_ENDL; mAssetID.setNull(); mAssetStatus = PREVIEW_ASSET_LOADED; - setHasUnsavedChanges(false); + resetUnsavedChanges(); setEnableEditing(allow_modify && !source_library); return; } @@ -2274,7 +2357,7 @@ void LLMaterialEditor::onLoadComplete(const LLUUID& asset_uuid, BOOL allow_modify = editor->canModify(editor->mObjectUUID, editor->getItem()); BOOL source_library = editor->mObjectUUID.isNull() && gInventory.isObjectDescendentOf(editor->mItemUUID, gInventory.getLibraryRootFolderID()); editor->setEnableEditing(allow_modify && !source_library); - editor->setHasUnsavedChanges(false); + editor->resetUnsavedChanges(); editor->mAssetStatus = PREVIEW_ASSET_LOADED; editor->setEnabled(true); // ready for use } diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index 438acb532b..040dbe99da 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -209,7 +209,6 @@ public: bool getDoubleSided(); void setDoubleSided(bool double_sided); - void setHasUnsavedChanges(bool value); void setCanSaveAs(bool value); void setCanSave(bool value); void setEnableEditing(bool can_modify); @@ -224,6 +223,8 @@ public: void modifyMaterialCoro(std::string cap_url, LLSD overrides); + U32 getUnsavedChangesFlags() { return mUnsavedChanges; } + private: void setFromGLTFMaterial(LLGLTFMaterial* mat); bool setFromSelection(); @@ -271,7 +272,10 @@ private: // based on what we know about it. const std::string buildMaterialDescription(); - bool mHasUnsavedChanges; + void resetUnsavedChanges(); + void markChangesUnsaved(U32 dirty_flag); + + U32 mUnsavedChanges; // flags to indicate individual changed parameters S32 mUploadingTexturesCount; S32 mExpectedUploadCost; std::string mMaterialNameShort; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 18d215f9f4..e1b92e5f2e 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -2956,30 +2956,20 @@ void handle_object_edit() return; } -void load_life_gltf_material(bool copy) +void handle_object_edit_gltf_material() { - update_camera(); - - LLSelectedTEGetmatIdAndPermissions func; - LLUUID mat_id; - LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&func, mat_id); - - if (copy) + if (!LLFloaterReg::instanceVisible("build")) { - LLMaterialEditor::loadFromGLTFMaterial(mat_id); + handle_object_edit(); // does update_camera(); } else { - LLMaterialEditor::loadLive(); + update_camera(); + + LLViewerJoystick::getInstance()->moveObjects(true); + LLViewerJoystick::getInstance()->setNeedsReset(true); } - LLViewerJoystick::getInstance()->moveObjects(true); - LLViewerJoystick::getInstance()->setNeedsReset(true); -} - -void handle_object_edit_gltf_material() -{ - handle_object_edit(); LLMaterialEditor::loadLive(); }