From 9f7967fcdc5ccb60bd72e8e9e1b7652dc2058524 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 29 Nov 2022 23:35:18 +0200 Subject: SL-18727 Save material to Inventoryshould prioritize picked face --- indra/newview/llmaterialeditor.cpp | 106 ++++++++++++++++++++++++++----------- 1 file changed, 76 insertions(+), 30 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index d5339777c4..fe674abeee 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -46,6 +46,7 @@ #include "llsdutil.h" #include "llselectmgr.h" #include "llstatusbar.h" // can_afford_transaction() +#include "lltoolpie.h" #include "llviewerinventory.h" #include "llinventory.h" #include "llviewerregion.h" @@ -322,9 +323,17 @@ bool LLSelectedTEGetMatData::apply(LLViewerObject* objectp, S32 te_index) mLocalMaterial = local_mat; } mMaterial = tep->getGLTFRenderMaterial(); + + if (mMaterial.isNull()) + { + // Shouldn't be possible? + LL_WARNS("MaterialEditor") << "Object has material id, but no material" << LL_ENDL; + mMaterial = gGLTFMaterialList.getMaterial(mat_id); + } } + return true; } - return true; + return false; } ///---------------------------------------------------------------------------- @@ -1816,58 +1825,95 @@ void LLMaterialEditor::loadLive() void LLMaterialEditor::saveObjectsMaterialAs() { - - // Find an applicable material. - // Do this before showing message, because - // message is going to drop selection. LLSelectedTEGetMatData func(false); LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func, true /*first applicable*/); + saveMaterialAs(func.mMaterial, func.mLocalMaterial); +} +void LLMaterialEditor::savePickedMaterialAs() +{ + LLPickInfo pick = LLToolPie::getInstance()->getPick(); + if (pick.mPickType != LLPickInfo::PICK_OBJECT || !pick.getObject()) + { + return; + } + + LLPointer render_material; + LLPointer local_material; - if (func.mLocalMaterial.notNull()) + LLViewerObject *objectp = pick.getObject(); + LLUUID mat_id = objectp->getRenderMaterialID(pick.mObjectFace); + if (mat_id.notNull() && objectp->permCopy()) + { + // Try a face user picked first + // (likely the only method we need, but in such case + // enable_object_save_gltf_material will need to check this) + LLTextureEntry *tep = objectp->getTE(pick.mObjectFace); + LLGLTFMaterial *mat = tep->getGLTFMaterial(); + LLLocalGLTFMaterial *local_mat = dynamic_cast(mat); + + if (local_mat) + { + local_material = local_mat; + } + render_material = tep->getGLTFRenderMaterial(); + } + else + { + // Find an applicable material. + // Do this before showing message, because + // message is going to drop selection. + LLSelectedTEGetMatData func(false); + LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func, true /*first applicable*/); + local_material = func.mLocalMaterial; + render_material = func.mMaterial; + } + + saveMaterialAs(render_material, local_material); +} + +void LLMaterialEditor::saveMaterialAs(const LLGLTFMaterial* render_material, const LLLocalGLTFMaterial *local_material) +{ + if (local_material) { // This is a local material, reload it from file // so that user won't end up with grey textures // on next login. - LLMaterialEditor::loadMaterialFromFile(func.mLocalMaterial->getFilename(), func.mLocalMaterial->getIndexInFile()); + LLMaterialEditor::loadMaterialFromFile(local_material->getFilename(), local_material->getIndexInFile()); LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor"); if (me) { - // apply differences on top - LLGLTFMaterial* local_mat = func.mLocalMaterial.get(); - // don't use override mat here, it has 'hacked ids' - // and values, use end result. - LLGLTFMaterial* cmp_mat = func.mMaterial.get(); - - me->setBaseColor(cmp_mat->mBaseColor); - me->setMetalnessFactor(cmp_mat->mMetallicFactor); - me->setRoughnessFactor(cmp_mat->mRoughnessFactor); - me->setEmissiveColor(cmp_mat->mEmissiveColor); - me->setDoubleSided(cmp_mat->mDoubleSided); - me->setAlphaMode(cmp_mat->getAlphaMode()); - me->setAlphaCutoff(cmp_mat->mAlphaCutoff); + // don't use override material here, it has 'hacked ids' + // and values, use end result, apply it on top of local. + me->setBaseColor(render_material->mBaseColor); + me->setMetalnessFactor(render_material->mMetallicFactor); + me->setRoughnessFactor(render_material->mRoughnessFactor); + me->setEmissiveColor(render_material->mEmissiveColor); + me->setDoubleSided(render_material->mDoubleSided); + me->setAlphaMode(render_material->getAlphaMode()); + me->setAlphaCutoff(render_material->mAlphaCutoff); // most things like colors we can apply without verifying // but texture ids are going to be different from both, base and override // so only apply override id if there is actually a difference - if (local_mat->mBaseColorId != cmp_mat->mBaseColorId) + if (local_material->mBaseColorId != render_material->mBaseColorId) { - me->setBaseColorId(cmp_mat->mBaseColorId); + me->setBaseColorId(render_material->mBaseColorId); me->childSetValue("base_color_upload_fee", me->getString("no_upload_fee_string")); } - if (local_mat->mNormalId != cmp_mat->mNormalId) + if (local_material->mNormalId != render_material->mNormalId) { - me->setNormalId(cmp_mat->mNormalId); + me->setNormalId(render_material->mNormalId); me->childSetValue("normal_upload_fee", me->getString("no_upload_fee_string")); } - if (local_mat->mMetallicRoughnessId != cmp_mat->mMetallicRoughnessId) + if (local_material->mMetallicRoughnessId != render_material->mMetallicRoughnessId) { - me->setMetallicRoughnessId(cmp_mat->mMetallicRoughnessId); + me->setMetallicRoughnessId(render_material->mMetallicRoughnessId); me->childSetValue("metallic_upload_fee", me->getString("no_upload_fee_string")); } - if (local_mat->mEmissiveId != cmp_mat->mEmissiveId) + if (local_material->mEmissiveId != render_material->mEmissiveId) { - me->setEmissiveId(cmp_mat->mEmissiveId); + me->setEmissiveId(render_material->mEmissiveId); me->childSetValue("emissive_upload_fee", me->getString("no_upload_fee_string")); } @@ -1879,9 +1925,9 @@ void LLMaterialEditor::saveObjectsMaterialAs() } LLSD payload; - if (func.mMaterial.notNull()) + if (render_material) { - payload["data"] = func.mMaterial->asJSON(); + payload["data"] = render_material->asJSON(); } else { -- cgit v1.3 From 361571cdb330dea18ad5a3575d7b06c69371e11b Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 29 Nov 2022 13:51:23 -0800 Subject: SL-18732: Use override update callback for LLMaterialEditor::updateLive as well --- indra/newview/llgltfmateriallist.cpp | 6 ------ indra/newview/llmaterialeditor.cpp | 3 +++ 2 files changed, 3 insertions(+), 6 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index cff2d22f18..8142762dfe 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -32,7 +32,6 @@ #include "lldispatcher.h" #include "llfetchedgltfmaterial.h" #include "llfilesystem.h" -#include "llmaterialeditor.h" #include "llsdserialize.h" #include "lltinygltfhelper.h" #include "llviewercontrol.h" @@ -294,7 +293,6 @@ public: } else if (obj && obj->isAnySelected()) { - LLMaterialEditor::updateLive(object_override.mObjectId, results[i].mSide); for (auto& override_update_callback : callbacks) { override_update_callback(object_override.mObjectId, results[i].mSide); @@ -306,7 +304,6 @@ public: // unblock material editor if (obj && obj->isAnySelected()) { - LLMaterialEditor::updateLive(object_override.mObjectId, results[i].mSide); for (auto& override_update_callback : callbacks) { override_update_callback(object_override.mObjectId, results[i].mSide); @@ -325,7 +322,6 @@ public: obj->setTEGLTFMaterialOverride(i, nullptr); if (object_has_selection) { - LLMaterialEditor::updateLive(object_override.mObjectId, i); for (auto& override_update_callback : callbacks) { override_update_callback(object_override.mObjectId, i); @@ -343,7 +339,6 @@ public: obj->setTEGLTFMaterialOverride(i, nullptr); if (object_has_selection) { - LLMaterialEditor::updateLive(obj->getID(), i); for (auto& override_update_callback : callbacks) { override_update_callback(obj->getID(), i); @@ -395,7 +390,6 @@ void LLGLTFMaterialList::applyQueuedOverrides(LLViewerObject* obj) obj->setTEGLTFMaterialOverride(i, overrides[i]); if (object_has_selection) { - LLMaterialEditor::updateLive(id, i); for (auto& override_update_callback : handle_gltf_override_message.mCallbacks) { override_update_callback(id, i); diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index d5339777c4..f1fd276402 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -399,6 +399,9 @@ BOOL LLMaterialEditor::postBuild() if (mIsOverride) { + // Material override change success callback + LLGLTFMaterialList::addUpdateCallback(&LLMaterialEditor::updateLive); + // Live editing needs a recovery mechanism on cancel mBaseColorTextureCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_BASE_COLOR_TEX_DIRTY)); mMetallicTextureCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY)); -- cgit v1.3 From bfcb07270ed7036c87a4ece7fa1f5416123fff85 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 29 Nov 2022 15:20:44 -0800 Subject: SL-18732: Review feedback --- indra/newview/llgltfmateriallist.cpp | 56 ++++++++++++++++-------------------- indra/newview/llgltfmateriallist.h | 2 +- indra/newview/llmaterialeditor.cpp | 2 +- indra/newview/llpanelface.cpp | 6 ++-- indra/newview/llpanelface.h | 2 +- 5 files changed, 30 insertions(+), 38 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index 048085fb71..d04a674e91 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -148,7 +148,7 @@ public: void addCallback(void(*callback)(const LLUUID& object_id, S32 side)) { - mCallbacks.push_back(callback); + mSelectionCallbacks.push_back(callback); } bool operator()(const LLDispatcher* dispatcher, const std::string& key, const LLUUID& invoice, const sparam_t& strings) override @@ -214,6 +214,14 @@ public: return true; } + void doSelectionCallbacks(const LLUUID& object_id, S32 side) + { + for (auto& callback : mSelectionCallbacks) + { + callback(object_id, side); + } + } + void applyData(const LLGLTFOverrideCacheEntry &object_override) { // Parse the data @@ -289,41 +297,31 @@ public: // object not ready to receive override data, queue for later gGLTFMaterialList.queueOverrideUpdate(object_override.mObjectId, results[i].mSide, results[i].mMaterial); } - else if (obj && obj->isAnySelected()) + else if (obj && obj->getTE(i) && obj->getTE(i)->isSelected()) { - for (auto& override_update_callback : mCallbacks) - { - override_update_callback(object_override.mObjectId, results[i].mSide); - } + doSelectionCallbacks(object_override.mObjectId, results[i].mSide); } } else { // unblock material editor - if (obj && obj->isAnySelected()) + if (obj && obj->getTE(i) && obj->getTE(i)->isSelected()) { - for (auto& override_update_callback : mCallbacks) - { - override_update_callback(object_override.mObjectId, results[i].mSide); - } + doSelectionCallbacks(object_override.mObjectId, results[i].mSide); } } } if (obj && side_set.size() != obj->getNumTEs()) { // object exists and at least one texture entry needs to have its override data nulled out - bool object_has_selection = obj->isAnySelected(); for (int i = 0; i < obj->getNumTEs(); ++i) { if (side_set.find(i) == side_set.end()) { obj->setTEGLTFMaterialOverride(i, nullptr); - if (object_has_selection) + if (obj->getTE(i) && obj->getTE(i)->isSelected()) { - for (auto& override_update_callback : mCallbacks) - { - override_update_callback(object_override.mObjectId, i); - } + doSelectionCallbacks(object_override.mObjectId, i); } } } @@ -331,23 +329,21 @@ public: } else if (obj) { // override list was empty or an error occurred, null out all overrides for this object - bool object_has_selection = obj->isAnySelected(); for (int i = 0; i < obj->getNumTEs(); ++i) { obj->setTEGLTFMaterialOverride(i, nullptr); - if (object_has_selection) + if (obj->getTE(i) && obj->getTE(i)->isSelected()) { - for (auto& override_update_callback : mCallbacks) - { - override_update_callback(obj->getID(), i); - } + doSelectionCallbacks(obj->getID(), i); } } } }); } - std::vector mCallbacks; +private: + + std::vector mSelectionCallbacks; }; namespace @@ -375,23 +371,19 @@ void LLGLTFMaterialList::applyQueuedOverrides(LLViewerObject* obj) if (iter != mQueuedOverrides.end()) { - bool object_has_selection = obj->isAnySelected(); override_list_t& overrides = iter->second; for (int i = 0; i < overrides.size(); ++i) { if (overrides[i].notNull()) { - if (!obj->getTE(i)->getGLTFMaterial()) + if (!obj->getTE(i) || !obj->getTE(i)->getGLTFMaterial()) { // object doesn't have its base GLTF material yet, don't apply override (yet) return; } obj->setTEGLTFMaterialOverride(i, overrides[i]); - if (object_has_selection) + if (obj->getTE(i)->isSelected()) { - for (auto& override_update_callback : handle_gltf_override_message.mCallbacks) - { - override_update_callback(id, i); - } + handle_gltf_override_message.doSelectionCallbacks(id, i); } } } @@ -480,7 +472,7 @@ void LLGLTFMaterialList::flushUpdates(void(*done_callback)(bool)) } } -void LLGLTFMaterialList::addUpdateCallback(void(*update_callback)(const LLUUID& object_id, S32 side)) +void LLGLTFMaterialList::addSelectionUpdateCallback(void(*update_callback)(const LLUUID& object_id, S32 side)) { handle_gltf_override_message.addCallback(update_callback); } diff --git a/indra/newview/llgltfmateriallist.h b/indra/newview/llgltfmateriallist.h index 5a184f5e94..abbb755599 100644 --- a/indra/newview/llgltfmateriallist.h +++ b/indra/newview/llgltfmateriallist.h @@ -75,7 +75,7 @@ public: // for cases that care about the done_callback forwarded to LLCoros::instance().launch static void flushUpdates(void(*done_callback)(bool) = nullptr); - static void addUpdateCallback(void(*update_callback)(const LLUUID& object_id, S32 side)); + static void addSelectionUpdateCallback(void(*update_callback)(const LLUUID& object_id, S32 side)); // Queue an explicit LLSD ModifyMaterialParams update apply given override data // overrides -- LLSD map (or array of maps) in the format: diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index f1fd276402..8c8a07bc21 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -400,7 +400,7 @@ BOOL LLMaterialEditor::postBuild() if (mIsOverride) { // Material override change success callback - LLGLTFMaterialList::addUpdateCallback(&LLMaterialEditor::updateLive); + LLGLTFMaterialList::addSelectionUpdateCallback(&LLMaterialEditor::updateLive); // Live editing needs a recovery mechanism on cancel mBaseColorTextureCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_BASE_COLOR_TEX_DIRTY)); diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 21c824ff5c..3d72865f69 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -276,7 +276,7 @@ BOOL LLPanelFace::postBuild() getChild("gltfTextureOffsetU")->setCommitCallback(boost::bind(&LLPanelFace::onCommitGLTFTextureOffsetU, this, _1), nullptr); getChild("gltfTextureOffsetV")->setCommitCallback(boost::bind(&LLPanelFace::onCommitGLTFTextureOffsetV, this, _1), nullptr); - LLGLTFMaterialList::addUpdateCallback(&LLPanelFace::onMaterialOverrideReceived); + LLGLTFMaterialList::addSelectionUpdateCallback(&LLPanelFace::onMaterialOverrideReceived); sMaterialOverrideSelection.connect(); childSetAction("button align",&LLPanelFace::onClickAutoFix,this); @@ -2056,7 +2056,7 @@ void LLPanelFace::unloadMedia() // static void LLPanelFace::onMaterialOverrideReceived(const LLUUID& object_id, S32 side) { - sMaterialOverrideSelection.onObjectUpdated(object_id, side); + sMaterialOverrideSelection.onSelectedObjectUpdated(object_id, side); } ////////////////////////////////////////////////////////////////////////////// @@ -4771,7 +4771,7 @@ void LLPanelFace::Selection::setObjectUpdatePending(const LLUUID &object_id, S32 mPendingSide = side; } -void LLPanelFace::Selection::onObjectUpdated(const LLUUID& object_id, S32 side) +void LLPanelFace::Selection::onSelectedObjectUpdated(const LLUUID& object_id, S32 side) { if (object_id == mSelectedObjectID && side == mSelectedSide) { diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 520b399d42..24bc973bde 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -487,7 +487,7 @@ private: // Callbacks void onSelectionChanged() { mNeedsSelectionCheck = true; } - void onObjectUpdated(const LLUUID &object_id, S32 side); + void onSelectedObjectUpdated(const LLUUID &object_id, S32 side); protected: void clearObjectUpdatePending(); -- cgit v1.3