diff options
Diffstat (limited to 'indra/newview/llpanelface.cpp')
-rw-r--r-- | indra/newview/llpanelface.cpp | 485 |
1 files changed, 351 insertions, 134 deletions
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index ba379f77d8..cb28fb4770 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -51,6 +51,7 @@ #include "llinventorymodelbackgroundfetch.h" #include "llfloatermediasettings.h" #include "llfloaterreg.h" +#include "llfloatertools.h" #include "lllineeditor.h" #include "llmaterialmgr.h" #include "llmaterialeditor.h" @@ -77,6 +78,7 @@ #include "llviewerregion.h" #include "llviewerstats.h" #include "llvovolume.h" +#include "llvoinventorylistener.h" #include "lluictrlfactory.h" #include "llpluginclassmedia.h" #include "llviewertexturelist.h"// Update sel manager as to which channel we're editing so it can reflect the correct overlay UI @@ -328,7 +330,7 @@ BOOL LLPanelFace::postBuild() pbr_ctrl->setImmediateFilterPermMask(PERM_NONE); pbr_ctrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER); pbr_ctrl->setBakeTextureEnabled(false); - pbr_ctrl->setInventoryPickType(EPickInventoryType::MATERIAL); + pbr_ctrl->setInventoryPickType(LLTextureCtrl::PICK_MATERIAL); } mTextureCtrl = getChild<LLTextureCtrl>("texture control"); @@ -490,6 +492,15 @@ LLPanelFace::~LLPanelFace() unloadMedia(); } +void LLPanelFace::onVisibilityChange(BOOL new_visibility) +{ + if (new_visibility) + { + gAgent.showLatestFeatureNotification("gltf"); + } + LLPanel::onVisibilityChange(new_visibility); +} + void LLPanelFace::draw() { updateCopyTexButton(); @@ -504,6 +515,7 @@ void LLPanelFace::draw() if (sMaterialOverrideSelection.update()) { setMaterialOverridesFromSelection(); + LLMaterialEditor::updateLive(); } } @@ -520,7 +532,11 @@ void LLPanelFace::sendTexture() { id = mTextureCtrl->getImageAssetID(); } - LLSelectMgr::getInstance()->selectionSetImage(id); + if (!LLSelectMgr::getInstance()->selectionSetImage(id)) + { + // need to refresh value in texture ctrl + refresh(); + } } } @@ -987,16 +1003,19 @@ void LLPanelFace::getState() void LLPanelFace::updateUI(bool force_set_values /*false*/) { //set state of UI to match state of texture entry(ies) (calls setEnabled, setValue, etc, but NOT setVisible) - LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(); + LLViewerObject* objectp = node ? node->getObject() : NULL; - if( objectp + if (objectp && objectp->getPCode() == LL_PCODE_VOLUME && objectp->permModify()) { BOOL editable = objectp->permModify() && !objectp->isPermanentEnforced(); + BOOL attachment = objectp->isAttachment(); bool has_pbr_material; - updateUIGLTF(objectp, has_pbr_material, force_set_values); + bool has_faces_without_pbr; + updateUIGLTF(objectp, has_pbr_material, has_faces_without_pbr, force_set_values); const bool has_material = !has_pbr_material; @@ -1017,9 +1036,68 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) } } + // *NOTE: The "identical" variable is currently only used to decide if + // the texgen control should be tentative - this is not used by GLTF + // materials. -Cosmic;2022-11-09 + bool identical = true; // true because it is anded below + bool identical_diffuse = false; + bool identical_norm = false; + bool identical_spec = false; + + LLTextureCtrl *texture_ctrl = getChild<LLTextureCtrl>("texture control"); + LLTextureCtrl *shinytexture_ctrl = getChild<LLTextureCtrl>("shinytexture control"); + LLTextureCtrl *bumpytexture_ctrl = getChild<LLTextureCtrl>("bumpytexture control"); + + LLUUID id; + LLUUID normmap_id; + LLUUID specmap_id; + + LLSelectedTE::getTexId(id, identical_diffuse); + LLSelectedTEMaterial::getNormalID(normmap_id, identical_norm); + LLSelectedTEMaterial::getSpecularID(specmap_id, identical_spec); + + static S32 selected_te = -1; + static LLUUID prev_obj_id; + if ((LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool()) && + !LLSelectMgr::getInstance()->getSelection()->isMultipleTESelected()) + { + S32 new_selection = -1; // Don't use getLastSelectedTE, it could have been deselected + S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); + for (S32 te = 0; te < num_tes; ++te) + { + if (node->isTESelected(te)) + { + new_selection = te; + break; + } + } + + if ((new_selection != selected_te) + || (prev_obj_id != objectp->getID())) + { + bool te_has_media = objectp->getTE(new_selection) && objectp->getTE(new_selection)->hasMedia(); + bool te_has_pbr = objectp->getRenderMaterialID(new_selection).notNull(); + + if (te_has_pbr && !((mComboMatMedia->getCurrentIndex() == MATMEDIA_MEDIA) && te_has_media)) + { + mComboMatMedia->selectNthItem(MATMEDIA_PBR); + } + else if (te_has_media) + { + mComboMatMedia->selectNthItem(MATMEDIA_MEDIA); + } + else if (id.notNull() || normmap_id.notNull() || specmap_id.notNull()) + { + mComboMatMedia->selectNthItem(MATMEDIA_MATERIAL); + } + selected_te = new_selection; + prev_obj_id = objectp->getID(); + } + } + mComboMatMedia->setEnabled(editable); - LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type"); + LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type"); if (radio_mat_type->getSelectedIndex() < MATTYPE_DIFFUSE) { radio_mat_type->selectNthItem(MATTYPE_DIFFUSE); @@ -1038,34 +1116,18 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) getChildView("checkbox_sync_settings")->setEnabled(editable); childSetValue("checkbox_sync_settings", gSavedSettings.getBOOL("SyncMaterialSettings")); - updateVisibility(); + updateVisibility(objectp); - // *NOTE: The "identical" variable is currently only used to decide if - // the texgen control should be tentative - this is not used by GLTF - // materials. -Cosmic;2022-11-09 - bool identical = true; // true because it is anded below - bool identical_diffuse = false; - bool identical_norm = false; - bool identical_spec = false; - - LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("texture control"); - LLTextureCtrl* shinytexture_ctrl = getChild<LLTextureCtrl>("shinytexture control"); - LLTextureCtrl* bumpytexture_ctrl = getChild<LLTextureCtrl>("bumpytexture control"); - - LLUUID id; - LLUUID normmap_id; - LLUUID specmap_id; - // Color swatch { getChildView("color label")->setEnabled(editable); } - LLColorSwatchCtrl* color_swatch = findChild<LLColorSwatchCtrl>("colorswatch"); + LLColorSwatchCtrl* color_swatch = findChild<LLColorSwatchCtrl>("colorswatch"); - LLColor4 color = LLColor4::white; - bool identical_color = false; + LLColor4 color = LLColor4::white; + bool identical_color = false; - if(color_swatch) + if (color_swatch) { LLSelectedTE::getColor(color, identical_color); LLColor4 prev_color = color_swatch->get(); @@ -1085,9 +1147,6 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) getChild<LLUICtrl>("ColorTrans")->setValue(editable ? transparency : 0); getChildView("ColorTrans")->setEnabled(editable && has_material); - // Specular map - LLSelectedTEMaterial::getSpecularID(specmap_id, identical_spec); - U8 shiny = 0; bool identical_shiny = false; @@ -1099,7 +1158,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) LLCtrlSelectionInterface* combobox_shininess = childGetSelectionInterface("combobox shininess"); if (combobox_shininess) - { + { combobox_shininess->selectNthItem((S32)shiny); } @@ -1119,8 +1178,8 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) getChild<LLUICtrl>("shinycolorswatch")->setTentative(!identical_spec); LLColorSwatchCtrl* mShinyColorSwatch = getChild<LLColorSwatchCtrl>("shinycolorswatch"); - if(mShinyColorSwatch) - { + if (mShinyColorSwatch) + { mShinyColorSwatch->setValid(editable); mShinyColorSwatch->setEnabled( editable ); mShinyColorSwatch->setCanApplyImmediately( editable ); @@ -1138,50 +1197,45 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) bumpy = norm_map_id.isNull() ? bumpy : BUMPY_TEXTURE; if (combobox_bumpiness) - { + { combobox_bumpiness->selectNthItem((S32)bumpy); - } + } else - { + { LL_WARNS() << "failed childGetSelectionInterface for 'combobox bumpiness'" << LL_ENDL; - } + } getChildView("combobox bumpiness")->setEnabled(editable); getChild<LLUICtrl>("combobox bumpiness")->setTentative(!identical_bumpy); getChildView("label bumpiness")->setEnabled(editable); - } + } // Texture { - LLSelectedTE::getTexId(id,identical_diffuse); - - // Normal map - LLSelectedTEMaterial::getNormalID(normmap_id, identical_norm); - mIsAlpha = FALSE; LLGLenum image_format = GL_RGB; bool identical_image_format = false; LLSelectedTE::getImageFormat(image_format, identical_image_format); - mIsAlpha = FALSE; - switch (image_format) - { - case GL_RGBA: - case GL_ALPHA: - { - mIsAlpha = TRUE; - } - break; - - case GL_RGB: break; - default: - { - LL_WARNS() << "Unexpected tex format in LLPanelFace...resorting to no alpha" << LL_ENDL; - } - break; + mIsAlpha = FALSE; + switch (image_format) + { + case GL_RGBA: + case GL_ALPHA: + { + mIsAlpha = TRUE; } + break; - if(LLViewerMedia::getInstance()->textureHasMedia(id)) + case GL_RGB: break; + default: + { + LL_WARNS() << "Unexpected tex format in LLPanelFace...resorting to no alpha" << LL_ENDL; + } + break; + } + + if (LLViewerMedia::getInstance()->textureHasMedia(id)) { getChildView("button align")->setEnabled(editable); } @@ -1233,7 +1287,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) } else if (id.isNull()) { - // None selected + // None selected texture_ctrl->setTentative(FALSE); texture_ctrl->setEnabled(FALSE); texture_ctrl->setImageAssetID(LLUUID::null); @@ -1246,7 +1300,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) } else { - // Tentative: multiple selected with different textures + // Tentative: multiple selected with different textures texture_ctrl->setTentative(TRUE); texture_ctrl->setEnabled(editable && !has_pbr_material); texture_ctrl->setImageAssetID(id); @@ -1257,7 +1311,18 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) texture_ctrl->setBakeTextureEnabled(TRUE); } - + + if (attachment) + { + // attachments are in world and in inventory, + // server doesn't support changing permissions + // in such case + texture_ctrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); + } + else + { + texture_ctrl->setImmediateFilterPermMask(PERM_NONE); + } } if (shinytexture_ctrl) @@ -1265,6 +1330,15 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) shinytexture_ctrl->setTentative( !identical_spec ); shinytexture_ctrl->setEnabled( editable && !has_pbr_material); shinytexture_ctrl->setImageAssetID( specmap_id ); + + if (attachment) + { + shinytexture_ctrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); + } + else + { + shinytexture_ctrl->setImmediateFilterPermMask(PERM_NONE); + } } if (bumpytexture_ctrl) @@ -1272,6 +1346,15 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) bumpytexture_ctrl->setTentative( !identical_norm ); bumpytexture_ctrl->setEnabled( editable && !has_pbr_material); bumpytexture_ctrl->setImageAssetID( normmap_id ); + + if (attachment) + { + bumpytexture_ctrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); + } + else + { + bumpytexture_ctrl->setImmediateFilterPermMask(PERM_NONE); + } } } @@ -1515,15 +1598,14 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) combobox_texgen->selectNthItem(((S32)selected_texgen) >> 1); } else - { + { LL_WARNS() << "failed childGetSelectionInterface for 'combobox texgen'" << LL_ENDL; - } + } getChildView("combobox texgen")->setEnabled(editable); getChild<LLUICtrl>("combobox texgen")->setTentative(!identical); getChildView("tex gen")->setEnabled(editable); - - } + } { U8 fullbright_flag = 0; @@ -1534,7 +1616,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) getChild<LLUICtrl>("checkbox fullbright")->setValue((S32)(fullbright_flag != 0)); getChildView("checkbox fullbright")->setEnabled(editable && !has_pbr_material); getChild<LLUICtrl>("checkbox fullbright")->setTentative(!identical_fullbright); - getChild<LLComboBox>("combobox matmedia")->setEnabledByValue("Materials", !has_pbr_material); + mComboMatMedia->setEnabledByValue("Materials", !has_pbr_material); } // Repeats per meter @@ -1553,7 +1635,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) LLComboBox* mComboTexGen = getChild<LLComboBox>("combobox texgen"); if (mComboTexGen) - { + { S32 index = mComboTexGen ? mComboTexGen->getCurrentIndex() : 0; bool enabled = editable && (index != 1); bool identical_repeats = true; @@ -1649,14 +1731,14 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) if (!mIsAlpha) { // ... unless there is no alpha channel in the texture, in which case alpha mode MUST ebe none alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE; - } + } combobox_alphamode->selectNthItem(alpha_mode); - } - else - { + } + else + { LL_WARNS() << "failed childGetSelectionInterface for 'combobox alphamode'" << LL_ENDL; - } + } getChild<LLUICtrl>("maskcutoff")->setValue(material->getAlphaMaskCutoff()); updateAlphaControls(); @@ -1668,15 +1750,15 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) texture_ctrl->setImageAssetID(material->getSpecularID()); if (!material->getSpecularID().isNull() && (shiny == SHINY_TEXTURE)) - { + { material->getSpecularOffset(offset_x,offset_y); material->getSpecularRepeat(repeat_x,repeat_y); if (identical_planar_texgen) - { + { repeat_x *= 2.0f; repeat_y *= 2.0f; - } + } rot = material->getSpecularRotation(); getChild<LLUICtrl>("shinyScaleU")->setValue(repeat_x); @@ -1688,7 +1770,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) getChild<LLUICtrl>("environment")->setValue(material->getEnvironmentIntensity()); updateShinyControls(!material->getSpecularID().isNull(), true); - } + } // Assert desired colorswatch color to match material AFTER updateShinyControls // to avoid getting overwritten with the default on some UI state changes. @@ -1756,14 +1838,14 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) pbr_ctrl->setEnabled(FALSE); } LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("texture control"); - if(texture_ctrl) + if (texture_ctrl) { texture_ctrl->setImageAssetID( LLUUID::null ); texture_ctrl->setEnabled( FALSE ); // this is a LLUICtrl, but we don't want it to have keyboard focus so we add it as a child, not a ctrl. // texture_ctrl->setValid(FALSE); } LLColorSwatchCtrl* mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch"); - if(mColorSwatch) + if (mColorSwatch) { mColorSwatch->setEnabled( FALSE ); mColorSwatch->setFallbackImage(LLUI::getUIImage("locked_image.j2c") ); @@ -1798,36 +1880,96 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) } } -void LLPanelFace::updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material, bool force_set_values) +// One-off listener that updates the build floater UI when the prim inventory updates +class PBRPickerItemListener : public LLVOInventoryListener +{ +protected: + LLViewerObject* mObjectp; + bool mChangePending = true; +public: + + PBRPickerItemListener(LLViewerObject* object) + : mObjectp(object) + { + registerVOInventoryListener(mObjectp, nullptr); + } + + const bool isListeningFor(const LLViewerObject* objectp) const + { + return mChangePending && (objectp == mObjectp); + } + + void inventoryChanged(LLViewerObject* object, + LLInventoryObject::object_list_t* inventory, + S32 serial_num, + void* user_data) override + { + if (gFloaterTools) + { + gFloaterTools->dirty(); + } + removeVOInventoryListener(); + mChangePending = false; + } + + ~PBRPickerItemListener() + { + removeVOInventoryListener(); + mChangePending = false; + } +}; + +void LLPanelFace::updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material, bool& has_faces_without_pbr, bool force_set_values) { has_pbr_material = false; - const bool editable = objectp->permModify() && !objectp->isPermanentEnforced(); bool has_pbr_capabilities = LLMaterialEditor::capabilitiesAvailable(); + bool identical_pbr = true; + const bool settable = has_pbr_capabilities && objectp->permModify() && !objectp->isPermanentEnforced(); + const bool editable = LLMaterialEditor::canModifyObjectsMaterial(); + const bool saveable = LLMaterialEditor::canSaveObjectsMaterial(); // pbr material LLTextureCtrl* pbr_ctrl = findChild<LLTextureCtrl>("pbr_control"); if (pbr_ctrl) { LLUUID pbr_id; - bool identical_pbr; - LLSelectedTE::getPbrMaterialId(pbr_id, identical_pbr); - - has_pbr_material = pbr_id.notNull(); + LLSelectedTE::getPbrMaterialId(pbr_id, identical_pbr, has_pbr_material, has_faces_without_pbr); pbr_ctrl->setTentative(identical_pbr ? FALSE : TRUE); - pbr_ctrl->setEnabled(editable && has_pbr_capabilities); + pbr_ctrl->setEnabled(settable); pbr_ctrl->setImageAssetID(pbr_id); + + if (objectp->isAttachment()) + { + pbr_ctrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER | PERM_MODIFY); + } + else + { + pbr_ctrl->setImmediateFilterPermMask(PERM_NONE); + } } - getChildView("pbr_from_inventory")->setEnabled(editable && has_pbr_capabilities); - getChildView("edit_selected_pbr")->setEnabled(editable && has_pbr_material && has_pbr_capabilities); - getChildView("save_selected_pbr")->setEnabled(objectp->permCopy() && has_pbr_material && has_pbr_capabilities); + getChildView("pbr_from_inventory")->setEnabled(settable); + getChildView("edit_selected_pbr")->setEnabled(editable && !has_faces_without_pbr); + getChildView("save_selected_pbr")->setEnabled(saveable && identical_pbr); + if (objectp->isInventoryPending()) + { + // Reuse the same listener when possible + if (!mInventoryListener || !mInventoryListener->isListeningFor(objectp)) + { + mInventoryListener = std::make_unique<PBRPickerItemListener>(objectp); + } + } + else + { + mInventoryListener = nullptr; + } const bool show_pbr = mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR && mComboMatMedia->getEnabled(); if (show_pbr) { - const bool new_state = has_pbr_capabilities && has_pbr_material; + const bool new_state = has_pbr_capabilities && has_pbr_material && !has_faces_without_pbr; LLUICtrl* gltfCtrlTextureScaleU = getChild<LLUICtrl>("gltfTextureScaleU"); LLUICtrl* gltfCtrlTextureScaleV = getChild<LLUICtrl>("gltfTextureScaleV"); @@ -1847,9 +1989,10 @@ void LLPanelFace::updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material, } } -void LLPanelFace::updateVisibilityGLTF() +void LLPanelFace::updateVisibilityGLTF(LLViewerObject* objectp /*= nullptr */) { const bool show_pbr = mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR && mComboMatMedia->getEnabled(); + const bool inventory_pending = objectp && objectp->isInventoryPending(); LLRadioGroup* radio_pbr_type = findChild<LLRadioGroup>("radio_pbr_type"); radio_pbr_type->setVisible(show_pbr); @@ -1860,8 +2003,9 @@ void LLPanelFace::updateVisibilityGLTF() getChildView("pbr_control")->setVisible(show_pbr_render_material_id); getChildView("pbr_from_inventory")->setVisible(show_pbr_render_material_id); - getChildView("edit_selected_pbr")->setVisible(show_pbr_render_material_id); - getChildView("save_selected_pbr")->setVisible(show_pbr_render_material_id); + getChildView("edit_selected_pbr")->setVisible(show_pbr_render_material_id && !inventory_pending); + getChildView("save_selected_pbr")->setVisible(show_pbr_render_material_id && !inventory_pending); + getChildView("material_permissions_loading_label")->setVisible(show_pbr_render_material_id && inventory_pending); getChildView("gltfTextureScaleU")->setVisible(show_pbr); getChildView("gltfTextureScaleV")->setVisible(show_pbr); @@ -1875,10 +2019,10 @@ void LLPanelFace::updateCopyTexButton() LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); mMenuClipboardTexture->setEnabled(objectp && objectp->getPCode() == LL_PCODE_VOLUME && objectp->permModify() && !objectp->isPermanentEnforced() && !objectp->isInventoryPending() - && (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1)); + && (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1) + && LLMaterialEditor::canClipboardObjectsMaterial()); std::string tooltip = (objectp && objectp->isInventoryPending()) ? LLTrans::getString("LoadingContents") : getString("paste_options"); mMenuClipboardTexture->setToolTip(tooltip); - } void LLPanelFace::refresh() @@ -2703,7 +2847,7 @@ void LLPanelFace::onCommitMaterialsMedia(LLUICtrl* ctrl, void* userdata) self->refreshMedia(); } -void LLPanelFace::updateVisibility() +void LLPanelFace::updateVisibility(LLViewerObject* objectp /* = nullptr */) { LLRadioGroup* radio_mat_type = findChild<LLRadioGroup>("radio_material_type"); LLRadioGroup* radio_pbr_type = findChild<LLRadioGroup>("radio_pbr_type"); @@ -2794,7 +2938,7 @@ void LLPanelFace::updateVisibility() getChild<LLSpinCtrl>("rptctrl")->setVisible(show_material || show_media); // PBR controls - updateVisibilityGLTF(); + updateVisibilityGLTF(objectp); } // static @@ -3032,7 +3176,11 @@ void LLPanelFace::onCommitPbr(const LLSD& data) { id = pbr_ctrl->getImageAssetID(); } - LLSelectMgr::getInstance()->selectionSetGLTFMaterial(id); + if (!LLSelectMgr::getInstance()->selectionSetGLTFMaterial(id)) + { + // If failed to set material, refresh pbr_ctrl's value + refresh(); + } } } @@ -3056,8 +3204,10 @@ void LLPanelFace::onSelectPbr(const LLSD& data) { id = pbr_ctrl->getImageAssetID(); } - LLSelectMgr::getInstance()->selectionSetGLTFMaterial(id); - LLSelectedTEMaterial::setMaterialID(this, id); + if (!LLSelectMgr::getInstance()->selectionSetGLTFMaterial(id)) + { + refresh(); + } } } @@ -4042,7 +4192,8 @@ void LLPanelFace::onCopyTexture() || objectp->getPCode() != LL_PCODE_VOLUME || !objectp->permModify() || objectp->isPermanentEnforced() - || selected_count > 1) + || selected_count > 1 + || !LLMaterialEditor::canClipboardObjectsMaterial()) { return; } @@ -4237,7 +4388,8 @@ void LLPanelFace::onPasteTexture() || objectp->getPCode() != LL_PCODE_VOLUME || !objectp->permModify() || objectp->isPermanentEnforced() - || selected_count > 1) + || selected_count > 1 + || !LLMaterialEditor::canClipboardObjectsMaterial()) { // not supposed to happen LL_WARNS() << "Failed to paste texture due to missing or wrong selection" << LL_ENDL; @@ -4666,13 +4818,6 @@ void LLPanelFace::updateGLTFTextureTransform(float value, U32 pbr_type, std::fun edit(&new_transform); } }); - - LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(); - if (node) - { - LLViewerObject* object = node->getObject(); - sMaterialOverrideSelection.setObjectUpdatePending(object->getID(), node->getLastSelectedTE()); - } } void LLPanelFace::setMaterialOverridesFromSelection() @@ -4785,17 +4930,22 @@ bool LLPanelFace::Selection::update() return changed; } -void LLPanelFace::Selection::setObjectUpdatePending(const LLUUID &object_id, S32 side) -{ - mPendingObjectID = object_id; - mPendingSide = side; -} - void LLPanelFace::Selection::onSelectedObjectUpdated(const LLUUID& object_id, S32 side) { - if (object_id == mSelectedObjectID && side == mSelectedSide) + if (object_id == mSelectedObjectID) { - mChanged = true; + if (side == mLastSelectedSide) + { + mChanged = true; + } + else if (mLastSelectedSide == -1) // if last selected face was deselected + { + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(); + if (node && node->isTESelected(side)) + { + mChanged = true; + } + } } } @@ -4808,8 +4958,9 @@ bool LLPanelFace::Selection::compareSelection() mNeedsSelectionCheck = false; const S32 old_object_count = mSelectedObjectCount; + const S32 old_te_count = mSelectedTECount; const LLUUID old_object_id = mSelectedObjectID; - const S32 old_side = mSelectedSide; + const S32 old_side = mLastSelectedSide; LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); LLSelectNode* node = selection->getFirstNode(); @@ -4817,17 +4968,23 @@ bool LLPanelFace::Selection::compareSelection() { LLViewerObject* object = node->getObject(); mSelectedObjectCount = selection->getObjectCount(); + mSelectedTECount = selection->getTECount(); mSelectedObjectID = object->getID(); - mSelectedSide = node->getLastSelectedTE(); + mLastSelectedSide = node->getLastSelectedTE(); } else { mSelectedObjectCount = 0; + mSelectedTECount = 0; mSelectedObjectID = LLUUID::null; - mSelectedSide = -1; + mLastSelectedSide = -1; } - const bool selection_changed = old_object_count != mSelectedObjectCount || old_object_id != mSelectedObjectID || old_side != mSelectedSide; + const bool selection_changed = + old_object_count != mSelectedObjectCount + || old_te_count != mSelectedTECount + || old_object_id != mSelectedObjectID + || old_side != mLastSelectedSide; mChanged = mChanged || selection_changed; return selection_changed; } @@ -4946,23 +5103,24 @@ void LLPanelFace::onPbrSelectionChanged(LLInventoryItem* itemp) LLSaleInfo sale_info; LLSelectMgr::instance().selectGetSaleInfo(sale_info); - bool can_copy = itemp->getPermissions().allowCopyBy(gAgentID); // do we have perm to copy this texture? - bool can_transfer = itemp->getPermissions().allowOperationBy(PERM_TRANSFER, gAgentID); // do we have perm to transfer this texture? - bool is_object_owner = gAgentID == obj_owner_id; // does object for which we are going to apply texture belong to the agent? - bool not_for_sale = !sale_info.isForSale(); // is object for which we are going to apply texture not for sale? + bool can_copy = itemp->getPermissions().allowCopyBy(gAgentID); // do we have perm to copy this material? + bool can_transfer = itemp->getPermissions().allowOperationBy(PERM_TRANSFER, gAgentID); // do we have perm to transfer this material? + bool can_modify = itemp->getPermissions().allowOperationBy(PERM_MODIFY, gAgentID); // do we have perm to transfer this material? + bool is_object_owner = gAgentID == obj_owner_id; // does object for which we are going to apply material belong to the agent? + bool not_for_sale = !sale_info.isForSale(); // is object for which we are going to apply material not for sale? - if (can_copy && can_transfer) + if (can_copy && can_transfer && can_modify) { pbr_ctrl->setCanApply(true, true); return; } - // if texture has (no-transfer) attribute it can be applied only for object which we own and is not for sale + // if material has (no-transfer) attribute it can be applied only for object which we own and is not for sale pbr_ctrl->setCanApply(false, can_transfer ? true : is_object_owner && not_for_sale); if (gSavedSettings.getBOOL("TextureLivePreview")) { - LLNotificationsUtil::add("LivePreviewUnavailable"); + LLNotificationsUtil::add("LivePreviewUnavailablePBR"); } } } @@ -5046,16 +5204,75 @@ void LLPanelFace::LLSelectedTE::getTexId(LLUUID& id, bool& identical) identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, id ); } -void LLPanelFace::LLSelectedTE::getPbrMaterialId(LLUUID& id, bool& identical) +void LLPanelFace::LLSelectedTE::getPbrMaterialId(LLUUID& id, bool& identical, bool& has_faces_with_pbr, bool& has_faces_without_pbr) { - struct LLSelectedTEGetmatId : public LLSelectedTEGetFunctor<LLUUID> + struct LLSelectedTEGetmatId : public LLSelectedTEFunctor { - LLUUID get(LLViewerObject* object, S32 te_index) + LLSelectedTEGetmatId() + : mHasFacesWithoutPBR(false) + , mHasFacesWithPBR(false) + , mIdenticalId(true) + , mIdenticalOverride(true) + , mInitialized(false) + , mMaterialOverride(LLGLTFMaterial::sDefault) { - return object->getRenderMaterialID(te_index); } + bool apply(LLViewerObject* object, S32 te_index) override + { + LLUUID pbr_id = object->getRenderMaterialID(te_index); + if (pbr_id.isNull()) + { + mHasFacesWithoutPBR = true; + } + else + { + mHasFacesWithPBR = true; + } + if (mInitialized) + { + if (mPBRId != pbr_id) + { + mIdenticalId = false; + } + + LLGLTFMaterial* te_override = object->getTE(te_index)->getGLTFMaterialOverride(); + if (te_override) + { + LLGLTFMaterial override = *te_override; + override.sanitizeAssetMaterial(); + mIdenticalOverride &= (override == mMaterialOverride); + } + else + { + mIdenticalOverride &= (mMaterialOverride == LLGLTFMaterial::sDefault); + } + } + else + { + mInitialized = true; + mPBRId = pbr_id; + LLGLTFMaterial* override = object->getTE(te_index)->getGLTFMaterialOverride(); + if (override) + { + mMaterialOverride = *override; + mMaterialOverride.sanitizeAssetMaterial(); + } + } + return true; + } + bool mHasFacesWithoutPBR; + bool mHasFacesWithPBR; + bool mIdenticalId; + bool mIdenticalOverride; + bool mInitialized; + LLGLTFMaterial mMaterialOverride; + LLUUID mPBRId; } func; - identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&func, id); + LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func); + id = func.mPBRId; + identical = func.mIdenticalId && func.mIdenticalOverride; + has_faces_with_pbr = func.mHasFacesWithPBR; + has_faces_without_pbr = func.mHasFacesWithoutPBR; } void LLPanelFace::LLSelectedTEMaterial::getCurrent(LLMaterialPtr& material_ptr, bool& identical_material) |