diff options
author | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2022-11-08 01:22:08 +0200 |
---|---|---|
committer | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2022-11-08 01:22:08 +0200 |
commit | 080421decbac73c85d878b7e734ad4e2cfb0f251 (patch) | |
tree | dd01c64168bf7856be9d84b93246f2c3b0f3a9b3 /indra/newview/llmaterialeditor.cpp | |
parent | 2b1ff7495df8e94ec47255616c81291ec0ba75d4 (diff) |
SL-18583 Make Live Material editor restore changes when canceling in texture or color pickers
Diffstat (limited to 'indra/newview/llmaterialeditor.cpp')
-rw-r--r-- | indra/newview/llmaterialeditor.cpp | 311 |
1 files changed, 234 insertions, 77 deletions
diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 9173981c01..7a23d8da37 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -31,6 +31,7 @@ #include "llagent.h" #include "llagentbenefits.h" #include "llappviewer.h" +#include "llcolorswatch.h" #include "llcombobox.h" #include "llfloaterreg.h" #include "llfilesystem.h" @@ -334,6 +335,7 @@ bool LLSelectedTEGetMatData::apply(LLViewerObject* objectp, S32 te_index) LLMaterialEditor::LLMaterialEditor(const LLSD& key) : LLPreview(key) , mUnsavedChanges(0) + , mRevertedChanges(0) , mExpectedUploadCost(0) , mUploadingTexturesCount(0) { @@ -373,11 +375,28 @@ BOOL LLMaterialEditor::postBuild() mMetallicTextureCtrl = getChild<LLTextureCtrl>("metallic_roughness_texture"); mEmissiveTextureCtrl = getChild<LLTextureCtrl>("emissive_texture"); mNormalTextureCtrl = getChild<LLTextureCtrl>("normal_texture"); + mBaseColorCtrl = getChild<LLColorSwatchCtrl>("base color"); + mEmissiveColorCtrl = getChild<LLColorSwatchCtrl>("emissive color"); - mBaseColorTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitBaseColorTexture, this, _1, _2)); - mMetallicTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitMetallicTexture, this, _1, _2)); - mEmissiveTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitEmissiveTexture, this, _1, _2)); - mNormalTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitNormalTexture, this, _1, _2)); + mBaseColorTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitTexture, this, _1, _2, MATERIAL_BASE_COLOR_TEX_DIRTY)); + mMetallicTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitTexture, this, _1, _2, MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY)); + mEmissiveTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitTexture, this, _1, _2, MATERIAL_EMISIVE_TEX_DIRTY)); + mNormalTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitTexture, this, _1, _2, MATERIAL_NORMAL_TEX_DIRTY)); + + if (mIsOverride) + { + // 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)); + mEmissiveTextureCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_EMISIVE_TEX_DIRTY)); + mNormalTextureCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_NORMAL_TEX_DIRTY)); + + // Save applied changes on 'OK' to our recovery mechanism. + mBaseColorTextureCtrl->setOnSelectCallback(boost::bind(&LLMaterialEditor::onSelectCtrl, this, _1, _2, MATERIAL_BASE_COLOR_TEX_DIRTY)); + mMetallicTextureCtrl->setOnSelectCallback(boost::bind(&LLMaterialEditor::onSelectCtrl, this, _1, _2, MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY)); + mEmissiveTextureCtrl->setOnSelectCallback(boost::bind(&LLMaterialEditor::onSelectCtrl, this, _1, _2, MATERIAL_EMISIVE_TEX_DIRTY)); + mNormalTextureCtrl->setOnSelectCallback(boost::bind(&LLMaterialEditor::onSelectCtrl, this, _1, _2, MATERIAL_NORMAL_TEX_DIRTY)); + } if (!mIsOverride) { @@ -413,7 +432,13 @@ BOOL LLMaterialEditor::postBuild() childSetCommitCallback("double sided", changes_callback, (void*)&MATERIAL_DOUBLE_SIDED_DIRTY); // BaseColor - childSetCommitCallback("base color", changes_callback, (void*)&MATERIAL_BASE_COLOR_DIRTY); + mBaseColorCtrl->setCommitCallback(changes_callback, (void*)&MATERIAL_BASE_COLOR_DIRTY); + if (mIsOverride) + { + mBaseColorCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_BASE_COLOR_DIRTY)); + mBaseColorCtrl->setOnSelectCallback(boost::bind(&LLMaterialEditor::onSelectCtrl, this, _1, _2, MATERIAL_BASE_COLOR_DIRTY)); + } + // transparency is a part of base color childSetCommitCallback("transparency", changes_callback, (void*)&MATERIAL_BASE_COLOR_DIRTY); childSetCommitCallback("alpha mode", changes_callback, (void*)&MATERIAL_ALPHA_MODE_DIRTY); childSetCommitCallback("alpha cutoff", changes_callback, (void*)&MATERIAL_ALPHA_CUTOFF_DIRTY); @@ -423,7 +448,12 @@ BOOL LLMaterialEditor::postBuild() childSetCommitCallback("roughness factor", changes_callback, (void*)&MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY); // Emissive - childSetCommitCallback("emissive color", changes_callback, (void*)&MATERIAL_EMISIVE_COLOR_DIRTY); + mEmissiveColorCtrl->setCommitCallback(changes_callback, (void*)&MATERIAL_EMISIVE_COLOR_DIRTY); + if (mIsOverride) + { + mEmissiveColorCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_EMISIVE_COLOR_DIRTY)); + mEmissiveColorCtrl->setOnSelectCallback(boost::bind(&LLMaterialEditor::onSelectCtrl, this, _1, _2, MATERIAL_EMISIVE_COLOR_DIRTY)); + } if (!mIsOverride) { @@ -527,14 +557,14 @@ void LLMaterialEditor::setBaseColorUploadId(const LLUUID& id) LLColor4 LLMaterialEditor::getBaseColor() { - LLColor4 ret = linearColor4(LLColor4(childGetValue("base color"))); + LLColor4 ret = linearColor4(LLColor4(mBaseColorCtrl->getValue())); ret.mV[3] = getTransparency(); return ret; } void LLMaterialEditor::setBaseColor(const LLColor4& color) { - childSetValue("base color", srgbColor4(color).getValue()); + mBaseColorCtrl->setValue(srgbColor4(color).getValue()); setTransparency(color.mV[3]); } @@ -644,12 +674,12 @@ void LLMaterialEditor::setEmissiveUploadId(const LLUUID& id) LLColor4 LLMaterialEditor::getEmissiveColor() { - return linearColor4(LLColor4(childGetValue("emissive color"))); + return linearColor4(LLColor4(mEmissiveColorCtrl->getValue())); } void LLMaterialEditor::setEmissiveColor(const LLColor4& color) { - childSetValue("emissive color", srgbColor4(color).getValue()); + mEmissiveColorCtrl->setValue(srgbColor4(color).getValue()); } LLUUID LLMaterialEditor::getNormalId() @@ -689,6 +719,7 @@ void LLMaterialEditor::setDoubleSided(bool double_sided) void LLMaterialEditor::resetUnsavedChanges() { mUnsavedChanges = 0; + mRevertedChanges = 0; if (!mIsOverride) { childSetVisible("unsaved_changes", false); @@ -794,85 +825,142 @@ void LLMaterialEditor::setEnableEditing(bool can_modify) mNormalTextureCtrl->setEnabled(can_modify); } -void LLMaterialEditor::onCommitBaseColorTexture(LLUICtrl * ctrl, const LLSD & data) +void LLMaterialEditor::onCommitTexture(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag) { if (!mIsOverride) { - // might be better to use arrays, to have a single callback - // and not to repeat the same thing for each tecture control - LLUUID new_val = mBaseColorTextureCtrl->getValue().asUUID(); - if (new_val == mBaseColorTextureUploadId && mBaseColorTextureUploadId.notNull()) + std::string upload_fee_ctrl_name; + LLUUID old_uuid; + + switch (dirty_flag) + { + case MATERIAL_BASE_COLOR_TEX_DIRTY: + { + upload_fee_ctrl_name = "base_color_upload_fee"; + old_uuid = mBaseColorTextureUploadId; + break; + } + case MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY: { - childSetValue("base_color_upload_fee", getString("upload_fee_string")); + upload_fee_ctrl_name = "metallic_upload_fee"; + old_uuid = mMetallicTextureUploadId; + break; + } + case MATERIAL_EMISIVE_TEX_DIRTY: + { + upload_fee_ctrl_name = "emissive_upload_fee"; + old_uuid = mEmissiveTextureUploadId; + break; + } + case MATERIAL_NORMAL_TEX_DIRTY: + { + upload_fee_ctrl_name = "normal_upload_fee"; + old_uuid = mNormalTextureUploadId; + break; + } + default: + break; + } + LLUUID new_val = ctrl->getValue().asUUID(); + if (new_val == old_uuid && old_uuid.notNull()) + { + childSetValue(upload_fee_ctrl_name, getString("upload_fee_string")); } else { // Texture picker has 'apply now' with 'cancel' support. - // Keep mBaseColorJ2C and mBaseColorFetched, it's our storage in - // case user decides to cancel changes. + // Don't clean mBaseColorJ2C and mBaseColorFetched, it's our + // storage in case user decides to cancel changes. // Without mBaseColorFetched, viewer will eventually cleanup // the texture that is not in use - childSetValue("base_color_upload_fee", getString("no_upload_fee_string")); + childSetValue(upload_fee_ctrl_name, getString("no_upload_fee_string")); } } - markChangesUnsaved(MATERIAL_BASE_COLOR_TEX_DIRTY); + + markChangesUnsaved(dirty_flag); applyToSelection(); } -void LLMaterialEditor::onCommitMetallicTexture(LLUICtrl * ctrl, const LLSD & data) +void LLMaterialEditor::onCancelCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag) { - if (!mIsOverride) - { - LLUUID new_val = mMetallicTextureCtrl->getValue().asUUID(); - if (new_val == mMetallicTextureUploadId && mMetallicTextureUploadId.notNull()) - { - childSetValue("metallic_upload_fee", getString("upload_fee_string")); - } - else - { - childSetValue("metallic_upload_fee", getString("no_upload_fee_string")); - } - } - markChangesUnsaved(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY); + mRevertedChanges |= dirty_flag; applyToSelection(); } -void LLMaterialEditor::onCommitEmissiveTexture(LLUICtrl * ctrl, const LLSD & data) +void LLMaterialEditor::onSelectCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag) { - if (!mIsOverride) - { - LLUUID new_val = mEmissiveTextureCtrl->getValue().asUUID(); - if (new_val == mEmissiveTextureUploadId && mEmissiveTextureUploadId.notNull()) - { - childSetValue("emissive_upload_fee", getString("upload_fee_string")); - } - else - { - childSetValue("emissive_upload_fee", getString("no_upload_fee_string")); - } - } - markChangesUnsaved(MATERIAL_EMISIVE_TEX_DIRTY); + mUnsavedChanges |= dirty_flag; applyToSelection(); -} -void LLMaterialEditor::onCommitNormalTexture(LLUICtrl * ctrl, const LLSD & data) -{ - if (!mIsOverride) + struct f : public LLSelectedNodeFunctor { - LLUUID new_val = mNormalTextureCtrl->getValue().asUUID(); - if (new_val == mNormalTextureUploadId && mNormalTextureUploadId.notNull()) + f(LLUICtrl* ctrl, S32 dirty_flag) : mCtrl(ctrl), mDirtyFlag(dirty_flag) { - childSetValue("normal_upload_fee", getString("upload_fee_string")); } - else + + virtual bool apply(LLSelectNode* nodep) { - childSetValue("normal_upload_fee", getString("no_upload_fee_string")); + LLViewerObject* objectp = nodep->getObject(); + if (!objectp) + { + return false; + } + S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); // avatars have TEs but no faces + for (S32 te = 0; te < num_tes; ++te) + { + if (nodep->isTESelected(te) && nodep->mSavedGLTFRenderMaterials.size() > te) + { + switch (mDirtyFlag) + { + //Textures + case MATERIAL_BASE_COLOR_TEX_DIRTY: + { + nodep->mSavedGLTFRenderMaterials[te]->mBaseColorId = mCtrl->getValue().asUUID(); + break; + } + case MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY: + { + nodep->mSavedGLTFRenderMaterials[te]->mMetallicRoughnessId = mCtrl->getValue().asUUID(); + break; + } + case MATERIAL_EMISIVE_TEX_DIRTY: + { + nodep->mSavedGLTFRenderMaterials[te]->mEmissiveId = mCtrl->getValue().asUUID(); + break; + } + case MATERIAL_NORMAL_TEX_DIRTY: + { + nodep->mSavedGLTFRenderMaterials[te]->mNormalId = mCtrl->getValue().asUUID(); + break; + } + // Colors + case MATERIAL_BASE_COLOR_DIRTY: + { + LLColor4 ret = linearColor4(LLColor4(mCtrl->getValue())); + // except transparency + ret.mV[3] = nodep->mSavedGLTFRenderMaterials[te]->mBaseColor.mV[3]; + nodep->mSavedGLTFRenderMaterials[te]->mBaseColor = ret; + break; + } + case MATERIAL_EMISIVE_COLOR_DIRTY: + { + nodep->mSavedGLTFRenderMaterials[te]->mEmissiveColor = LLColor4(mCtrl->getValue()); + break; + } + default: + break; + } + } + } + return true; } - } - markChangesUnsaved(MATERIAL_NORMAL_TEX_DIRTY); - applyToSelection(); -} + LLUICtrl* mCtrl; + S32 mDirtyFlag; + } func(ctrl, dirty_flag); + + LLSelectMgr::getInstance()->getSelection()->applyToNodes(&func); +} static void write_color(const LLColor4& color, std::vector<double>& c) { @@ -2254,7 +2342,7 @@ private: LLUUID mMatId; }; -class LLRenderMaterialOverrideFunctor : public LLSelectedTEFunctor +class LLRenderMaterialOverrideFunctor : public LLSelectedNodeFunctor { public: LLRenderMaterialOverrideFunctor( @@ -2270,16 +2358,29 @@ public: { } - bool apply(LLViewerObject* objectp, S32 te) override + virtual bool apply(LLSelectNode* nodep) override { + LLViewerObject* objectp = nodep->getObject(); + if (!objectp || !objectp->permModify() || !objectp->getVolume()) + { + return false; + } + S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); // avatars have TEs but no faces + // post override from given object and te to the simulator // requestData should have: // object_id - UUID of LLViewerObject // side - S32 index of texture entry // gltf_json - String of GLTF json for override data - if (objectp && objectp->permModify() && objectp->getVolume()) + for (S32 te = 0; te < num_tes; ++te) { + if (!nodep->isTESelected(te)) + { + continue; + } + + // Get material from object // Selection can cover multiple objects, and live editor is // supposed to overwrite changed values only @@ -2293,59 +2394,114 @@ public: return false; } + // make a copy to not invalidate existing // material for multiple objects material = new LLGLTFMaterial(*material); + U32 changed_flags = mEditor->getUnsavedChangesFlags(); + U32 reverted_flags = mEditor->getRevertedChangesFlags(); + bool can_revert = nodep->mSavedGLTFRenderMaterials.size() > te; + // Override object's values with values from editor where appropriate - if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_COLOR_DIRTY) + if (changed_flags & MATERIAL_BASE_COLOR_DIRTY) { material->setBaseColorFactor(mEditor->getBaseColor(), true); } - if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_COLOR_TEX_DIRTY) + else if ((reverted_flags & MATERIAL_BASE_COLOR_DIRTY) && can_revert) + { + material->setBaseColorFactor(nodep->mSavedGLTFRenderMaterials[te]->mBaseColor, true); + } + + if (changed_flags & MATERIAL_BASE_COLOR_TEX_DIRTY) { material->setBaseColorId(mEditor->getBaseColorId(), true); } + else if ((reverted_flags & MATERIAL_BASE_COLOR_TEX_DIRTY) && can_revert) + { + material->setBaseColorId(nodep->mSavedGLTFRenderMaterials[te]->mBaseColorId, true); + } - if (mEditor->getUnsavedChangesFlags() & MATERIAL_NORMAL_TEX_DIRTY) + if (changed_flags & MATERIAL_NORMAL_TEX_DIRTY) { material->setNormalId(mEditor->getNormalId(), true); } + else if ((reverted_flags & MATERIAL_NORMAL_TEX_DIRTY) && can_revert) + { + material->setNormalId(nodep->mSavedGLTFRenderMaterials[te]->mNormalId, true); + } - if (mEditor->getUnsavedChangesFlags() & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) + if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) { material->setMetallicRoughnessId(mEditor->getMetallicRoughnessId(), true); } - if (mEditor->getUnsavedChangesFlags() & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY) + else if ((reverted_flags & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) && can_revert) + { + material->setMetallicRoughnessId(nodep->mSavedGLTFRenderMaterials[te]->mMetallicRoughnessId, true); + } + + if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY) { material->setMetallicFactor(mEditor->getMetalnessFactor(), true); } - if (mEditor->getUnsavedChangesFlags() & MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY) + else if ((reverted_flags & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY) && can_revert) + { + material->setMetallicFactor(nodep->mSavedGLTFRenderMaterials[te]->mMetallicFactor, true); + } + + if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY) { material->setRoughnessFactor(mEditor->getRoughnessFactor(), true); } + else if ((reverted_flags & MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY) && can_revert) + { + material->setRoughnessFactor(nodep->mSavedGLTFRenderMaterials[te]->mRoughnessFactor, true); + } - if (mEditor->getUnsavedChangesFlags() & MATERIAL_EMISIVE_COLOR_DIRTY) + if (changed_flags & MATERIAL_EMISIVE_COLOR_DIRTY) { material->setEmissiveColorFactor(LLColor3(mEditor->getEmissiveColor()), true); } - if (mEditor->getUnsavedChangesFlags() & MATERIAL_EMISIVE_TEX_DIRTY) + else if ((reverted_flags & MATERIAL_EMISIVE_COLOR_DIRTY) && can_revert) + { + material->setEmissiveColorFactor(nodep->mSavedGLTFRenderMaterials[te]->mEmissiveColor, true); + } + + if (changed_flags & MATERIAL_EMISIVE_TEX_DIRTY) { material->setEmissiveId(mEditor->getEmissiveId(), true); } + else if ((reverted_flags & MATERIAL_EMISIVE_TEX_DIRTY) && can_revert) + { + material->setEmissiveId(nodep->mSavedGLTFRenderMaterials[te]->mEmissiveId, true); + } - if (mEditor->getUnsavedChangesFlags() & MATERIAL_DOUBLE_SIDED_DIRTY) + if (changed_flags & MATERIAL_DOUBLE_SIDED_DIRTY) { material->setDoubleSided(mEditor->getDoubleSided(), true); } - if (mEditor->getUnsavedChangesFlags() & MATERIAL_ALPHA_MODE_DIRTY) + else if ((reverted_flags & MATERIAL_DOUBLE_SIDED_DIRTY) && can_revert) + { + material->setDoubleSided(nodep->mSavedGLTFRenderMaterials[te]->mDoubleSided, true); + } + + if (changed_flags & MATERIAL_ALPHA_MODE_DIRTY) { material->setAlphaMode(mEditor->getAlphaMode(), true); } - if (mEditor->getUnsavedChangesFlags() & MATERIAL_ALPHA_CUTOFF_DIRTY) + else if ((reverted_flags & MATERIAL_ALPHA_MODE_DIRTY) && can_revert) + { + material->setAlphaMode(nodep->mSavedGLTFRenderMaterials[te]->mAlphaMode, true); + } + + if (changed_flags & MATERIAL_ALPHA_CUTOFF_DIRTY) { material->setAlphaCutoff(mEditor->getAlphaCutoff(), true); } + else if ((reverted_flags & MATERIAL_ALPHA_CUTOFF_DIRTY) && can_revert) + { + material->setAlphaCutoff(nodep->mSavedGLTFRenderMaterials[te]->mAlphaCutoff, true); + } std::string overrides_json = material->asJSON(); @@ -2413,12 +2569,12 @@ void LLMaterialEditor::applyToSelection() // Don't send data if there is nothing to send. // Some UI elements will cause multiple commits, // like spin ctrls on click and on down - if (mUnsavedChanges != 0) + if (mUnsavedChanges != 0 || mRevertedChanges != 0) { mOverrideInProgress = true; LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); LLRenderMaterialOverrideFunctor override_func(this, url, mOverrideObjectId, mOverrideObjectTE); - selected_objects->applyToTEs(&override_func); + selected_objects->applyToNodes(&override_func); if (!override_func.getResult()) { // OverrideFunctor didn't find expected object or face @@ -2427,6 +2583,7 @@ void LLMaterialEditor::applyToSelection() // we posted all changes mUnsavedChanges = 0; + mRevertedChanges = 0; } } else |