From 8ae0e6c07a8272c04d8a0f122e6204cf24f547af Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 25 Jul 2024 16:15:18 +0300 Subject: viewer#2102 Update feature notification to notify about Favorites and remove old notifications --- indra/newview/llpanelface.cpp | 4 ---- 1 file changed, 4 deletions(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 38af68bfff..c8e876ee7a 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -505,10 +505,6 @@ LLPanelFace::~LLPanelFace() void LLPanelFace::onVisibilityChange(BOOL new_visibility) { - if (new_visibility) - { - gAgent.showLatestFeatureNotification("gltf"); - } LLPanel::onVisibilityChange(new_visibility); } -- cgit v1.3 From a1ccb44c15b484787bce34e06adb0396bfc6d2a4 Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko Date: Mon, 3 Mar 2025 22:29:26 +0200 Subject: #3512 Add UX for marking water exclusion surfaces --- indra/newview/llpanelface.cpp | 83 ++++++++++++++++++++-- indra/newview/llpanelface.h | 5 ++ .../newview/skins/default/xui/en/notifications.xml | 12 ++++ .../skins/default/xui/en/panel_tools_texture.xml | 8 +++ 4 files changed, 103 insertions(+), 5 deletions(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index c080d72580..692bd9cc41 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -420,6 +420,7 @@ bool LLPanelFace::postBuild() mCtrlColorTransp->setFollowsLeft(); getChildSetCommitCallback(mCheckFullbright, "checkbox fullbright", [&](LLUICtrl*, const LLSD&) { onCommitFullbright(); }); + getChildSetCommitCallback(mCheckHideWater, "checkbox_hide_water", [&](LLUICtrl*, const LLSD&) { onCommitHideWater(); }); mLabelTexGen = getChild("tex gen"); getChildSetCommitCallback(mComboTexGen, "combobox texgen", [&](LLUICtrl*, const LLSD&) { onCommitTexGen(); }); @@ -1024,6 +1025,13 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) LLSelectedTEMaterial::getNormalID(normmap_id, identical_norm); LLSelectedTEMaterial::getSpecularID(specmap_id, identical_spec); + LLColor4 color = LLColor4::white; + bool identical_color = false; + + LLSelectedTE::getColor(color, identical_color); + F32 transparency = (1.f - color.mV[VALPHA]) * 100.f; + mExcludeWater = (id == IMG_ALPHA_GRAD) && normmap_id.isNull() && specmap_id.isNull() && (transparency == 0); + static S32 selected_te = -1; static LLUUID prev_obj_id; if ((LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool()) && @@ -1098,12 +1106,26 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) updateVisibility(objectp); + // Water exclusion + { + mCheckHideWater->setEnabled(editable && !has_pbr_material && !isMediaTexSelected()); + mCheckHideWater->set(mExcludeWater); + if (mExcludeWater && !has_pbr_material) + { + mComboMatMedia->selectNthItem(MATMEDIA_MATERIAL); + } + editable &= !mExcludeWater; + + // disable controls for water exclusion face after updateVisibility, so the whole panel is not hidden + mComboMatMedia->setEnabled(editable); + mRadioMaterialType->setEnabled(editable); + mRadioPbrType->setEnabled(editable); + mCheckSyncSettings->setEnabled(editable); + } + // Color swatch mLabelColor->setEnabled(editable); - LLColor4 color = LLColor4::white; - bool identical_color = false; - LLSelectedTE::getColor(color, identical_color); LLColor4 prev_color = mColorSwatch->get(); mColorSwatch->setOriginal(color); mColorSwatch->set(color, force_set_values || (prev_color != color) || !editable); @@ -1114,7 +1136,6 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) // Color transparency mLabelColorTransp->setEnabled(editable); - F32 transparency = (1.f - color.mV[VALPHA]) * 100.f; mCtrlColorTransp->setValue(editable ? transparency : 0); mCtrlColorTransp->setEnabled(editable && has_material); @@ -1986,7 +2007,8 @@ void LLPanelFace::updateCopyTexButton() mMenuClipboardTexture->setEnabled(objectp && objectp->getPCode() == LL_PCODE_VOLUME && objectp->permModify() && !objectp->isPermanentEnforced() && !objectp->isInventoryPending() && (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1) - && LLMaterialEditor::canClipboardObjectsMaterial()); + && LLMaterialEditor::canClipboardObjectsMaterial() + && !mExcludeWater); std::string tooltip = (objectp && objectp->isInventoryPending()) ? LLTrans::getString("LoadingContents") : getString("paste_options"); mMenuClipboardTexture->setToolTip(tooltip); } @@ -3027,6 +3049,37 @@ void LLPanelFace::onCommitFullbright() sendFullbright(); } +void LLPanelFace::onCommitHideWater() +{ + if (mCheckHideWater->get()) + { + LLHandle handle = getHandle(); + LLNotificationsUtil::add("WaterExclusionSurfacesWarning", LLSD(), LLSD(), + [handle](const LLSD& notification, const LLSD& response) + { + if(LLPanelFace* panel = (LLPanelFace*)handle.get()) + { + if (LLNotificationsUtil::getSelectedOption(notification, response) == 1) + { + panel->mCheckHideWater->setValue(false); + return; + } + // apply invisiprim texture and reset related params to set water exclusion surface + panel->sendBump(0); + panel->sendShiny(0); + LLSelectMgr::getInstance()->selectionSetAlphaOnly(1.f); + LLSelectMgr::getInstance()->selectionSetImage(IMG_ALPHA_GRAD); + LLSelectedTEMaterial::setDiffuseAlphaMode(panel, LLMaterial::DIFFUSE_ALPHA_MODE_BLEND); + } + }); + } + else + { + // reset texture to default plywood + LLSelectMgr::getInstance()->selectionSetImage(DEFAULT_OBJECT_TEXTURE); + } +} + void LLPanelFace::onCommitGlow() { sendGlow(); @@ -4891,6 +4944,26 @@ bool LLPanelFace::isIdenticalPlanarTexgen() return (identical_texgen && (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR)); } +bool LLPanelFace::isMediaTexSelected() +{ + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(); + if (LLViewerObject* objectp = node->getObject()) + { + S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); + for (S32 te = 0; te < num_tes; ++te) + { + if (node->isTESelected(te)) + { + if (objectp->getTE(te) && objectp->getTE(te)->hasMedia()) + { + return true; + } + } + } + } + return false; +} + void LLPanelFace::LLSelectedTE::getFace(LLFace*& face_to_return, bool& identical_face) { struct LLSelectedTEGetFace : public LLSelectedTEGetFunctor diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index dfd3201533..6e0d34cbd6 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -139,6 +139,8 @@ protected: void updateMediaSettings(); void updateMediaTitle(); + bool isMediaTexSelected(); + void getState(); void sendTexture(); // applies and sends texture @@ -238,6 +240,7 @@ protected: void onCommitShiny(); void onCommitAlphaMode(); void onCommitFullbright(); + void onCommitHideWater(); void onCommitGlow(); void onCommitPlanarAlign(); void onCommitRepeatsPerMeter(); @@ -308,6 +311,7 @@ private: LLRadioGroup* mRadioPbrType { nullptr }; LLCheckBoxCtrl* mCheckFullbright { nullptr }; + LLCheckBoxCtrl* mCheckHideWater{ nullptr }; LLTextBox* mLabelColorTransp { nullptr }; LLSpinCtrl* mCtrlColorTransp { nullptr }; // transparency = 1 - alpha @@ -555,6 +559,7 @@ private: LLMenuButton* mMenuClipboardTexture; bool mIsAlpha; + bool mExcludeWater { false }; LLSD mClipboardParams; diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index b5f742e5fb..dba48012ac 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -12580,4 +12580,16 @@ are wearing now. name="okbutton" yestext="OK"/> + + + Checking the hide water box will overwrite the texture, bumpiness, and shininess choices. + confirm + + diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml index e80f315259..9a19d06432 100644 --- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml +++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml @@ -123,6 +123,14 @@ name="checkbox fullbright" top_pad="4" width="81" /> + Date: Wed, 12 Mar 2025 20:07:53 +0200 Subject: #3189 Pasted PBR materials disappearing --- indra/newview/llgltfmateriallist.cpp | 16 ++++++++++++++++ indra/newview/llgltfmateriallist.h | 2 ++ indra/newview/llpanelface.cpp | 11 ++--------- 3 files changed, 20 insertions(+), 9 deletions(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index 25438eae5e..d8b3f996aa 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -353,6 +353,18 @@ void LLGLTFMaterialList::queueApply(const LLViewerObject* obj, S32 side, const L } } +void LLGLTFMaterialList::queueApply(const LLViewerObject* obj, S32 side, const LLUUID& asset_id, const std::string &override_json) +{ + if (asset_id.isNull() || override_json.empty()) + { + queueApply(obj, side, asset_id); + } + else + { + sApplyQueue.push_back({ obj->getID(), side, asset_id, nullptr, override_json }); + } +} + void LLGLTFMaterialList::queueApply(const LLViewerObject* obj, S32 side, const LLUUID& asset_id, const LLGLTFMaterial* material_override) { if (asset_id.isNull() || material_override == nullptr) @@ -456,6 +468,10 @@ void LLGLTFMaterialList::flushUpdatesOnce(std::shared_ptr callba { data[i]["gltf_json"] = e.override_data->asJSON(); } + if (!e.override_json.empty()) + { + data[i]["gltf_json"] = e.override_json; + } else { // Clear all overrides diff --git a/indra/newview/llgltfmateriallist.h b/indra/newview/llgltfmateriallist.h index e79da3592a..97d173d3a7 100644 --- a/indra/newview/llgltfmateriallist.h +++ b/indra/newview/llgltfmateriallist.h @@ -67,6 +67,7 @@ public: // // NOTE: Implicitly clears most override data if present static void queueApply(const LLViewerObject* obj, S32 side, const LLUUID& asset_id); + static void queueApply(const LLViewerObject* obj, S32 side, const LLUUID& asset_id, const std::string& override_json); // Queue an application of a material asset we want to send to the simulator. // Call "flushUpdates" to flush pending updates immediately. @@ -160,6 +161,7 @@ protected: S32 side = -1; LLUUID asset_id; LLPointer override_data; + std::string override_json; }; typedef std::list apply_queue_t; diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 692bd9cc41..f491cccaf8 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -4464,21 +4464,14 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te) tep->setGLTFRenderMaterial(nullptr); tep->setGLTFMaterialOverride(nullptr); - LLSD override_data; - override_data["object_id"] = objectp->getID(); - override_data["side"] = te; if (te_data["te"].has("pbr_override")) { - override_data["gltf_json"] = te_data["te"]["pbr_override"]; + LLGLTFMaterialList::queueApply(objectp, te, te_data["te"]["pbr"].asUUID(), te_data["te"]["pbr_override"]); } else { - override_data["gltf_json"] = ""; + LLGLTFMaterialList::queueApply(objectp, te, te_data["te"]["pbr"].asUUID()); } - - override_data["asset_id"] = te_data["te"]["pbr"].asUUID(); - - LLGLTFMaterialList::queueUpdate(override_data); } else { -- cgit v1.3 From c695ae285fc14f1cce50a1cf1757b3a6e38308b8 Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko Date: Thu, 20 Mar 2025 21:10:06 +0200 Subject: #3779 reset texture repeats when unchecking the Hide Water option --- indra/newview/llpanelface.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index f491cccaf8..c4f118fed8 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -3077,6 +3077,8 @@ void LLPanelFace::onCommitHideWater() { // reset texture to default plywood LLSelectMgr::getInstance()->selectionSetImage(DEFAULT_OBJECT_TEXTURE); + // reset texture repeats, that might be altered by invisiprim script from wiki + LLSelectMgr::getInstance()->selectionTexScaleAutofit(2.f); } } -- cgit v1.3 From 6b88a2bec27e24debb4eb4fe986850f36f8689a9 Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko Date: Mon, 24 Mar 2025 18:05:06 +0200 Subject: #3780 disable water exclusion if user applies PBR or Media --- indra/newview/llpanelface.cpp | 5 +---- indra/newview/llselectmgr.cpp | 11 ++++++++++- indra/newview/llselectmgr.h | 1 + indra/newview/llviewerobject.cpp | 25 +++++++++++++++++++++++++ indra/newview/llviewerobject.h | 2 ++ 5 files changed, 39 insertions(+), 5 deletions(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index c4f118fed8..b7d9df6ea6 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -3075,10 +3075,7 @@ void LLPanelFace::onCommitHideWater() } else { - // reset texture to default plywood - LLSelectMgr::getInstance()->selectionSetImage(DEFAULT_OBJECT_TEXTURE); - // reset texture repeats, that might be altered by invisiprim script from wiki - LLSelectMgr::getInstance()->selectionTexScaleAutofit(2.f); + LLSelectMgr::getInstance()->clearWaterExclusion(); } } diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index b307de787c..cc88d31aee 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -1995,7 +1995,7 @@ bool LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id) asset_id = BLANK_MATERIAL_ASSET_ID; } } - + objectp->clearTEWaterExclusion(te); // Blank out most override data on the object and send to server objectp->setRenderMaterialID(te, asset_id); @@ -2477,6 +2477,7 @@ void LLSelectMgr::selectionSetMedia(U8 media_type, const LLSD &media_data) } else { // Add/update media + object->clearTEWaterExclusion(te); object->setTEMediaFlags(te, mMediaFlags); LLVOVolume *vo = dynamic_cast(object); llassert(NULL != vo); @@ -7724,6 +7725,14 @@ void LLSelectMgr::setAgentHUDZoom(F32 target_zoom, F32 current_zoom) gAgentCamera.mHUDCurZoom = current_zoom; } +void LLSelectMgr::clearWaterExclusion() +{ + // reset texture to default plywood + LLSelectMgr::getInstance()->selectionSetImage(DEFAULT_OBJECT_TEXTURE); + // reset texture repeats, that might be altered by invisiprim script from wiki + LLSelectMgr::getInstance()->selectionTexScaleAutofit(2.f); +} + ///////////////////////////////////////////////////////////////////////////// // Object selection iterator helpers ///////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index b70ec3dbea..0dbdc133e3 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -836,6 +836,7 @@ public: void getAgentHUDZoom(F32 &target_zoom, F32 ¤t_zoom) const; void updatePointAt(); + void clearWaterExclusion(); // Internal list maintenance functions. TODO: Make these private! void remove(std::vector& objects); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 3d88cc5f39..c5e81dd179 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -7682,6 +7682,31 @@ void LLViewerObject::setGLTFAsset(const LLUUID& id) updateVolume(volume_params); } +void LLViewerObject::clearTEWaterExclusion(const U8 te) +{ + if (permModify()) + { + LLViewerTexture* image = getTEImage(te); + if (image && (IMG_ALPHA_GRAD == image->getID())) + { + // reset texture to default plywood + setTEImage(te, LLViewerTextureManager::getFetchedTexture(DEFAULT_OBJECT_TEXTURE, FTT_DEFAULT, true, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); + + // reset texture repeats, that might be altered by invisiprim script from wiki + U32 s_axis, t_axis; + if (!LLPrimitive::getTESTAxes(te, &s_axis, &t_axis)) + { + return; + } + F32 DEFAULT_REPEATS = 2.f; + F32 new_s = getScale().mV[s_axis] * DEFAULT_REPEATS; + F32 new_t = getScale().mV[t_axis] * DEFAULT_REPEATS; + + setTEScale(te, new_s, new_t); + sendTEUpdate(); + } + } +} class ObjectPhysicsProperties : public LLHTTPNode { diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 63458e60ea..2b52ea2076 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -405,6 +405,8 @@ public: LLViewerTexture *getTENormalMap(const U8 te) const; LLViewerTexture *getTESpecularMap(const U8 te) const; + void clearTEWaterExclusion(const U8 te); + bool isImageAlphaBlended(const U8 te) const; void fitFaceTexture(const U8 face); -- cgit v1.3 From 2bb4de97e43a32589434a35b617a36c2dfda22ee Mon Sep 17 00:00:00 2001 From: Hecklezz Date: Wed, 2 Apr 2025 18:18:17 +1000 Subject: Fix normal and specular repeats per meter scaling --- indra/newview/llpanelface.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index c080d72580..5a2a8ce128 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -3592,7 +3592,7 @@ void LLPanelFace::onCommitRepeatsPerMeter() bool identical_scale_t = false; LLSelectedTE::getObjectScaleS(obj_scale_s, identical_scale_s); - LLSelectedTE::getObjectScaleS(obj_scale_t, identical_scale_t); + LLSelectedTE::getObjectScaleT(obj_scale_t, identical_scale_t); if (gSavedSettings.getBOOL("SyncMaterialSettings")) { @@ -5086,6 +5086,7 @@ void LLPanelFace::LLSelectedTEMaterial::getMaxSpecularRepeats(F32& repeats, bool LLMaterial* mat = object->getTE(face)->getMaterialParams().get(); U32 s_axis = VX; U32 t_axis = VY; + LLPrimitive::getTESTAxes(face, &s_axis, &t_axis); F32 repeats_s = 1.0f; F32 repeats_t = 1.0f; if (mat) @@ -5110,6 +5111,7 @@ void LLPanelFace::LLSelectedTEMaterial::getMaxNormalRepeats(F32& repeats, bool& LLMaterial* mat = object->getTE(face)->getMaterialParams().get(); U32 s_axis = VX; U32 t_axis = VY; + LLPrimitive::getTESTAxes(face, &s_axis, &t_axis); F32 repeats_s = 1.0f; F32 repeats_t = 1.0f; if (mat) -- cgit v1.3 From 3dc6c22401b3125f4605fa464ecdbab836a73882 Mon Sep 17 00:00:00 2001 From: Hecklezz Date: Thu, 24 Apr 2025 07:51:04 +1000 Subject: Implemented PBR repeats per meter --- indra/newview/llpanelface.cpp | 175 +++++++++++++++++++-- indra/newview/llpanelface.h | 4 + .../skins/default/xui/en/panel_tools_texture.xml | 13 ++ 3 files changed, 177 insertions(+), 15 deletions(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 6e0b0d252e..f5ae99d8ab 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -162,6 +162,36 @@ void LLPanelFace::updateSelectedGLTFMaterials(std::functiongetSelection()->applyToTEs(&select_func); } +void LLPanelFace::updateSelectedGLTFMaterialsWithScale(std::function func) +{ + struct LLSelectedTEGLTFMaterialFunctor : public LLSelectedTEFunctor + { + LLSelectedTEGLTFMaterialFunctor(std::function func) : mFunc(func) {} + virtual ~LLSelectedTEGLTFMaterialFunctor() {}; + bool apply(LLViewerObject* object, S32 face) override + { + LLGLTFMaterial new_override; + const LLTextureEntry* tep = object->getTE(face); + if (tep->getGLTFMaterialOverride()) + { + new_override = *tep->getGLTFMaterialOverride(); + } + + U32 s_axis = VX; + U32 t_axis = VY; + LLPrimitive::getTESTAxes(face, &s_axis, &t_axis); + mFunc(&new_override, object->getScale().mV[s_axis], object->getScale().mV[t_axis]); + LLGLTFMaterialList::queueModify(object, face, &new_override); + + return true; + } + + std::function mFunc; + } select_func(func); + + LLSelectMgr::getInstance()->getSelection()->applyToTEs(&select_func); +} + template void readSelectedGLTFMaterial(std::function func, T& value, bool& identical, bool has_tolerance, T tolerance) { @@ -182,6 +212,36 @@ void readSelectedGLTFMaterial(std::function func, T& v identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&select_func, value, has_tolerance, tolerance); } +void getSelectedGLTFMaterialMaxRepeats(LLGLTFMaterial::TextureInfo channel, F32& repeats, bool& identical) +{ + // The All channel should read base color values + if (channel == LLGLTFMaterial::TextureInfo::GLTF_TEXTURE_INFO_COUNT) + channel = LLGLTFMaterial::TextureInfo::GLTF_TEXTURE_INFO_BASE_COLOR; + + struct LLSelectedTEGetGLTFMaterialMaxRepeatsFunctor : public LLSelectedTEGetFunctor + { + LLSelectedTEGetGLTFMaterialMaxRepeatsFunctor(LLGLTFMaterial::TextureInfo channel) : mChannel(channel) {} + virtual ~LLSelectedTEGetGLTFMaterialMaxRepeatsFunctor() {}; + F32 get(LLViewerObject* object, S32 face) override + { + const LLTextureEntry* tep = object->getTE(face); + const LLGLTFMaterial* render_material = tep->getGLTFRenderMaterial(); + if (!render_material) + return 0.f; + + U32 s_axis = VX; + U32 t_axis = VY; + LLPrimitive::getTESTAxes(face, &s_axis, &t_axis); + F32 repeats_u = render_material->mTextureTransform[mChannel].mScale[VX] / object->getScale().mV[s_axis]; + F32 repeats_v = render_material->mTextureTransform[mChannel].mScale[VY] / object->getScale().mV[t_axis]; + return llmax(repeats_u, repeats_v); + } + + LLGLTFMaterial::TextureInfo mChannel; + } max_repeats_func(channel); + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&max_repeats_func, repeats); +} + BOOST_STATIC_ASSERT(MATTYPE_DIFFUSE == LLRender::DIFFUSE_MAP && MATTYPE_NORMAL == LLRender::NORMAL_MAP && MATTYPE_SPECULAR == LLRender::SPECULAR_MAP); // @@ -322,6 +382,7 @@ bool LLPanelFace::postBuild() getChildSetCommitCallback(mPBRScaleU, "gltfTextureScaleU", [&](LLUICtrl*, const LLSD&) { onCommitGLTFTextureScaleU(); }); getChildSetCommitCallback(mPBRScaleV, "gltfTextureScaleV", [&](LLUICtrl*, const LLSD&) { onCommitGLTFTextureScaleV(); }); + getChildSetCommitCallback(mPBRRepeat, "gltfRptctrl", [&](LLUICtrl*, const LLSD&) { onCommitGLTFRepeatsPerMeter(); }); getChildSetCommitCallback(mPBRRotate, "gltfTextureRotation", [&](LLUICtrl*, const LLSD&) { onCommitGLTFRotation(); }); getChildSetCommitCallback(mPBROffsetU, "gltfTextureOffsetU", [&](LLUICtrl*, const LLSD&) { onCommitGLTFTextureOffsetU(); }); getChildSetCommitCallback(mPBROffsetV, "gltfTextureOffsetV", [&](LLUICtrl*, const LLSD&) { onCommitGLTFTextureOffsetV(); }); @@ -1591,36 +1652,57 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) F32 repeats_norm = 1.f; F32 repeats_spec = 1.f; + F32 repeats_pbr_basecolor = 1.f; + F32 repeats_pbr_metallic_roughness = 1.f; + F32 repeats_pbr_normal = 1.f; + F32 repeats_pbr_emissive = 1.f; + bool identical_diff_repeats = false; bool identical_norm_repeats = false; bool identical_spec_repeats = false; - LLSelectedTE::getMaxDiffuseRepeats(repeats_diff, identical_diff_repeats); - LLSelectedTEMaterial::getMaxNormalRepeats(repeats_norm, identical_norm_repeats); - LLSelectedTEMaterial::getMaxSpecularRepeats(repeats_spec, identical_spec_repeats); + bool identical_pbr_basecolor_repeats = false; + bool identical_pbr_metallic_roughness_repeats = false; + bool identical_pbr_normal_repeats = false; + bool identical_pbr_emissive_repeats = false; { + LLSpinCtrl* repeats_spin_ctrl = nullptr; S32 index = mComboTexGen ? mComboTexGen->getCurrentIndex() : 0; bool enabled = editable && (index != 1); bool identical_repeats = true; S32 material_selection = mComboMatMedia->getCurrentIndex(); F32 repeats = 1.0f; - U32 material_type = MATTYPE_DIFFUSE; - if (material_selection == MATMEDIA_MATERIAL) + LLRender::eTexIndex material_channel = LLRender::DIFFUSE_MAP; + if (material_selection != MATMEDIA_PBR) { - material_type = mRadioMaterialType->getSelectedIndex(); + repeats_spin_ctrl = mTexRepeat; + material_channel = getMatTextureChannel(); + LLSelectedTE::getMaxDiffuseRepeats(repeats_diff, identical_diff_repeats); + LLSelectedTEMaterial::getMaxNormalRepeats(repeats_norm, identical_norm_repeats); + LLSelectedTEMaterial::getMaxSpecularRepeats(repeats_spec, identical_spec_repeats); } else if (material_selection == MATMEDIA_PBR) { + repeats_spin_ctrl = mPBRRepeat; enabled = editable && has_pbr_material; - material_type = mRadioPbrType->getSelectedIndex(); + material_channel = getPBRTextureChannel(); + + getSelectedGLTFMaterialMaxRepeats(LLGLTFMaterial::TextureInfo::GLTF_TEXTURE_INFO_BASE_COLOR, + repeats_pbr_basecolor, identical_pbr_basecolor_repeats); + getSelectedGLTFMaterialMaxRepeats(LLGLTFMaterial::TextureInfo::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS, + repeats_pbr_metallic_roughness, identical_pbr_metallic_roughness_repeats); + getSelectedGLTFMaterialMaxRepeats(LLGLTFMaterial::TextureInfo::GLTF_TEXTURE_INFO_NORMAL, + repeats_pbr_normal, identical_pbr_normal_repeats); + getSelectedGLTFMaterialMaxRepeats(LLGLTFMaterial::TextureInfo::GLTF_TEXTURE_INFO_EMISSIVE, + repeats_pbr_emissive, identical_pbr_emissive_repeats); } - switch (material_type) + switch (material_channel) { default: - case MATTYPE_DIFFUSE: + case LLRender::DIFFUSE_MAP: if (material_selection != MATMEDIA_PBR) { enabled = editable && !id.isNull(); @@ -1628,7 +1710,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) identical_repeats = identical_diff_repeats; repeats = repeats_diff; break; - case MATTYPE_SPECULAR: + case LLRender::SPECULAR_MAP: if (material_selection != MATMEDIA_PBR) { enabled = (editable && ((shiny == SHINY_TEXTURE) && !specmap_id.isNull())); @@ -1636,7 +1718,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) identical_repeats = identical_spec_repeats; repeats = repeats_spec; break; - case MATTYPE_NORMAL: + case LLRender::NORMAL_MAP: if (material_selection != MATMEDIA_PBR) { enabled = (editable && ((bumpy == BUMPY_TEXTURE) && !normmap_id.isNull())); @@ -1644,6 +1726,23 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) identical_repeats = identical_norm_repeats; repeats = repeats_norm; break; + case LLRender::NUM_TEXTURE_CHANNELS: + case LLRender::BASECOLOR_MAP: + identical_repeats = identical_pbr_basecolor_repeats; + repeats = repeats_pbr_basecolor; + break; + case LLRender::METALLIC_ROUGHNESS_MAP: + identical_repeats = identical_pbr_metallic_roughness_repeats; + repeats = repeats_pbr_metallic_roughness; + break; + case LLRender::GLTF_NORMAL_MAP: + identical_repeats = identical_pbr_normal_repeats; + repeats = repeats_pbr_normal; + break; + case LLRender::EMISSIVE_MAP: + identical_repeats = identical_pbr_emissive_repeats; + repeats = repeats_pbr_emissive; + break; } bool repeats_tentative = !identical_repeats; @@ -1651,14 +1750,14 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) if (force_set_values) { // onCommit, previosly edited element updates related ones - mTexRepeat->forceSetValue(editable ? repeats : 1.0f); + repeats_spin_ctrl->forceSetValue(editable ? repeats : 1.0f); } else { - mTexRepeat->setValue(editable ? repeats : 1.0f); + repeats_spin_ctrl->setValue(editable ? repeats : 1.0f); } - mTexRepeat->setTentative(LLSD(repeats_tentative)); - mTexRepeat->setEnabled(has_material && !identical_planar_texgen && enabled); + repeats_spin_ctrl->setTentative(LLSD(repeats_tentative)); + repeats_spin_ctrl->setEnabled(!identical_planar_texgen && enabled); } } @@ -1804,6 +1903,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) } mLabelColorTransp->setEnabled(false); mTexRepeat->setEnabled(false); + mPBRRepeat->setEnabled(false); mLabelTexGen->setEnabled(false); mLabelShininess->setEnabled(false); mLabelBumpiness->setEnabled(false); @@ -1999,6 +2099,7 @@ void LLPanelFace::updateVisibilityGLTF(LLViewerObject* objectp /*= nullptr */) mPBRRotate->setVisible(show_pbr); mPBROffsetU->setVisible(show_pbr); mPBROffsetV->setVisible(show_pbr); + mPBRRepeat->setVisible(show_pbr); } void LLPanelFace::updateCopyTexButton() @@ -3693,6 +3794,21 @@ void LLPanelFace::onCommitRepeatsPerMeter() updateUI(true); } +// Commit the number of GLTF repeats per meter +void LLPanelFace::onCommitGLTFRepeatsPerMeter() +{ + F32 repeats_per_meter = (F32)mPBRRepeat->getValue().asReal(); + + LLGLTFMaterial::TextureInfo material_type = getPBRTextureInfo(); + updateGLTFTextureTransformWithScale(material_type, [&](LLGLTFMaterial::TextureTransform* new_transform, F32 scale_s, F32 scale_t) + { + new_transform->mScale.mV[VX] = scale_s * repeats_per_meter; + new_transform->mScale.mV[VY] = scale_t * repeats_per_meter; + }); + + updateUI(true); +} + struct LLPanelFaceSetMediaFunctor : public LLSelectedTEFunctor { virtual bool apply(LLViewerObject* object, S32 te) @@ -4642,6 +4758,29 @@ void LLPanelFace::updateGLTFTextureTransform(std::function edit) +{ + if (texture_info == LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT) + { + updateSelectedGLTFMaterialsWithScale([&](LLGLTFMaterial* new_override, const F32 scale_s, const F32 scale_t) + { + for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i) + { + LLGLTFMaterial::TextureTransform& new_transform = new_override->mTextureTransform[(LLGLTFMaterial::TextureInfo)i]; + edit(&new_transform, scale_s, scale_t); + } + }); + } + else + { + updateSelectedGLTFMaterialsWithScale([&](LLGLTFMaterial* new_override, const F32 scale_s, const F32 scale_t) + { + LLGLTFMaterial::TextureTransform& new_transform = new_override->mTextureTransform[texture_info]; + edit(&new_transform, scale_s, scale_t); + }); + } +} + void LLPanelFace::setMaterialOverridesFromSelection() { const LLGLTFMaterial::TextureInfo texture_info = getPBRTextureInfo(); @@ -4728,6 +4867,12 @@ void LLPanelFace::setMaterialOverridesFromSelection() mPBRRotate->setTentative(!rotation_same); mPBROffsetU->setTentative(!offset_u_same); mPBROffsetV->setTentative(!offset_v_same); + + F32 repeats = 1.f; + bool identical = false; + getSelectedGLTFMaterialMaxRepeats(getPBRDropChannel(), repeats, identical); + mPBRRepeat->forceSetValue(repeats); + mPBRRepeat->setTentative(!identical || !scale_u_same || !scale_v_same); } void LLPanelFace::Selection::connect() diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 6e0d34cbd6..9d28065934 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -250,6 +250,7 @@ protected: void onCommitGLTFRotation(); void onCommitGLTFTextureOffsetU(); void onCommitGLTFTextureOffsetV(); + void onCommitGLTFRepeatsPerMeter(); void onClickAutoFix(); void onAlignTexture(); @@ -358,6 +359,7 @@ private: LLButton* mDelMedia { nullptr }; LLSpinCtrl* mPBRScaleU { nullptr }; LLSpinCtrl* mPBRScaleV { nullptr }; + LLSpinCtrl* mPBRRepeat { nullptr }; LLSpinCtrl* mPBRRotate { nullptr }; LLSpinCtrl* mPBROffsetU { nullptr }; LLSpinCtrl* mPBROffsetV { nullptr }; @@ -551,7 +553,9 @@ private: void updateVisibilityGLTF(LLViewerObject* objectp = nullptr); void updateSelectedGLTFMaterials(std::function func); + void updateSelectedGLTFMaterialsWithScale(std::function func); void updateGLTFTextureTransform(std::function edit); + void updateGLTFTextureTransformWithScale(const LLGLTFMaterial::TextureInfo texture_info, std::function edit); void setMaterialOverridesFromSelection(); diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml index 9a19d06432..028faca881 100644 --- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml +++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml @@ -985,6 +985,19 @@ max_val="100" name="gltfTextureScaleV" width="265" /> + Date: Thu, 24 Apr 2025 23:46:42 +1000 Subject: Autofit Blinn Phong normal and specular when using repeats per meter --- indra/newview/llpanelface.cpp | 82 +++++++++++++++++++++++++++++++------------ indra/newview/llpanelface.h | 2 ++ 2 files changed, 62 insertions(+), 22 deletions(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index f5ae99d8ab..b1b4577c5d 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -3750,18 +3750,8 @@ void LLPanelFace::onCommitRepeatsPerMeter() if (gSavedSettings.getBOOL("SyncMaterialSettings")) { LLSelectMgr::getInstance()->selectionTexScaleAutofit(repeats_per_meter); - - mBumpyScaleU->setValue(obj_scale_s * repeats_per_meter); - mBumpyScaleV->setValue(obj_scale_t * repeats_per_meter); - - LLSelectedTEMaterial::setNormalRepeatX(this, obj_scale_s * repeats_per_meter); - LLSelectedTEMaterial::setNormalRepeatY(this, obj_scale_t * repeats_per_meter); - - mShinyScaleU->setValue(obj_scale_s * repeats_per_meter); - mShinyScaleV->setValue(obj_scale_t * repeats_per_meter); - - LLSelectedTEMaterial::setSpecularRepeatX(this, obj_scale_s * repeats_per_meter); - LLSelectedTEMaterial::setSpecularRepeatY(this, obj_scale_t * repeats_per_meter); + LLSelectedTEMaterial::selectionNormalScaleAutofit(this, repeats_per_meter); + LLSelectedTEMaterial::selectionSpecularScaleAutofit(this, repeats_per_meter); } else { @@ -3772,18 +3762,10 @@ void LLPanelFace::onCommitRepeatsPerMeter() LLSelectMgr::getInstance()->selectionTexScaleAutofit(repeats_per_meter); break; case MATTYPE_NORMAL: - mBumpyScaleU->setValue(obj_scale_s * repeats_per_meter); - mBumpyScaleV->setValue(obj_scale_t * repeats_per_meter); - - LLSelectedTEMaterial::setNormalRepeatX(this, obj_scale_s * repeats_per_meter); - LLSelectedTEMaterial::setNormalRepeatY(this, obj_scale_t * repeats_per_meter); + LLSelectedTEMaterial::selectionNormalScaleAutofit(this, repeats_per_meter); break; case MATTYPE_SPECULAR: - mBumpyScaleU->setValue(obj_scale_s * repeats_per_meter); - mBumpyScaleV->setValue(obj_scale_t * repeats_per_meter); - - LLSelectedTEMaterial::setSpecularRepeatX(this, obj_scale_s * repeats_per_meter); - LLSelectedTEMaterial::setSpecularRepeatY(this, obj_scale_t * repeats_per_meter); + LLSelectedTEMaterial::selectionSpecularScaleAutofit(this, repeats_per_meter); break; default: llassert(false); @@ -5366,6 +5348,62 @@ void LLPanelFace::LLSelectedTEMaterial::getCurrentDiffuseAlphaMode(U8& diffuse_a identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &get_diff_mode, diffuse_alpha_mode); } +void LLPanelFace::LLSelectedTEMaterial::selectionNormalScaleAutofit(LLPanelFace* panel_face, F32 repeats_per_meter) +{ + struct f : public LLSelectedTEFunctor + { + LLPanelFace* mFacePanel; + F32 mRepeatsPerMeter; + f(LLPanelFace* face_panel, const F32& repeats_per_meter) : mFacePanel(face_panel), mRepeatsPerMeter(repeats_per_meter) {} + bool apply(LLViewerObject* object, S32 te) + { + if (object->permModify()) + { + // Compute S,T to axis mapping + U32 s_axis, t_axis; + if (!LLPrimitive::getTESTAxes(te, &s_axis, &t_axis)) + return true; + + F32 new_s = object->getScale().mV[s_axis] * mRepeatsPerMeter; + F32 new_t = object->getScale().mV[t_axis] * mRepeatsPerMeter; + + setNormalRepeatX(mFacePanel, new_s, te); + setNormalRepeatY(mFacePanel, new_t, te); + } + return true; + } + } setfunc(panel_face, repeats_per_meter); + LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc); +} + +void LLPanelFace::LLSelectedTEMaterial::selectionSpecularScaleAutofit(LLPanelFace* panel_face, F32 repeats_per_meter) +{ + struct f : public LLSelectedTEFunctor + { + LLPanelFace* mFacePanel; + F32 mRepeatsPerMeter; + f(LLPanelFace* face_panel, const F32& repeats_per_meter) : mFacePanel(face_panel), mRepeatsPerMeter(repeats_per_meter) {} + bool apply(LLViewerObject* object, S32 te) + { + if (object->permModify()) + { + // Compute S,T to axis mapping + U32 s_axis, t_axis; + if (!LLPrimitive::getTESTAxes(te, &s_axis, &t_axis)) + return true; + + F32 new_s = object->getScale().mV[s_axis] * mRepeatsPerMeter; + F32 new_t = object->getScale().mV[t_axis] * mRepeatsPerMeter; + + setSpecularRepeatX(mFacePanel, new_s, te); + setSpecularRepeatY(mFacePanel, new_t, te); + } + return true; + } + } setfunc(panel_face, repeats_per_meter); + LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc); +} + void LLPanelFace::LLSelectedTE::getObjectScaleS(F32& scale_s, bool& identical) { struct LLSelectedTEGetObjectScaleS : public LLSelectedTEGetFunctor diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 9d28065934..2a2156f041 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -650,6 +650,8 @@ public: static void getMaxSpecularRepeats(F32& repeats, bool& identical); static void getMaxNormalRepeats(F32& repeats, bool& identical); static void getCurrentDiffuseAlphaMode(U8& diffuse_alpha_mode, bool& identical, bool diffuse_texture_has_alpha); + static void selectionNormalScaleAutofit(LLPanelFace* panel_face, F32 repeats_per_meter); + static void selectionSpecularScaleAutofit(LLPanelFace* panel_face, F32 repeats_per_meter); DEF_GET_MAT_STATE(LLUUID, const LLUUID&, getNormalID, LLUUID::null, false, LLUUID::null); DEF_GET_MAT_STATE(LLUUID, const LLUUID&, getSpecularID, LLUUID::null, false, LLUUID::null); -- cgit v1.3 From 56ec95de29c0eea1f9e411b570bd046af7344b4e Mon Sep 17 00:00:00 2001 From: Hecklezz Date: Fri, 25 Apr 2025 01:28:41 +1000 Subject: Fix scale values not updating if they were focused and you used repeats per meter --- indra/newview/llpanelface.cpp | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index b1b4577c5d..c6d24f276d 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -1456,9 +1456,18 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) spec_scale_s = editable ? spec_scale_s : 1.0f; spec_scale_s *= identical_planar_texgen ? 2.0f : 1.0f; - mTexScaleU->setValue(diff_scale_s); - mShinyScaleU->setValue(spec_scale_s); - mBumpyScaleU->setValue(norm_scale_s); + if (force_set_values) + { + mTexScaleU->forceSetValue(diff_scale_s); + mShinyScaleU->forceSetValue(spec_scale_s); + mBumpyScaleU->forceSetValue(norm_scale_s); + } + else + { + mTexScaleU->setValue(diff_scale_s); + mShinyScaleU->setValue(spec_scale_s); + mBumpyScaleU->setValue(norm_scale_s); + } mTexScaleU->setEnabled(editable && has_material); mShinyScaleU->setEnabled(editable && has_material && specmap_id.notNull()); @@ -1506,13 +1515,16 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) if (force_set_values) { mTexScaleV->forceSetValue(diff_scale_t); + mShinyScaleV->forceSetValue(spec_scale_t); + mBumpyScaleV->forceSetValue(norm_scale_t); } else { mTexScaleV->setValue(diff_scale_t); + mShinyScaleV->setValue(spec_scale_t); + mBumpyScaleV->setValue(norm_scale_t); } - mShinyScaleV->setValue(spec_scale_t); - mBumpyScaleV->setValue(norm_scale_t); + mTexScaleV->setTentative(LLSD(diff_scale_tentative)); mShinyScaleV->setTentative(LLSD(spec_scale_tentative)); @@ -4838,8 +4850,9 @@ void LLPanelFace::setMaterialOverridesFromSelection() } } - mPBRScaleU->setValue(transform.mScale[VX]); - mPBRScaleV->setValue(transform.mScale[VY]); + // Force set scales just in case they were set by repeats per meter and their spinner is focused + mPBRScaleU->forceSetValue(transform.mScale[VX]); + mPBRScaleV->forceSetValue(transform.mScale[VY]); mPBRRotate->setValue(transform.mRotation * RAD_TO_DEG); mPBROffsetU->setValue(transform.mOffset[VX]); mPBROffsetV->setValue(transform.mOffset[VY]); -- cgit v1.3 From 7bd18e256d70804f72d747ccc1e62c92679dd645 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 25 Apr 2025 18:57:58 +0300 Subject: viewerp#300 Fix inconsistency with copying textures vs pbr --- indra/newview/llinventorymodel.cpp | 1 + indra/newview/llpanelface.cpp | 462 ++++++++++++++++++++++++------------- indra/newview/llpanelface.h | 3 + indra/newview/lltexturectrl.cpp | 3 +- 4 files changed, 312 insertions(+), 157 deletions(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 0a2d938bd0..cf1efd283a 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -2768,6 +2768,7 @@ bool LLInventoryModel::loadSkeleton( bool is_cache_obsolete = false; if (loadFromFile(inventory_filename, categories, items, categories_to_update, is_cache_obsolete)) { + LL_PROFILE_ZONE_NAMED("loadFromFile"); // We were able to find a cache of files. So, use what we // found to generate a set of categories we should add. We // will go through each category loaded and if the version diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 6e0b0d252e..2e57e2a5bd 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -4009,6 +4009,85 @@ void LLPanelFace::onPasteColor(LLViewerObject* objectp, S32 te) } } +void set_item_availability( + const LLUUID& id, + LLSD& dest, + const std::string& modifier, + bool is_creator, + std::map &asset_item_map, + LLViewerObject* objectp) +{ + if (id.isNull()) + { + return; + } + + LLUUID item_id; + bool from_library = get_is_predefined_texture(id); + bool full_perm = from_library; + full_perm |= is_creator; + + if (!full_perm) + { + std::map::iterator iter = asset_item_map.find(id); + if (iter != asset_item_map.end()) + { + item_id = iter->second; + } + else + { + // What this does is simply searches inventory for item with same asset id, + // as result it is Hightly unreliable, leaves little control to user, borderline hack + // but there are little options to preserve permissions - multiple inventory + // items might reference same asset and inventory search is expensive. + bool no_transfer = false; + if (objectp->getInventoryItemByAsset(id)) + { + no_transfer = !objectp->getInventoryItemByAsset(id)->getIsFullPerm(); + } + item_id = get_copy_free_item_by_asset_id(id, no_transfer); + // record value to avoid repeating inventory search when possible + asset_item_map[id] = item_id; + } + } + + if (item_id.notNull() && gInventory.isObjectDescendentOf(item_id, gInventory.getLibraryRootFolderID())) + { + full_perm = true; + from_library = true; + } + + dest[modifier + "itemfullperm"] = full_perm; + dest[modifier + "fromlibrary"] = from_library; + + // If full permission object, texture is free to copy, + // but otherwise we need to check inventory and extract permissions + // + // Normally we care only about restrictions for current user and objects + // don't inherit any 'next owner' permissions from texture, so there is + // no need to record item id if full_perm==true + if (!full_perm && item_id.notNull()) + { + LLViewerInventoryItem* itemp = gInventory.getItem(item_id); + if (itemp) + { + LLPermissions item_permissions = itemp->getPermissions(); + if (item_permissions.allowOperationBy(PERM_COPY, + gAgent.getID(), + gAgent.getGroupID())) + { + dest[modifier + "itemid"] = item_id; + dest[modifier + "itemfullperm"] = itemp->getIsFullPerm(); + if (!itemp->isFinished()) + { + // needed for dropTextureAllFaces + LLInventoryModelBackgroundFetch::instance().start(item_id, false); + } + } + } + } +} + void LLPanelFace::onCopyTexture() { LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); @@ -4046,6 +4125,7 @@ void LLPanelFace::onCopyTexture() if (tep) { LLSD te_data; + LLUUID pbr_id = objectp->getRenderMaterialID(te); // asLLSD() includes media te_data["te"] = tep->asLLSD(); @@ -4054,21 +4134,20 @@ void LLPanelFace::onCopyTexture() te_data["te"]["bumpshiny"] = tep->getBumpShiny(); te_data["te"]["bumpfullbright"] = tep->getBumpShinyFullbright(); te_data["te"]["texgen"] = tep->getTexGen(); - te_data["te"]["pbr"] = objectp->getRenderMaterialID(te); + te_data["te"]["pbr"] = pbr_id; if (tep->getGLTFMaterialOverride() != nullptr) { te_data["te"]["pbr_override"] = tep->getGLTFMaterialOverride()->asJSON(); } - if (te_data["te"].has("imageid")) + if (te_data["te"].has("imageid") || pbr_id.notNull()) { - LLUUID item_id; - LLUUID id = te_data["te"]["imageid"].asUUID(); - bool from_library = get_is_predefined_texture(id); - bool full_perm = from_library; + LLUUID img_id = te_data["te"]["imageid"].asUUID(); + bool pbr_from_library = false; + bool pbr_full_perm = false; + bool is_creator = false; - if (!full_perm - && objectp->permCopy() + if (objectp->permCopy() && objectp->permTransfer() && objectp->permModify()) { @@ -4078,66 +4157,31 @@ void LLPanelFace::onCopyTexture() std::string creator_app_link; LLUUID creator_id; LLSelectMgr::getInstance()->selectGetCreator(creator_id, creator_app_link); - full_perm = objectp->mOwnerID == creator_id; + is_creator = objectp->mOwnerID == creator_id; } - if (id.notNull() && !full_perm) + // check permissions for blin-phong/diffuse image and for pbr asset + if (img_id.notNull()) { - std::map::iterator iter = asset_item_map.find(id); - if (iter != asset_item_map.end()) - { - item_id = iter->second; - } - else - { - // What this does is simply searches inventory for item with same asset id, - // as result it is Hightly unreliable, leaves little control to user, borderline hack - // but there are little options to preserve permissions - multiple inventory - // items might reference same asset and inventory search is expensive. - bool no_transfer = false; - if (objectp->getInventoryItemByAsset(id)) - { - no_transfer = !objectp->getInventoryItemByAsset(id)->getIsFullPerm(); - } - item_id = get_copy_free_item_by_asset_id(id, no_transfer); - // record value to avoid repeating inventory search when possible - asset_item_map[id] = item_id; - } + set_item_availability(img_id, te_data["te"], "img", is_creator, asset_item_map, objectp); } - - if (item_id.notNull() && gInventory.isObjectDescendentOf(item_id, gInventory.getLibraryRootFolderID())) + if (pbr_id.notNull()) { - full_perm = true; - from_library = true; - } + set_item_availability(pbr_id, te_data["te"], "pbr", is_creator, asset_item_map, objectp); - { - te_data["te"]["itemfullperm"] = full_perm; - te_data["te"]["fromlibrary"] = from_library; - - // If full permission object, texture is free to copy, - // but otherwise we need to check inventory and extract permissions - // - // Normally we care only about restrictions for current user and objects - // don't inherit any 'next owner' permissions from texture, so there is - // no need to record item id if full_perm==true - if (!full_perm && !from_library && item_id.notNull()) + // permissions for overrides + // Overrides do not permit no-copy textures + LLGLTFMaterial* override = tep->getGLTFMaterialOverride(); + if (override != nullptr) { - LLViewerInventoryItem* itemp = gInventory.getItem(item_id); - if (itemp) + for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i) { - LLPermissions item_permissions = itemp->getPermissions(); - if (item_permissions.allowOperationBy(PERM_COPY, - gAgent.getID(), - gAgent.getGroupID())) + LLUUID& texture_id = override->mTextureId[i]; + if (texture_id.notNull()) { - te_data["te"]["imageitemid"] = item_id; - te_data["te"]["itemfullperm"] = itemp->getIsFullPerm(); - if (!itemp->isFinished()) - { - // needed for dropTextureAllFaces - LLInventoryModelBackgroundFetch::instance().start(item_id, false); - } + const std::string prefix = "pbr" + std::to_string(i); + te_data["te"][prefix + "imageid"] = texture_id; + set_item_availability(texture_id, te_data["te"], prefix, is_creator, asset_item_map, objectp); } } } @@ -4201,6 +4245,44 @@ void LLPanelFace::onCopyTexture() } } +bool get_full_permission(const LLSD& te, const std::string &prefix) +{ + return te.has(prefix + "itemfullperm") && te[prefix+"itemfullperm"].asBoolean(); +} + +bool LLPanelFace::validateInventoryItem(const LLSD& te, const std::string& prefix) +{ + if (te.has(prefix + "itemid")) + { + LLUUID item_id = te[prefix + "itemid"].asUUID(); + if (item_id.notNull()) + { + LLViewerInventoryItem* itemp = gInventory.getItem(item_id); + if (!itemp) + { + // image might be in object's inventory, but it can be not up to date + LLSD notif_args; + static std::string reason = getString("paste_error_inventory_not_found"); + notif_args["REASON"] = reason; + LLNotificationsUtil::add("FacePasteFailed", notif_args); + return false; + } + } + } + else + { + // Item was not found on 'copy' stage + // Since this happened at copy, might be better to either show this + // at copy stage or to drop clipboard here + LLSD notif_args; + static std::string reason = getString("paste_error_inventory_not_found"); + notif_args["REASON"] = reason; + LLNotificationsUtil::add("FacePasteFailed", notif_args); + return false; + } + return true; +} + void LLPanelFace::onPasteTexture() { if (!mClipboardParams.has("texture")) @@ -4265,39 +4347,49 @@ void LLPanelFace::onPasteTexture() for (; iter != end; ++iter) { const LLSD& te_data = *iter; - if (te_data.has("te") && te_data["te"].has("imageid")) + if (te_data.has("te")) { - bool full_perm = te_data["te"].has("itemfullperm") && te_data["te"]["itemfullperm"].asBoolean(); - full_perm_object &= full_perm; - if (!full_perm) + if (te_data["te"].has("imageid")) { - if (te_data["te"].has("imageitemid")) + bool full_perm = get_full_permission(te_data["te"], "img"); + full_perm_object &= full_perm; + if (!full_perm) { - LLUUID item_id = te_data["te"]["imageitemid"].asUUID(); - if (item_id.notNull()) + if (!validateInventoryItem(te_data["te"], "img")) { - LLViewerInventoryItem* itemp = gInventory.getItem(item_id); - if (!itemp) - { - // image might be in object's inventory, but it can be not up to date - LLSD notif_args; - static std::string reason = getString("paste_error_inventory_not_found"); - notif_args["REASON"] = reason; - LLNotificationsUtil::add("FacePasteFailed", notif_args); - return; - } + return; } } - else + } + if (te_data["te"].has("pbr")) + { + bool full_perm = get_full_permission(te_data["te"], "pbr"); + full_perm_object &= full_perm; + if (!full_perm) { - // Item was not found on 'copy' stage - // Since this happened at copy, might be better to either show this - // at copy stage or to drop clipboard here - LLSD notif_args; - static std::string reason = getString("paste_error_inventory_not_found"); - notif_args["REASON"] = reason; - LLNotificationsUtil::add("FacePasteFailed", notif_args); - return; + if (!validateInventoryItem(te_data["te"], "pbr")) + { + return; + } + } + if (te_data["te"].has("pbr_override")) + { + for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i) + { + const std::string prefix = "pbr" + std::to_string(i); + if (te_data["te"].has(prefix + "imageid")) + { + bool full_perm = get_full_permission(te_data["te"], prefix); + full_perm_object &= full_perm; + if (!full_perm) + { + if (!validateInventoryItem(te_data["te"], prefix)) + { + return; + } + } + } + } } } } @@ -4322,6 +4414,71 @@ void LLPanelFace::onPasteTexture() selected_objects->applyToTEs(&navigate_home_func); } +void get_item_and_permissions(const LLUUID &id, LLViewerInventoryItem*& itemp, bool& full_perm, bool& from_library, const LLSD &data, const std::string &prefix) +{ + full_perm = get_full_permission(data, prefix); + from_library = data.has(prefix + "fromlibrary") && data.get(prefix + "fromlibrary").asBoolean(); + LLViewerInventoryItem* itemp_res = NULL; + + if (data.has(prefix + "itemid")) + { + LLUUID item_id = data.get(prefix + "itemid").asUUID(); + if (item_id.notNull()) + { + LLViewerInventoryItem* itemp = gInventory.getItem(item_id); + if (itemp && itemp->isFinished()) + { + // dropTextureAllFaces will fail if incomplete + itemp_res = itemp; + } + else + { + // Theoretically shouldn't happend, but if it does happen, we + // might need to add a notification to user that paste will fail + // since inventory isn't fully loaded + LL_WARNS() << "Item " << item_id << " is incomplete, paste might fail silently." << LL_ENDL; + } + } + } + + // for case when item got removed from inventory after we pressed 'copy' + // or texture got pasted into previous object + if (!itemp_res && !full_perm) + { + // Due to checks for imageitemid in LLPanelFace::onPasteTexture() this should no longer be reachable. + LL_INFOS() << "Item " << data.get(prefix + "itemid").asUUID() << " no longer in inventory." << LL_ENDL; + // Todo: fix this, we are often searching same texture multiple times (equal to number of faces) + // Perhaps just mPanelFace->onPasteTexture(objectp, te, &asset_to_item_id_map); ? Not pretty, but will work + LLViewerInventoryCategory::cat_array_t cats; + LLViewerInventoryItem::item_array_t items; + LLAssetIDMatches asset_id_matches(id); + gInventory.collectDescendentsIf(LLUUID::null, + cats, + items, + LLInventoryModel::INCLUDE_TRASH, + asset_id_matches); + + // Extremely unreliable and perfomance unfriendly. + // But we need this to check permissions and it is how texture control finds items + for (S32 i = 0; i < items.size(); i++) + { + LLViewerInventoryItem* itemp = items[i]; + if (itemp && itemp->isFinished()) + { + // dropTextureAllFaces will fail if incomplete + LLPermissions item_permissions = itemp->getPermissions(); + if (item_permissions.allowOperationBy(PERM_COPY, + gAgent.getID(), + gAgent.getGroupID())) + { + itemp_res = itemp; + break; // first match + } + } + } + } +} + void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te) { LLSD te_data; @@ -4345,77 +4502,22 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te) if (te_data.has("te")) { // Texture - bool full_perm = te_data["te"].has("itemfullperm") && te_data["te"]["itemfullperm"].asBoolean(); - bool from_library = te_data["te"].has("fromlibrary") && te_data["te"]["fromlibrary"].asBoolean(); if (te_data["te"].has("imageid")) { + bool img_full_perm = false; + bool img_from_library = false; const LLUUID& imageid = te_data["te"]["imageid"].asUUID(); //texture or asset id - LLViewerInventoryItem* itemp_res = NULL; + LLViewerInventoryItem* img_itemp_res = NULL; - if (te_data["te"].has("imageitemid")) - { - LLUUID item_id = te_data["te"]["imageitemid"].asUUID(); - if (item_id.notNull()) - { - LLViewerInventoryItem* itemp = gInventory.getItem(item_id); - if (itemp && itemp->isFinished()) - { - // dropTextureAllFaces will fail if incomplete - itemp_res = itemp; - } - else - { - // Theoretically shouldn't happend, but if it does happen, we - // might need to add a notification to user that paste will fail - // since inventory isn't fully loaded - LL_WARNS() << "Item " << item_id << " is incomplete, paste might fail silently." << LL_ENDL; - } - } - } - // for case when item got removed from inventory after we pressed 'copy' - // or texture got pasted into previous object - if (!itemp_res && !full_perm) - { - // Due to checks for imageitemid in LLPanelFace::onPasteTexture() this should no longer be reachable. - LL_INFOS() << "Item " << te_data["te"]["imageitemid"].asUUID() << " no longer in inventory." << LL_ENDL; - // Todo: fix this, we are often searching same texture multiple times (equal to number of faces) - // Perhaps just mPanelFace->onPasteTexture(objectp, te, &asset_to_item_id_map); ? Not pretty, but will work - LLViewerInventoryCategory::cat_array_t cats; - LLViewerInventoryItem::item_array_t items; - LLAssetIDMatches asset_id_matches(imageid); - gInventory.collectDescendentsIf(LLUUID::null, - cats, - items, - LLInventoryModel::INCLUDE_TRASH, - asset_id_matches); - - // Extremely unreliable and perfomance unfriendly. - // But we need this to check permissions and it is how texture control finds items - for (S32 i = 0; i < items.size(); i++) - { - LLViewerInventoryItem* itemp = items[i]; - if (itemp && itemp->isFinished()) - { - // dropTextureAllFaces will fail if incomplete - LLPermissions item_permissions = itemp->getPermissions(); - if (item_permissions.allowOperationBy(PERM_COPY, - gAgent.getID(), - gAgent.getGroupID())) - { - itemp_res = itemp; - break; // first match - } - } - } - } + get_item_and_permissions(imageid, img_itemp_res, img_full_perm, img_from_library, te_data["te"], "img"); - if (itemp_res) + if (img_itemp_res) { if (te == -1) // all faces { LLToolDragAndDrop::dropTextureAllFaces(objectp, - itemp_res, - from_library ? LLToolDragAndDrop::SOURCE_LIBRARY : LLToolDragAndDrop::SOURCE_AGENT, + img_itemp_res, + img_from_library ? LLToolDragAndDrop::SOURCE_LIBRARY : LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null, false); } @@ -4423,15 +4525,15 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te) { LLToolDragAndDrop::dropTextureOneFace(objectp, te, - itemp_res, - from_library ? LLToolDragAndDrop::SOURCE_LIBRARY : LLToolDragAndDrop::SOURCE_AGENT, + img_itemp_res, + img_from_library ? LLToolDragAndDrop::SOURCE_LIBRARY : LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null, false, 0); } } // not an inventory item or no complete items - else if (full_perm) + else if (img_full_perm) { // Either library, local or existed as fullperm when user made a copy LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(imageid, FTT_DEFAULT, true, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); @@ -4459,17 +4561,65 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te) // PBR/GLTF if (te_data["te"].has("pbr")) { - objectp->setRenderMaterialID(te, te_data["te"]["pbr"].asUUID(), false /*managing our own update*/); - tep->setGLTFRenderMaterial(nullptr); - tep->setGLTFMaterialOverride(nullptr); + const LLUUID pbr_id = te_data["te"]["pbr"].asUUID(); + bool pbr_full_perm = false; + bool pbr_from_library = false; + LLViewerInventoryItem* pbr_itemp_res = NULL; + + get_item_and_permissions(pbr_id, pbr_itemp_res, pbr_full_perm, pbr_from_library, te_data["te"], "pbr"); + bool allow = true; + + // check overrides first since they don't need t be moved to inventory if (te_data["te"].has("pbr_override")) { - LLGLTFMaterialList::queueApply(objectp, te, te_data["te"]["pbr"].asUUID(), te_data["te"]["pbr_override"]); + for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i) + { + const std::string prefix = "pbr" + std::to_string(i); + if (te_data["te"].has(prefix + "imageid")) + { + LLUUID tex_id = te_data["te"][prefix + "imageid"]; + + bool full_perm = false; + bool from_library = false; + LLViewerInventoryItem* itemp_res = NULL; + get_item_and_permissions(tex_id, itemp_res, full_perm, from_library, te_data["te"], prefix); + allow = full_perm; + if (!allow) break; + } + } + } + + if (allow && pbr_itemp_res) + { + if (pbr_itemp_res) + { + allow = LLToolDragAndDrop::handleDropMaterialProtections( + objectp, + pbr_itemp_res, + pbr_from_library ? LLToolDragAndDrop::SOURCE_LIBRARY : LLToolDragAndDrop::SOURCE_AGENT, + pbr_id); + } + else + { + allow = pbr_full_perm; + } } - else + + if (allow) { - LLGLTFMaterialList::queueApply(objectp, te, te_data["te"]["pbr"].asUUID()); + objectp->setRenderMaterialID(te, te_data["te"]["pbr"].asUUID(), false /*managing our own update*/); + tep->setGLTFRenderMaterial(nullptr); + tep->setGLTFMaterialOverride(nullptr); + + if (te_data["te"].has("pbr_override")) + { + LLGLTFMaterialList::queueApply(objectp, te, te_data["te"]["pbr"].asUUID(), te_data["te"]["pbr_override"]); + } + else + { + LLGLTFMaterialList::queueApply(objectp, te, te_data["te"]["pbr"].asUUID()); + } } } else diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 6e0d34cbd6..b59f7434af 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -264,6 +264,9 @@ public: // needs to be accessible to selection manager void onCopyTexture(); void onPasteTexture(); void onPasteTexture(LLViewerObject* objectp, S32 te); +private: + // for copy/paste operations + bool validateInventoryItem(const LLSD& te, const std::string& prefix); protected: void menuDoToSelected(const LLSD& userdata); diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 35057a910a..20127f5f27 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -88,7 +88,8 @@ bool get_is_predefined_texture(LLUUID asset_id) || asset_id == DEFAULT_OBJECT_NORMAL || asset_id == BLANK_OBJECT_NORMAL || asset_id == IMG_WHITE - || asset_id == LLUUID(SCULPT_DEFAULT_TEXTURE)) + || asset_id == LLUUID(SCULPT_DEFAULT_TEXTURE) + || asset_id == BLANK_MATERIAL_ASSET_ID) { return true; } -- cgit v1.3 From fdda524ee1395c7dd5d5f65ce1f61c64e256c531 Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko Date: Tue, 29 Apr 2025 00:50:38 +0300 Subject: #3791 check against alpha blending as a part of determining exclude water --- indra/newview/llpanelface.cpp | 111 ++++++++++++++++++++++-------------------- 1 file changed, 57 insertions(+), 54 deletions(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 2e57e2a5bd..99471a2555 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -1106,6 +1106,63 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) updateVisibility(objectp); + bool missing_asset = false; + { + LLGLenum image_format = GL_RGB; + bool identical_image_format = false; + LLSelectedTE::getImageFormat(image_format, identical_image_format, missing_asset); + + if (!missing_asset) + { + 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; + } + } + else + { + // Don't know image's properties, use material's mode value + mIsAlpha = true; + } + + // Diffuse Alpha Mode + // Init to the default that is appropriate for the alpha content of the asset + // + U8 alpha_mode = mIsAlpha ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE; + + bool identical_alpha_mode = false; + + // See if that's been overridden by a material setting for same... + // + LLSelectedTEMaterial::getCurrentDiffuseAlphaMode(alpha_mode, identical_alpha_mode, mIsAlpha); + + // it is invalid to have any alpha mode other than blend if transparency is greater than zero ... + // Want masking? Want emissive? Tough! You get BLEND! + alpha_mode = (transparency > 0.f) ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : alpha_mode; + + // ... unless there is no alpha channel in the texture, in which case alpha mode MUST be none + alpha_mode = mIsAlpha ? alpha_mode : LLMaterial::DIFFUSE_ALPHA_MODE_NONE; + + mComboAlphaMode->getSelectionInterface()->selectNthItem(alpha_mode); + updateAlphaControls(); + + mExcludeWater &= (LLMaterial::DIFFUSE_ALPHA_MODE_BLEND == alpha_mode); + } + // Water exclusion { mCheckHideWater->setEnabled(editable && !has_pbr_material && !isMediaTexSelected()); @@ -1188,65 +1245,11 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) // Texture { - LLGLenum image_format = GL_RGB; - bool identical_image_format = false; - bool missing_asset = false; - LLSelectedTE::getImageFormat(image_format, identical_image_format, missing_asset); - - if (!missing_asset) - { - 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; - } - } - else - { - // Don't know image's properties, use material's mode value - mIsAlpha = true; - } - if (LLViewerMedia::getInstance()->textureHasMedia(id)) { mBtnAlign->setEnabled(editable); } - // Diffuse Alpha Mode - - // Init to the default that is appropriate for the alpha content of the asset - // - U8 alpha_mode = mIsAlpha ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE; - - bool identical_alpha_mode = false; - - // See if that's been overridden by a material setting for same... - // - LLSelectedTEMaterial::getCurrentDiffuseAlphaMode(alpha_mode, identical_alpha_mode, mIsAlpha); - - // it is invalid to have any alpha mode other than blend if transparency is greater than zero ... - // Want masking? Want emissive? Tough! You get BLEND! - alpha_mode = (transparency > 0.f) ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : alpha_mode; - - // ... unless there is no alpha channel in the texture, in which case alpha mode MUST be none - alpha_mode = mIsAlpha ? alpha_mode : LLMaterial::DIFFUSE_ALPHA_MODE_NONE; - - mComboAlphaMode->getSelectionInterface()->selectNthItem(alpha_mode); - - updateAlphaControls(); - if (mTextureCtrl) { if (identical_diffuse) -- cgit v1.3 From b084d842c9900e532cba11e1e5a4e85299a0e184 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 6 May 2025 23:05:27 +0300 Subject: #4008 Fix media scale adjustments with pbr applied --- indra/newview/llpanelface.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 99471a2555..a7b50f8364 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -1099,6 +1099,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) } mRadioPbrType->setEnabled(editable); const bool pbr_selected = mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR; + const bool media_selected = mComboMatMedia->getCurrentIndex() == MATMEDIA_MEDIA; const bool texture_info_selected = pbr_selected && mRadioPbrType->getSelectedIndex() != PBRTYPE_RENDER_MATERIAL_ID; mCheckSyncSettings->setEnabled(editable); @@ -1402,7 +1403,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) mShinyScaleU->setValue(spec_scale_s); mBumpyScaleU->setValue(norm_scale_s); - mTexScaleU->setEnabled(editable && has_material); + mTexScaleU->setEnabled(editable && (has_material || media_selected)); mShinyScaleU->setEnabled(editable && has_material && specmap_id.notNull()); mBumpyScaleU->setEnabled(editable && has_material && normmap_id.notNull()); @@ -1441,7 +1442,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) bool norm_scale_tentative = !identical_norm_scale_t; bool spec_scale_tentative = !identical_spec_scale_t; - mTexScaleV->setEnabled(editable && has_material); + mTexScaleV->setEnabled(editable && (has_material || media_selected)); mShinyScaleV->setEnabled(editable && has_material && specmap_id.notNull()); mBumpyScaleV->setEnabled(editable && has_material && normmap_id.notNull()); @@ -1487,7 +1488,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) mShinyOffsetU->setTentative(LLSD(spec_offset_u_tentative)); mBumpyOffsetU->setTentative(LLSD(norm_offset_u_tentative)); - mTexOffsetU->setEnabled(editable && has_material); + mTexOffsetU->setEnabled(editable && (has_material || media_selected)); mShinyOffsetU->setEnabled(editable && has_material && specmap_id.notNull()); mBumpyOffsetU->setEnabled(editable && has_material && normmap_id.notNull()); } @@ -1517,7 +1518,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) mBumpyOffsetV->setTentative(LLSD(norm_offset_v_tentative)); mShinyOffsetV->setTentative(LLSD(spec_offset_v_tentative)); - mTexOffsetV->setEnabled(editable && has_material); + mTexOffsetV->setEnabled(editable && (has_material || media_selected)); mShinyOffsetV->setEnabled(editable && has_material && specmap_id.notNull()); mBumpyOffsetV->setEnabled(editable && has_material && normmap_id.notNull()); } @@ -1544,7 +1545,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) F32 norm_rot_deg = norm_rotation * RAD_TO_DEG; F32 spec_rot_deg = spec_rotation * RAD_TO_DEG; - mTexRotate->setEnabled(editable && has_material); + mTexRotate->setEnabled(editable && (has_material || media_selected)); mShinyRotate->setEnabled(editable && has_material && specmap_id.notNull()); mBumpyRotate->setEnabled(editable && has_material && normmap_id.notNull()); @@ -1661,7 +1662,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) mTexRepeat->setValue(editable ? repeats : 1.0f); } mTexRepeat->setTentative(LLSD(repeats_tentative)); - mTexRepeat->setEnabled(has_material && !identical_planar_texgen && enabled); + mTexRepeat->setEnabled(!identical_planar_texgen && enabled && (has_material || media_selected)); } } -- cgit v1.3 From fb34971786fd499d08ff42a76d1b1e458dc8fe24 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 12 May 2025 20:37:08 +0300 Subject: Revert "#4008 Fix media scale adjustments with pbr applied" This reverts commit b084d842c9900e532cba11e1e5a4e85299a0e184. --- indra/newview/llpanelface.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index a7b50f8364..99471a2555 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -1099,7 +1099,6 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) } mRadioPbrType->setEnabled(editable); const bool pbr_selected = mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR; - const bool media_selected = mComboMatMedia->getCurrentIndex() == MATMEDIA_MEDIA; const bool texture_info_selected = pbr_selected && mRadioPbrType->getSelectedIndex() != PBRTYPE_RENDER_MATERIAL_ID; mCheckSyncSettings->setEnabled(editable); @@ -1403,7 +1402,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) mShinyScaleU->setValue(spec_scale_s); mBumpyScaleU->setValue(norm_scale_s); - mTexScaleU->setEnabled(editable && (has_material || media_selected)); + mTexScaleU->setEnabled(editable && has_material); mShinyScaleU->setEnabled(editable && has_material && specmap_id.notNull()); mBumpyScaleU->setEnabled(editable && has_material && normmap_id.notNull()); @@ -1442,7 +1441,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) bool norm_scale_tentative = !identical_norm_scale_t; bool spec_scale_tentative = !identical_spec_scale_t; - mTexScaleV->setEnabled(editable && (has_material || media_selected)); + mTexScaleV->setEnabled(editable && has_material); mShinyScaleV->setEnabled(editable && has_material && specmap_id.notNull()); mBumpyScaleV->setEnabled(editable && has_material && normmap_id.notNull()); @@ -1488,7 +1487,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) mShinyOffsetU->setTentative(LLSD(spec_offset_u_tentative)); mBumpyOffsetU->setTentative(LLSD(norm_offset_u_tentative)); - mTexOffsetU->setEnabled(editable && (has_material || media_selected)); + mTexOffsetU->setEnabled(editable && has_material); mShinyOffsetU->setEnabled(editable && has_material && specmap_id.notNull()); mBumpyOffsetU->setEnabled(editable && has_material && normmap_id.notNull()); } @@ -1518,7 +1517,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) mBumpyOffsetV->setTentative(LLSD(norm_offset_v_tentative)); mShinyOffsetV->setTentative(LLSD(spec_offset_v_tentative)); - mTexOffsetV->setEnabled(editable && (has_material || media_selected)); + mTexOffsetV->setEnabled(editable && has_material); mShinyOffsetV->setEnabled(editable && has_material && specmap_id.notNull()); mBumpyOffsetV->setEnabled(editable && has_material && normmap_id.notNull()); } @@ -1545,7 +1544,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) F32 norm_rot_deg = norm_rotation * RAD_TO_DEG; F32 spec_rot_deg = spec_rotation * RAD_TO_DEG; - mTexRotate->setEnabled(editable && (has_material || media_selected)); + mTexRotate->setEnabled(editable && has_material); mShinyRotate->setEnabled(editable && has_material && specmap_id.notNull()); mBumpyRotate->setEnabled(editable && has_material && normmap_id.notNull()); @@ -1662,7 +1661,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) mTexRepeat->setValue(editable ? repeats : 1.0f); } mTexRepeat->setTentative(LLSD(repeats_tentative)); - mTexRepeat->setEnabled(!identical_planar_texgen && enabled && (has_material || media_selected)); + mTexRepeat->setEnabled(has_material && !identical_planar_texgen && enabled); } } -- cgit v1.3 From 210abc3755038d3b8630a646734df52fa54459fd Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko Date: Thu, 10 Jul 2025 15:15:10 +0300 Subject: #4349 fix repeats cannot be adjusted for specular when a normal map is not applied --- indra/newview/llpanelface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 0086a9a86d..25dd37590d 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -276,7 +276,7 @@ LLRender::eTexIndex LLPanelFace::getMatTextureChannel() return LLRender::NORMAL_MAP; break; case MATTYPE_SPECULAR: // "Shininess (specular)" - if (getCurrentNormalMap().notNull()) + if (getCurrentSpecularMap().notNull()) return LLRender::SPECULAR_MAP; break; } -- cgit v1.3 From dcd9d368c2633576d9d3896c075d25346e818883 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 16 Jul 2025 20:31:37 +0300 Subject: #3964 Don't spawn CEF instances for the build tools unless strictly needed --- indra/newview/llfloatermediasettings.cpp | 9 ++++++++- indra/newview/llfloatermediasettings.h | 2 +- indra/newview/llpanelface.cpp | 17 ++++++++++------- 3 files changed, 19 insertions(+), 9 deletions(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llfloatermediasettings.cpp b/indra/newview/llfloatermediasettings.cpp index 2496887c9d..81eab52e6c 100644 --- a/indra/newview/llfloatermediasettings.cpp +++ b/indra/newview/llfloatermediasettings.cpp @@ -180,8 +180,15 @@ void LLFloaterMediaSettings::onClose(bool app_quitting) //////////////////////////////////////////////////////////////////////////////// //static -void LLFloaterMediaSettings::initValues( const LLSD& media_settings, bool editable ) +void LLFloaterMediaSettings::initValues( const LLSD& media_settings, bool editable, bool has_media_info, bool multiple_media, bool multiple_valid_media) { + if (!sInstance) + { + return; + } + sInstance->mIdenticalHasMediaInfo = has_media_info; + sInstance->mMultipleMedia = multiple_media; + sInstance->mMultipleValidMedia = multiple_valid_media; if (sInstance->hasFocus()) return; // Clear values diff --git a/indra/newview/llfloatermediasettings.h b/indra/newview/llfloatermediasettings.h index 38730ddc98..7ed7ab246f 100644 --- a/indra/newview/llfloatermediasettings.h +++ b/indra/newview/llfloatermediasettings.h @@ -48,7 +48,7 @@ public: static LLFloaterMediaSettings* getInstance(); static bool instanceExists(); static void apply(); - static void initValues( const LLSD& media_settings , bool editable); + static void initValues( const LLSD& media_settings , bool editable, bool has_media_info, bool multiple_media, bool multiple_valid_media); static void clearValues( bool editable); LLPanelMediaSettingsSecurity* getPanelSecurity(){return mPanelMediaSettingsSecurity;}; diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 25dd37590d..9076576f00 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -2209,7 +2209,7 @@ void LLPanelFace::refreshMedia() // check if all faces have media(or, all dont have media) - LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo = selected_objects->getSelectedTEValue(&func, bool_has_media); + bool identical_has_media_info = selected_objects->getSelectedTEValue(&func, bool_has_media); const LLMediaEntry default_media_data; @@ -2231,7 +2231,8 @@ void LLPanelFace::refreshMedia() } func_media_data(default_media_data); LLMediaEntry media_data_get; - LLFloaterMediaSettings::getInstance()->mMultipleMedia = !(selected_objects->getSelectedTEValue(&func_media_data, media_data_get)); + bool multiple_media = !(selected_objects->getSelectedTEValue(&func_media_data, media_data_get)); + bool multiple_valid_media = false; std::string multi_media_info_str = LLTrans::getString("Multiple Media"); std::string media_title = ""; @@ -2240,12 +2241,12 @@ void LLPanelFace::refreshMedia() mAddMedia->setEnabled(editable); // IF all the faces have media (or all dont have media) - if (LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo) + if (identical_has_media_info) { // TODO: get media title and set it. mTitleMediaText->clear(); // if identical is set, all faces are same (whether all empty or has the same media) - if (!(LLFloaterMediaSettings::getInstance()->mMultipleMedia)) + if (!multiple_media) { // Media data is valid if (media_data_get != default_media_data) @@ -2266,9 +2267,9 @@ void LLPanelFace::refreshMedia() else // not all face has media but at least one does. { // seleted faces have not identical value - LLFloaterMediaSettings::getInstance()->mMultipleValidMedia = selected_objects->isMultipleTEValue(&func_media_data, default_media_data); + multiple_valid_media = selected_objects->isMultipleTEValue(&func_media_data, default_media_data); - if (LLFloaterMediaSettings::getInstance()->mMultipleValidMedia) + if (multiple_valid_media) { media_title = multi_media_info_str; } @@ -2305,7 +2306,7 @@ void LLPanelFace::refreshMedia() // load values for media settings updateMediaSettings(); - LLFloaterMediaSettings::initValues(mMediaSettings, editable); + LLFloaterMediaSettings::initValues(mMediaSettings, editable, identical_has_media_info, multiple_media, multiple_valid_media); } void LLPanelFace::unloadMedia() @@ -3378,6 +3379,7 @@ void LLPanelFace::onSelectNormalTexture(const LLSD& data) // TODO: test if there is media on the item and only allow editing if present void LLPanelFace::onClickBtnEditMedia() { + LLFloaterMediaSettings::getInstance(); // make sure floater we are about to open exists before refreshMedia refreshMedia(); LLFloaterReg::showInstance("media_settings"); } @@ -3396,6 +3398,7 @@ void LLPanelFace::onClickBtnAddMedia() // check if multiple faces are selected if (LLSelectMgr::getInstance()->getSelection()->isMultipleTESelected()) { + LLFloaterMediaSettings::getInstance(); // make sure floater we are about to open exists before refreshMedia refreshMedia(); LLNotificationsUtil::add("MultipleFacesSelected", LLSD(), LLSD(), multipleFacesSelectedConfirm); } -- cgit v1.3 From 8679b86cdebed65c116dc02978cbcd83e8da4fa5 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> Date: Wed, 15 Oct 2025 22:32:06 +0300 Subject: #2570 Fix extra setGLTFRenderMaterial setRenderMaterialID already calls setGLTFRenderMaterial --- indra/newview/llpanelface.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 3ab48f69c8..182b648914 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -4721,7 +4721,6 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te) if (allow) { objectp->setRenderMaterialID(te, te_data["te"]["pbr"].asUUID(), false /*managing our own update*/); - tep->setGLTFRenderMaterial(nullptr); tep->setGLTFMaterialOverride(nullptr); if (te_data["te"].has("pbr_override")) @@ -4737,7 +4736,6 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te) else { objectp->setRenderMaterialID(te, LLUUID::null, false /*send in bulk later*/ ); - tep->setGLTFRenderMaterial(nullptr); tep->setGLTFMaterialOverride(nullptr); // blank out most override data on the server -- cgit v1.3 From 4ca362fd1b32d50c8c7abfb1d61d86d735cb7487 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> Date: Wed, 19 Nov 2025 11:40:45 +0200 Subject: #4991 Cant set cut off mask --- indra/newview/llpanelface.cpp | 30 ++++++++++++++++-------------- indra/newview/llpanelface.h | 2 +- 2 files changed, 17 insertions(+), 15 deletions(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 182b648914..de8ab95dee 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -1166,26 +1166,22 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) bool missing_asset = false; { LLGLenum image_format = GL_RGB; + bool has_alpha = false; bool identical_image_format = false; - LLSelectedTE::getImageFormat(image_format, identical_image_format, missing_asset); + LLSelectedTE::getImageFormat(image_format, has_alpha, identical_image_format, missing_asset); if (!missing_asset) { - mIsAlpha = false; + mIsAlpha = has_alpha; 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; + LL_WARNS() << "Unexpected tex format in LLPanelFace..." << LL_ENDL; } break; } @@ -3292,23 +3288,22 @@ void LLPanelFace::onSelectTexture() sendTexture(); LLGLenum image_format; + bool has_alpha; bool identical_image_format = false; bool missing_asset = false; - LLSelectedTE::getImageFormat(image_format, identical_image_format, missing_asset); + LLSelectedTE::getImageFormat(image_format, has_alpha, identical_image_format, missing_asset); - U32 alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE; if (!missing_asset) { + U32 alpha_mode = has_alpha ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE; switch (image_format) { case GL_RGBA: case GL_ALPHA: - alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND; - break; case GL_RGB: break; default: - LL_WARNS() << "Unexpected tex format in LLPanelFace...resorting to no alpha" << LL_ENDL; + LL_WARNS() << "Unexpected tex format in LLPanelFace..." << LL_ENDL; break; } @@ -5258,12 +5253,13 @@ void LLPanelFace::LLSelectedTE::getFace(LLFace*& face_to_return, bool& identical identical_face = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_te_face_func, face_to_return, false, (LLFace*)nullptr); } -void LLPanelFace::LLSelectedTE::getImageFormat(LLGLenum& image_format_to_return, bool& identical_face, bool& missing_asset) +void LLPanelFace::LLSelectedTE::getImageFormat(LLGLenum& image_format_to_return, bool& has_alpha, bool& identical_face, bool& missing_asset) { struct LLSelectedTEGetmatId : public LLSelectedTEFunctor { LLSelectedTEGetmatId() : mImageFormat(GL_RGB) + , mHasAlpha(false) , mIdentical(true) , mMissingAsset(false) , mFirstRun(true) @@ -5278,6 +5274,10 @@ void LLPanelFace::LLSelectedTE::getImageFormat(LLGLenum& image_format_to_return, { format = image->getPrimaryFormat(); missing = image->isMissingAsset(); + if (format == GL_RGBA || format == GL_ALPHA) + { + mHasAlpha = true; + } } if (mFirstRun) @@ -5294,6 +5294,7 @@ void LLPanelFace::LLSelectedTE::getImageFormat(LLGLenum& image_format_to_return, return true; } LLGLenum mImageFormat; + bool mHasAlpha; bool mIdentical; bool mMissingAsset; bool mFirstRun; @@ -5301,6 +5302,7 @@ void LLPanelFace::LLSelectedTE::getImageFormat(LLGLenum& image_format_to_return, LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func); image_format_to_return = func.mImageFormat; + has_alpha = func.mHasAlpha; identical_face = func.mIdentical; missing_asset = func.mMissingAsset; } diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 8a8460204c..63fee6bab8 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -697,7 +697,7 @@ public: { public: static void getFace(class LLFace*& face_to_return, bool& identical_face); - static void getImageFormat(LLGLenum& image_format_to_return, bool& identical_face, bool& missing_asset); + static void getImageFormat(LLGLenum& image_format_to_return, bool& has_alpha, bool& identical_face, bool& missing_asset); static void getTexId(LLUUID& id, bool& identical); static void getPbrMaterialId(LLUUID& id, bool& identical, bool& has_pbr, bool& has_faces_without_pbr); static void getObjectScaleS(F32& scale_s, bool& identical); -- cgit v1.3