From ad533fcd6b1a3433273fa6d75e19a7ce56c75867 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 14 Jun 2022 23:39:11 -0500 Subject: SL-17586 WIP -- LLMaterialEditor prototype and "New Material" inventory buttons. --- indra/newview/llmaterialeditor.cpp | 207 +++++++++++++++++++++++++++++++++++++ 1 file changed, 207 insertions(+) create mode 100644 indra/newview/llmaterialeditor.cpp (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp new file mode 100644 index 0000000000..6e7f7adfed --- /dev/null +++ b/indra/newview/llmaterialeditor.cpp @@ -0,0 +1,207 @@ +/** + * @file llmaterialeditor.cpp + * @brief Implementation of the notecard editor + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llmaterialeditor.h" +#include "llcombobox.h" + +#include "tinygltf/tiny_gltf.h" + +///---------------------------------------------------------------------------- +/// Class LLPreviewNotecard +///---------------------------------------------------------------------------- + +// Default constructor +LLMaterialEditor::LLMaterialEditor(const LLSD& key) + : LLFloater(key) +{ +} + +BOOL LLMaterialEditor::postBuild() +{ + childSetAction("save", boost::bind(&LLMaterialEditor::onClickSave, this)); + return LLFloater::postBuild(); +} + +LLUUID LLMaterialEditor::getAlbedoId() +{ + return childGetValue("albedo texture").asUUID(); +} + +LLColor4 LLMaterialEditor::getAlbedoColor() +{ + LLColor4 ret = LLColor4(childGetValue("albedo color")); + ret.mV[3] = getTransparency(); + return ret; +} + + +F32 LLMaterialEditor::getTransparency() +{ + return childGetValue("transparency").asReal(); +} + +std::string LLMaterialEditor::getAlphaMode() +{ + return childGetValue("alpha mode").asString(); +} + +F32 LLMaterialEditor::getAlphaCutoff() +{ + return childGetValue("alpha cutoff").asReal(); +} + +LLUUID LLMaterialEditor::getMetallicRoughnessId() +{ + return childGetValue("metallic-roughness texture").asUUID(); +} + +F32 LLMaterialEditor::getMetalnessFactor() +{ + return childGetValue("metalness factor").asReal(); +} + +F32 LLMaterialEditor::getRoughnessFactor() +{ + return childGetValue("roughness factor").asReal(); +} + +LLUUID LLMaterialEditor::getEmissiveId() +{ + return childGetValue("emissive texture").asUUID(); +} + +LLColor4 LLMaterialEditor::getEmissiveColor() +{ + return LLColor4(childGetValue("emissive color")); +} + +LLUUID LLMaterialEditor::getNormalId() +{ + return childGetValue("normal texture").asUUID(); +} + +bool LLMaterialEditor::getDoubleSided() +{ + return childGetValue("double sided").asBoolean(); +} + + +static void write_color(const LLColor4& color, std::vector& c) +{ + for (int i = 0; i < c.size(); ++i) // NOTE -- use c.size because some gltf colors are 3-component + { + c[i] = color.mV[i]; + } +} + +static U32 write_texture(const LLUUID& id, tinygltf::Model& model) +{ + tinygltf::Image image; + image.uri = id.asString(); + model.images.push_back(image); + U32 image_idx = model.images.size() - 1; + + tinygltf::Texture texture; + texture.source = image_idx; + model.textures.push_back(texture); + U32 texture_idx = model.textures.size() - 1; + + return texture_idx; +} + +void LLMaterialEditor::onClickSave() +{ + tinygltf::Model model; + model.materials.resize(1); + tinygltf::PbrMetallicRoughness& pbrMaterial = model.materials[0].pbrMetallicRoughness; + + // write albedo + LLColor4 albedo_color = getAlbedoColor(); + albedo_color.mV[3] = getTransparency(); + write_color(albedo_color, pbrMaterial.baseColorFactor); + + model.materials[0].alphaCutoff = getAlphaCutoff(); + model.materials[0].alphaMode = getAlphaMode(); + + LLUUID albedo_id = getAlbedoId(); + + if (albedo_id.notNull()) + { + U32 texture_idx = write_texture(albedo_id, model); + + pbrMaterial.baseColorTexture.index = texture_idx; + } + + // write metallic/roughness + F32 metalness = getMetalnessFactor(); + F32 roughness = getRoughnessFactor(); + + pbrMaterial.metallicFactor = metalness; + pbrMaterial.roughnessFactor = roughness; + + LLUUID mr_id = getMetallicRoughnessId(); + if (mr_id.notNull()) + { + U32 texture_idx = write_texture(mr_id, model); + pbrMaterial.metallicRoughnessTexture.index = texture_idx; + } + + //write emissive + LLColor4 emissive_color = getEmissiveColor(); + model.materials[0].emissiveFactor.resize(3); + write_color(emissive_color, model.materials[0].emissiveFactor); + + LLUUID emissive_id = getEmissiveId(); + if (emissive_id.notNull()) + { + U32 idx = write_texture(emissive_id, model); + model.materials[0].emissiveTexture.index = idx; + } + + //write normal + LLUUID normal_id = getNormalId(); + if (normal_id.notNull()) + { + U32 idx = write_texture(normal_id, model); + model.materials[0].normalTexture.index = idx; + } + + //write doublesided + model.materials[0].doubleSided = getDoubleSided(); + + std::ostringstream str; + + tinygltf::TinyGLTF gltf; + model.asset.version = "2.0"; + gltf.WriteGltfSceneToStream(&model, str, true, false); + + std::string dump = str.str(); + + LL_INFOS() << dump << LL_ENDL; +} + -- cgit v1.2.3 From f5d66e79eec07384ef6f4fd3f516f7a9d010fb9e Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 15 Jun 2022 17:03:38 -0500 Subject: SL-17605 WIP - Upload->Material now lets you pick a GLTF file and imports the first material in the GLTF file to the Material Editor --- indra/newview/llmaterialeditor.cpp | 241 +++++++++++++++++++++++++++++++++++++ 1 file changed, 241 insertions(+) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 6e7f7adfed..f23564c51b 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -28,6 +28,9 @@ #include "llmaterialeditor.h" #include "llcombobox.h" +#include "llviewermenufile.h" +#include "llappviewer.h" +#include "llviewertexture.h" #include "tinygltf/tiny_gltf.h" @@ -52,6 +55,11 @@ LLUUID LLMaterialEditor::getAlbedoId() return childGetValue("albedo texture").asUUID(); } +void LLMaterialEditor::setAlbedoId(const LLUUID& id) +{ + childSetValue("albedo texture", id); +} + LLColor4 LLMaterialEditor::getAlbedoColor() { LLColor4 ret = LLColor4(childGetValue("albedo color")); @@ -60,6 +68,12 @@ LLColor4 LLMaterialEditor::getAlbedoColor() } +void LLMaterialEditor::setAlbedoColor(const LLColor4& color) +{ + childSetValue("albedo color", color.getValue()); + childSetValue("transparency", color.mV[3]); +} + F32 LLMaterialEditor::getTransparency() { return childGetValue("transparency").asReal(); @@ -70,46 +84,91 @@ std::string LLMaterialEditor::getAlphaMode() return childGetValue("alpha mode").asString(); } +void LLMaterialEditor::setAlphaMode(const std::string& alpha_mode) +{ + childSetValue("alpha mode", alpha_mode); +} + F32 LLMaterialEditor::getAlphaCutoff() { return childGetValue("alpha cutoff").asReal(); } +void LLMaterialEditor::setAlphaCutoff(F32 alpha_cutoff) +{ + childSetValue("alpha cutoff", alpha_cutoff); +} + LLUUID LLMaterialEditor::getMetallicRoughnessId() { return childGetValue("metallic-roughness texture").asUUID(); } +void LLMaterialEditor::setMetallicRoughnessId(const LLUUID& id) +{ + childSetValue("metallic-roughness texture", id); +} + F32 LLMaterialEditor::getMetalnessFactor() { return childGetValue("metalness factor").asReal(); } +void LLMaterialEditor::setMetalnessFactor(F32 factor) +{ + childSetValue("metalness factor", factor); +} + F32 LLMaterialEditor::getRoughnessFactor() { return childGetValue("roughness factor").asReal(); } +void LLMaterialEditor::setRoughnessFactor(F32 factor) +{ + childSetValue("roughness factor", factor); +} + LLUUID LLMaterialEditor::getEmissiveId() { return childGetValue("emissive texture").asUUID(); } +void LLMaterialEditor::setEmissiveId(const LLUUID& id) +{ + childSetValue("emissive texture", id); +} + LLColor4 LLMaterialEditor::getEmissiveColor() { return LLColor4(childGetValue("emissive color")); } +void LLMaterialEditor::setEmissiveColor(const LLColor4& color) +{ + childSetValue("emissive color", color.getValue()); +} + LLUUID LLMaterialEditor::getNormalId() { return childGetValue("normal texture").asUUID(); } +void LLMaterialEditor::setNormalId(const LLUUID& id) +{ + childSetValue("normal texture", id); +} + bool LLMaterialEditor::getDoubleSided() { return childGetValue("double sided").asBoolean(); } +void LLMaterialEditor::setDoubleSided(bool double_sided) +{ + childSetValue("double sided", double_sided); +} + static void write_color(const LLColor4& color, std::vector& c) { @@ -205,3 +264,185 @@ void LLMaterialEditor::onClickSave() LL_INFOS() << dump << LL_ENDL; } +class LLMaterialFilePicker : public LLFilePickerThread +{ +public: + LLMaterialFilePicker(LLMaterialEditor* me); + virtual void notify(const std::vector& filenames); + void loadMaterial(const std::string& filename); + static void textureLoadedCallback(BOOL success, LLViewerFetchedTexture* src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata); +private: + LLMaterialEditor* mME; +}; + +LLMaterialFilePicker::LLMaterialFilePicker(LLMaterialEditor* me) + : LLFilePickerThread(LLFilePicker::FFLOAD_MODEL) +{ + mME = me; +} + +void LLMaterialFilePicker::notify(const std::vector& filenames) +{ + if (LLAppViewer::instance()->quitRequested()) + { + return; + } + + + if (filenames.size() > 0) + { + loadMaterial(filenames[0]); + } +} + +static std::string get_texture_uri(const tinygltf::Model& model, S32 texture_index) +{ + std::string ret; + + if (texture_index >= 0) + { + S32 source_idx = model.textures[texture_index].source; + if (source_idx >= 0) + { + ret = model.images[source_idx].uri; + } + } + + return ret; +} + +static LLViewerFetchedTexture* get_texture(const std::string& folder, const tinygltf::Model& model, S32 texture_index) +{ + LLViewerFetchedTexture* ret = nullptr; + std::string file = get_texture_uri(model, texture_index); + if (!file.empty()) + { + std::string uri = folder; + gDirUtilp->append(uri, file); + + ret = LLViewerTextureManager::getFetchedTextureFromUrl("file://" + LLURI::unescape(uri), FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_PREVIEW); + //ret->setLoadedCallback(LLMaterialFilePicker::textureLoadedCallback, 0, TRUE, FALSE, opaque, NULL, FALSE); + ret->forceToSaveRawImage(0, F32_MAX); + } + return ret; +} + +static LLColor4 get_color(const std::vector& in) +{ + LLColor4 out; + for (S32 i = 0; i < llmin((S32) in.size(), 4); ++i) + { + out.mV[i] = in[i]; + } + + return out; +} + +void LLMaterialFilePicker::textureLoadedCallback(BOOL success, LLViewerFetchedTexture* src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata) +{ +} + + +void LLMaterialFilePicker::loadMaterial(const std::string& filename) +{ + tinygltf::TinyGLTF loader; + std::string error_msg; + std::string warn_msg; + + bool loaded = false; + tinygltf::Model model_in; + + std::string filename_lc = filename; + LLStringUtil::toLower(filename_lc); + + // Load a tinygltf model fom a file. Assumes that the input filename has already been + // been sanitized to one of (.gltf , .glb) extensions, so does a simple find to distinguish. + if (std::string::npos == filename_lc.rfind(".gltf")) + { // file is binary + loaded = loader.LoadBinaryFromFile(&model_in, &error_msg, &warn_msg, filename); + } + else + { // file is ascii + loaded = loader.LoadASCIIFromFile(&model_in, &error_msg, &warn_msg, filename); + } + + if (!loaded) + { + // TODO: show error_msg to user + return; + } + + if (model_in.materials.empty()) + { + // TODO: show error message that materials are missing + return; + } + + std::string folder = gDirUtilp->getDirName(filename); + + + tinygltf::Material material_in = model_in.materials[0]; + + tinygltf::Model model_out; + model_out.asset.version = "2.0"; + model_out.materials.resize(1); + + // get albedo texture + LLPointer albedo_tex = get_texture(folder, model_in, material_in.pbrMetallicRoughness.baseColorTexture.index); + + LLUUID albedo_id; + if (albedo_tex != nullptr) + { + albedo_id = albedo_tex->getID(); + } + + // get metallic-roughness texture + LLPointer mr_tex = get_texture(folder, model_in, material_in.pbrMetallicRoughness.metallicRoughnessTexture.index); + + LLUUID mr_id; + if (mr_tex != nullptr) + { + mr_id = mr_tex->getID(); + } + + // get emissive texture + LLPointer emissive_tex = get_texture(folder, model_in, material_in.emissiveTexture.index); + + LLUUID emissive_id; + if (emissive_tex != nullptr) + { + emissive_id = emissive_tex->getID(); + } + + // get normal map + LLPointer normal_tex = get_texture(folder, model_in, material_in.normalTexture.index); + + LLUUID normal_id; + if (normal_tex != nullptr) + { + normal_id = normal_tex->getID(); + } + + mME->setAlbedoId(albedo_id); + mME->setMetallicRoughnessId(mr_id); + mME->setEmissiveId(emissive_id); + mME->setNormalId(normal_id); + + mME->setAlphaMode(material_in.alphaMode); + mME->setAlphaCutoff(material_in.alphaCutoff); + + mME->setAlbedoColor(get_color(material_in.pbrMetallicRoughness.baseColorFactor)); + mME->setEmissiveColor(get_color(material_in.emissiveFactor)); + + mME->setMetalnessFactor(material_in.pbrMetallicRoughness.metallicFactor); + mME->setRoughnessFactor(material_in.pbrMetallicRoughness.roughnessFactor); + + mME->setDoubleSided(material_in.doubleSided); + + mME->openFloater(); +} + +void LLMaterialEditor::importMaterial() +{ + (new LLMaterialFilePicker(this))->getFile(); +} \ No newline at end of file -- cgit v1.2.3 From 18b0aa03717cd8209b6c239457bcf69f0d39ecf7 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 16 Jun 2022 16:16:53 -0500 Subject: SL-17619 Add support for embedded textures to GLTF importer --- indra/newview/llmaterialeditor.cpp | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index f23564c51b..05e7ff524a 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -295,35 +295,40 @@ void LLMaterialFilePicker::notify(const std::vector& filenames) } } -static std::string get_texture_uri(const tinygltf::Model& model, S32 texture_index) +const tinygltf::Image* get_image_from_texture_index(const tinygltf::Model& model, S32 texture_index) { - std::string ret; - if (texture_index >= 0) { S32 source_idx = model.textures[texture_index].source; if (source_idx >= 0) { - ret = model.images[source_idx].uri; + return &(model.images[source_idx]); } } - return ret; + return nullptr; } static LLViewerFetchedTexture* get_texture(const std::string& folder, const tinygltf::Model& model, S32 texture_index) { LLViewerFetchedTexture* ret = nullptr; - std::string file = get_texture_uri(model, texture_index); - if (!file.empty()) + + const tinygltf::Image* image = get_image_from_texture_index(model, texture_index); + + if (image != nullptr && + image->bits == 8 && + !image->image.empty() && + image->component <= 4) { - std::string uri = folder; - gDirUtilp->append(uri, file); + LLPointer rawImage = new LLImageRaw(&image->image[0], image->width, image->height, image->component); + + ret = LLViewerTextureManager::getFetchedTexture(rawImage, FTType::FTT_LOCAL_FILE, true); - ret = LLViewerTextureManager::getFetchedTextureFromUrl("file://" + LLURI::unescape(uri), FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_PREVIEW); - //ret->setLoadedCallback(LLMaterialFilePicker::textureLoadedCallback, 0, TRUE, FALSE, opaque, NULL, FALSE); ret->forceToSaveRawImage(0, F32_MAX); } + + // TODO: provide helpful error message if image fails to load + return ret; } -- cgit v1.2.3 From 394479d7cc48a0170854e07f14267e28ba247990 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 23 Jun 2022 16:21:53 -0500 Subject: SL-17653 WIP - Apply GLTF material in Material Editor to selected object when you click "Save" --- indra/newview/llmaterialeditor.cpp | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 05e7ff524a..5a0c23d59b 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -31,6 +31,8 @@ #include "llviewermenufile.h" #include "llappviewer.h" #include "llviewertexture.h" +#include "llselectmgr.h" +#include "llvovolume.h" #include "tinygltf/tiny_gltf.h" @@ -195,6 +197,8 @@ static U32 write_texture(const LLUUID& id, tinygltf::Model& model) void LLMaterialEditor::onClickSave() { + applyToSelection(); + tinygltf::Model model; model.materials.resize(1); tinygltf::PbrMetallicRoughness& pbrMaterial = model.materials[0].pbrMetallicRoughness; @@ -450,4 +454,35 @@ void LLMaterialFilePicker::loadMaterial(const std::string& filename) void LLMaterialEditor::importMaterial() { (new LLMaterialFilePicker(this))->getFile(); -} \ No newline at end of file +} + +void LLMaterialEditor::applyToSelection() +{ + LLViewerObject* objectp = LLSelectMgr::instance().getSelection()->getFirstObject(); + if (objectp && objectp->getVolume()) + { + LLGLTFMaterial* mat = new LLGLTFMaterial(); + mat->mAlbedoColor = getAlbedoColor(); + mat->mAlbedoColor.mV[3] = getTransparency(); + mat->mAlbedoId = getAlbedoId(); + + mat->mNormalId = getNormalId(); + + mat->mMetallicRoughnessId = getMetallicRoughnessId(); + mat->mMetallicFactor = getMetalnessFactor(); + mat->mRoughnessFactor = getRoughnessFactor(); + + mat->mEmissiveColor = getEmissiveColor(); + mat->mEmissiveId = getEmissiveId(); + + mat->mDoubleSided = getDoubleSided(); + mat->setAlphaMode(getAlphaMode()); + + LLVOVolume* vobjp = (LLVOVolume*)objectp; + for (int i = 0; i < vobjp->getNumTEs(); ++i) + { + vobjp->getTE(i)->setGLTFMaterial(mat); + vobjp->updateTEMaterialTextures(i); + } + } +} -- cgit v1.2.3 From 6ce3df5514076baaf8b507dc5fda0658b992e296 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 23 Jun 2022 18:06:55 -0500 Subject: SL-17653 Flip imported GLTF textures, remove .dae and .glb/.gltf from file dialogs that don't support them --- indra/newview/llmaterialeditor.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 5a0c23d59b..8b4d3b832b 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -280,7 +280,7 @@ private: }; LLMaterialFilePicker::LLMaterialFilePicker(LLMaterialEditor* me) - : LLFilePickerThread(LLFilePicker::FFLOAD_MODEL) + : LLFilePickerThread(LLFilePicker::FFLOAD_MATERIAL) { mME = me; } @@ -325,6 +325,7 @@ static LLViewerFetchedTexture* get_texture(const std::string& folder, const tiny image->component <= 4) { LLPointer rawImage = new LLImageRaw(&image->image[0], image->width, image->height, image->component); + rawImage->verticalFlip(); ret = LLViewerTextureManager::getFetchedTexture(rawImage, FTType::FTT_LOCAL_FILE, true); @@ -449,6 +450,8 @@ void LLMaterialFilePicker::loadMaterial(const std::string& filename) mME->setDoubleSided(material_in.doubleSided); mME->openFloater(); + + mME->applyToSelection(); } void LLMaterialEditor::importMaterial() @@ -484,5 +487,7 @@ void LLMaterialEditor::applyToSelection() vobjp->getTE(i)->setGLTFMaterial(mat); vobjp->updateTEMaterialTextures(i); } + + vobjp->markForUpdate(TRUE); } } -- cgit v1.2.3 From 0bc7fee11fe43281d5d3c97e95249f9c26af0eb1 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 23 Jun 2022 19:51:11 +0300 Subject: SL-17640 Materials Upload UI #1 1. Allow 'none' textures 2. Disable 'apply now' buttons 3. Switch from loading dae files to just gltf glb --- indra/newview/llmaterialeditor.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 8b4d3b832b..f4bf400844 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -27,9 +27,12 @@ #include "llviewerprecompiledheaders.h" #include "llmaterialeditor.h" + +#include "llappviewer.h" #include "llcombobox.h" +#include "llnotificationsutil.h" +#include "lltrans.h" #include "llviewermenufile.h" -#include "llappviewer.h" #include "llviewertexture.h" #include "llselectmgr.h" #include "llvovolume.h" @@ -101,6 +104,11 @@ void LLMaterialEditor::setAlphaCutoff(F32 alpha_cutoff) childSetValue("alpha cutoff", alpha_cutoff); } +void LLMaterialEditor::setMaterialName(const std::string &name) +{ + setTitle(name); +} + LLUUID LLMaterialEditor::getMetallicRoughnessId() { return childGetValue("metallic-roughness texture").asUUID(); @@ -378,13 +386,14 @@ void LLMaterialFilePicker::loadMaterial(const std::string& filename) if (!loaded) { - // TODO: show error_msg to user + LLNotificationsUtil::add("CannotUploadMaterial"); return; } if (model_in.materials.empty()) { - // TODO: show error message that materials are missing + // materials are missing + LLNotificationsUtil::add("CannotUploadMaterial"); return; } @@ -446,9 +455,12 @@ void LLMaterialFilePicker::loadMaterial(const std::string& filename) mME->setMetalnessFactor(material_in.pbrMetallicRoughness.metallicFactor); mME->setRoughnessFactor(material_in.pbrMetallicRoughness.roughnessFactor); - + mME->setDoubleSided(material_in.doubleSided); + std::string new_material = LLTrans::getString("New Material"); + mME->setMaterialName(new_material); + mME->openFloater(); mME->applyToSelection(); -- cgit v1.2.3 From da1d9139b3412e391b5ed7c868d350760719ee9e Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 24 Jun 2022 01:02:01 +0300 Subject: SL-17640 Materials Upload UI #2 New Fee fields New Buttons --- indra/newview/llmaterialeditor.cpp | 158 ++++++++++++++++++++++++++++++++++--- 1 file changed, 148 insertions(+), 10 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index f4bf400844..86f629db95 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -31,6 +31,7 @@ #include "llappviewer.h" #include "llcombobox.h" #include "llnotificationsutil.h" +#include "lltexturectrl.h" #include "lltrans.h" #include "llviewermenufile.h" #include "llviewertexture.h" @@ -51,18 +52,41 @@ LLMaterialEditor::LLMaterialEditor(const LLSD& key) BOOL LLMaterialEditor::postBuild() { + mAlbedoTextureCtrl = getChild("albedo_texture"); + mMetallicTextureCtrl = getChild("metallic_roughness_texture"); + mEmissiveTextureCtrl = getChild("emissive_texture"); + mNormalTextureCtrl = getChild("normal_texture"); + + mAlbedoTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitAlbedoTexture, this, _1, _2)); + mMetallicTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitMetallicTexture, this, _1, _2)); + mEmissiveTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitEmissiveTexture, this, _1, _2)); + mNormalTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitNormalTexture, this, _1, _2)); + childSetAction("save", boost::bind(&LLMaterialEditor::onClickSave, this)); + childSetAction("save_as", boost::bind(&LLMaterialEditor::onClickSaveAs, this)); + childSetAction("cancel", boost::bind(&LLMaterialEditor::onClickCancel, this)); + return LLFloater::postBuild(); } LLUUID LLMaterialEditor::getAlbedoId() { - return childGetValue("albedo texture").asUUID(); + return mAlbedoTextureCtrl->getValue().asUUID(); } void LLMaterialEditor::setAlbedoId(const LLUUID& id) { - childSetValue("albedo texture", id); + mAlbedoTextureCtrl->setValue(id); + mAlbedoTextureCtrl->setDefaultImageAssetID(id); + + if (id.notNull()) + { + // todo: this does not account for posibility of texture + // being from inventory, need to check that + childSetValue("albedo_upload_fee", getString("upload_fee_string")); + // Only set if we will need to upload this texture + mAlbedoTextureUploadId = id; + } } LLColor4 LLMaterialEditor::getAlbedoColor() @@ -72,7 +96,6 @@ LLColor4 LLMaterialEditor::getAlbedoColor() return ret; } - void LLMaterialEditor::setAlbedoColor(const LLColor4& color) { childSetValue("albedo color", color.getValue()); @@ -107,16 +130,26 @@ void LLMaterialEditor::setAlphaCutoff(F32 alpha_cutoff) void LLMaterialEditor::setMaterialName(const std::string &name) { setTitle(name); + mMaterialName = name; } LLUUID LLMaterialEditor::getMetallicRoughnessId() { - return childGetValue("metallic-roughness texture").asUUID(); + return mMetallicTextureCtrl->getValue().asUUID(); } void LLMaterialEditor::setMetallicRoughnessId(const LLUUID& id) { - childSetValue("metallic-roughness texture", id); + mMetallicTextureCtrl->setValue(id); + mMetallicTextureCtrl->setDefaultImageAssetID(id); + + if (id.notNull()) + { + // todo: this does not account for posibility of texture + // being from inventory, need to check that + childSetValue("metallic_upload_fee", getString("upload_fee_string")); + mMetallicTextureUploadId = id; + } } F32 LLMaterialEditor::getMetalnessFactor() @@ -141,12 +174,21 @@ void LLMaterialEditor::setRoughnessFactor(F32 factor) LLUUID LLMaterialEditor::getEmissiveId() { - return childGetValue("emissive texture").asUUID(); + return mEmissiveTextureCtrl->getValue().asUUID(); } void LLMaterialEditor::setEmissiveId(const LLUUID& id) { - childSetValue("emissive texture", id); + mEmissiveTextureCtrl->setValue(id); + mEmissiveTextureCtrl->setDefaultImageAssetID(id); + + if (id.notNull()) + { + // todo: this does not account for posibility of texture + // being from inventory, need to check that + childSetValue("emissive_upload_fee", getString("upload_fee_string")); + mEmissiveTextureUploadId = id; + } } LLColor4 LLMaterialEditor::getEmissiveColor() @@ -161,12 +203,21 @@ void LLMaterialEditor::setEmissiveColor(const LLColor4& color) LLUUID LLMaterialEditor::getNormalId() { - return childGetValue("normal texture").asUUID(); + return mNormalTextureCtrl->getValue().asUUID(); } void LLMaterialEditor::setNormalId(const LLUUID& id) { - childSetValue("normal texture", id); + mNormalTextureCtrl->setValue(id); + mNormalTextureCtrl->setDefaultImageAssetID(id); + + if (id.notNull()) + { + // todo: this does not account for posibility of texture + // being from inventory, need to check that + childSetValue("normal_upload_fee", getString("upload_fee_string")); + mNormalTextureUploadId = id; + } } bool LLMaterialEditor::getDoubleSided() @@ -179,6 +230,60 @@ void LLMaterialEditor::setDoubleSided(bool double_sided) childSetValue("double sided", double_sided); } +void LLMaterialEditor::onCommitAlbedoTexture(LLUICtrl * ctrl, const LLSD & data) +{ + // might be better to use arrays, to have a single callback + // and not to repeat the same thing for each tecture controls + LLUUID new_val = mAlbedoTextureCtrl->getValue().asUUID(); + if (new_val == mAlbedoTextureUploadId && mAlbedoTextureUploadId.notNull()) + { + childSetValue("albedo_upload_fee", getString("upload_fee_string")); + } + else + { + childSetValue("albedo_upload_fee", getString("no_upload_fee_string")); + } +} + +void LLMaterialEditor::onCommitMetallicTexture(LLUICtrl * ctrl, const LLSD & data) +{ + LLUUID new_val = mMetallicTextureCtrl->getValue().asUUID(); + if (new_val == mMetallicTextureUploadId && mMetallicTextureUploadId.notNull()) + { + childSetValue("metallic_upload_fee", getString("upload_fee_string")); + } + else + { + childSetValue("metallic_upload_fee", getString("no_upload_fee_string")); + } +} + +void LLMaterialEditor::onCommitEmissiveTexture(LLUICtrl * ctrl, const LLSD & data) +{ + LLUUID new_val = mEmissiveTextureCtrl->getValue().asUUID(); + if (new_val == mEmissiveTextureUploadId && mEmissiveTextureUploadId.notNull()) + { + childSetValue("emissive_upload_fee", getString("upload_fee_string")); + } + else + { + childSetValue("emissive_upload_fee", getString("no_upload_fee_string")); + } +} + +void LLMaterialEditor::onCommitNormalTexture(LLUICtrl * ctrl, const LLSD & data) +{ + LLUUID new_val = mNormalTextureCtrl->getValue().asUUID(); + if (new_val == mNormalTextureUploadId && mNormalTextureUploadId.notNull()) + { + childSetValue("normal_upload_fee", getString("upload_fee_string")); + } + else + { + childSetValue("normal_upload_fee", getString("no_upload_fee_string")); + } +} + static void write_color(const LLColor4& color, std::vector& c) { @@ -273,7 +378,40 @@ void LLMaterialEditor::onClickSave() std::string dump = str.str(); - LL_INFOS() << dump << LL_ENDL; + LL_INFOS() << mMaterialName << ": " << dump << LL_ENDL; +} + +void LLMaterialEditor::onClickSaveAs() +{ + LLSD args; + args["DESC"] = mMaterialName; + + LLNotificationsUtil::add("SaveMaterialAs", args, LLSD(), boost::bind(&LLMaterialEditor::onSaveAsCommitCallback, this, _1, _2)); +} + +void LLMaterialEditor::onSaveAsCommitCallback(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (0 == option) + { + std::string new_name = response["message"].asString(); + LLStringUtil::trim(new_name); + if (!new_name.empty()) + { + setMaterialName(new_name); + onClickSave(); + } + else + { + LLNotificationsUtil::add("InvalidMaterialName"); + } + } +} + +void LLMaterialEditor::onClickCancel() +{ + // Todo: confirm usaved changes + closeFloater(); } class LLMaterialFilePicker : public LLFilePickerThread -- cgit v1.2.3 From bce1e9a51581fc42072dbc1448db38e5069c7378 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 24 Jun 2022 11:13:41 -0500 Subject: SL-17658 Make Material Importer strip alpha channels and repack occlusion as needed. --- indra/newview/llmaterialeditor.cpp | 150 +++++++++++++++++++++++++++++++------ 1 file changed, 126 insertions(+), 24 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 8b4d3b832b..e2dce10662 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -313,28 +313,115 @@ const tinygltf::Image* get_image_from_texture_index(const tinygltf::Model& model return nullptr; } -static LLViewerFetchedTexture* get_texture(const std::string& folder, const tinygltf::Model& model, S32 texture_index) +static LLImageRaw* get_texture(const std::string& folder, const tinygltf::Model& model, S32 texture_index) { - LLViewerFetchedTexture* ret = nullptr; - const tinygltf::Image* image = get_image_from_texture_index(model, texture_index); + LLImageRaw* rawImage = nullptr; + if (image != nullptr && image->bits == 8 && !image->image.empty() && image->component <= 4) { - LLPointer rawImage = new LLImageRaw(&image->image[0], image->width, image->height, image->component); + rawImage = new LLImageRaw(&image->image[0], image->width, image->height, image->component); rawImage->verticalFlip(); - - ret = LLViewerTextureManager::getFetchedTexture(rawImage, FTType::FTT_LOCAL_FILE, true); + } - ret->forceToSaveRawImage(0, F32_MAX); + return rawImage; +} + +static void strip_alpha_channel(LLPointer& img) +{ + if (img->getComponents() == 4) + { + LLImageRaw* tmp = new LLImageRaw(img->getWidth(), img->getHeight(), 3); + tmp->copyUnscaled4onto3(img); + img = tmp; } +} + +// copy red channel from src_img to dst_img +// PRECONDITIONS: +// dst_img must be 3 component +// src_img and dst_image must have the same dimensions +static void copy_red_channel(LLPointer& src_img, LLPointer& dst_img) +{ + llassert(src_img->getWidth() == dst_img->getWidth() && src_img->getHeight() == dst_img->getHeight()); + llassert(dst_img->getComponents() == 3); - // TODO: provide helpful error message if image fails to load + U32 pixel_count = dst_img->getWidth() * dst_img->getHeight(); + U8* src = src_img->getData(); + U8* dst = dst_img->getData(); + S8 src_components = src_img->getComponents(); - return ret; + for (U32 i = 0; i < pixel_count; ++i) + { + dst[i * 3] = src[i * src_components]; + } +} + +static void pack_textures(tinygltf::Model& model, tinygltf::Material& material, + LLPointer& albedo_img, + LLPointer& normal_img, + LLPointer& mr_img, + LLPointer& emissive_img, + LLPointer& occlusion_img, + LLPointer& albedo_tex, + LLPointer& normal_tex, + LLPointer& mr_tex, + LLPointer& emissive_tex) +{ + // TODO: downscale if needed + if (albedo_img) + { + albedo_tex = LLViewerTextureManager::getFetchedTexture(albedo_img, FTType::FTT_LOCAL_FILE, true); + } + + if (normal_img) + { + strip_alpha_channel(normal_img); + normal_tex = LLViewerTextureManager::getFetchedTexture(normal_img, FTType::FTT_LOCAL_FILE, true); + } + + if (mr_img) + { + strip_alpha_channel(mr_img); + + if (occlusion_img && material.pbrMetallicRoughness.metallicRoughnessTexture.index != material.occlusionTexture.index) + { + // occlusion is a distinct texture from pbrMetallicRoughness + // pack into mr red channel + int occlusion_idx = material.occlusionTexture.index; + int mr_idx = material.pbrMetallicRoughness.metallicRoughnessTexture.index; + if (occlusion_idx != mr_idx) + { + //scale occlusion image to match resolution of mr image + occlusion_img->scale(mr_img->getWidth(), mr_img->getHeight()); + + copy_red_channel(occlusion_img, mr_img); + } + } + } + else if (occlusion_img) + { + //no mr but occlusion exists, make a white mr_img and copy occlusion red channel over + mr_img = new LLImageRaw(occlusion_img->getWidth(), occlusion_img->getHeight(), 3); + mr_img->clear(255, 255, 255); + copy_red_channel(occlusion_img, mr_img); + + } + + if (mr_img) + { + mr_tex = LLViewerTextureManager::getFetchedTexture(mr_img, FTType::FTT_LOCAL_FILE, true); + } + + if (emissive_img) + { + strip_alpha_channel(emissive_img); + emissive_tex = LLViewerTextureManager::getFetchedTexture(emissive_img, FTType::FTT_LOCAL_FILE, true); + } } static LLColor4 get_color(const std::vector& in) @@ -398,41 +485,56 @@ void LLMaterialFilePicker::loadMaterial(const std::string& filename) model_out.materials.resize(1); // get albedo texture - LLPointer albedo_tex = get_texture(folder, model_in, material_in.pbrMetallicRoughness.baseColorTexture.index); + LLPointer albedo_img = get_texture(folder, model_in, material_in.pbrMetallicRoughness.baseColorTexture.index); + // get normal map + LLPointer normal_img = get_texture(folder, model_in, material_in.normalTexture.index); + // get metallic-roughness texture + LLPointer mr_img = get_texture(folder, model_in, material_in.pbrMetallicRoughness.metallicRoughnessTexture.index); + // get emissive texture + LLPointer emissive_img = get_texture(folder, model_in, material_in.emissiveTexture.index); + // get occlusion map if needed + LLPointer occlusion_img; + if (material_in.occlusionTexture.index != material_in.pbrMetallicRoughness.metallicRoughnessTexture.index) + { + occlusion_img = get_texture(folder, model_in, material_in.occlusionTexture.index); + } + LLPointer albedo_tex; + LLPointer normal_tex; + LLPointer mr_tex; + LLPointer emissive_tex; + + pack_textures(model_in, material_in, albedo_img, normal_img, mr_img, emissive_img, occlusion_img, + albedo_tex, normal_tex, mr_tex, emissive_tex); + LLUUID albedo_id; if (albedo_tex != nullptr) { + albedo_tex->forceToSaveRawImage(0, F32_MAX); albedo_id = albedo_tex->getID(); } - // get metallic-roughness texture - LLPointer mr_tex = get_texture(folder, model_in, material_in.pbrMetallicRoughness.metallicRoughnessTexture.index); + LLUUID normal_id; + if (normal_tex != nullptr) + { + normal_tex->forceToSaveRawImage(0, F32_MAX); + normal_id = normal_tex->getID(); + } LLUUID mr_id; if (mr_tex != nullptr) { + mr_tex->forceToSaveRawImage(0, F32_MAX); mr_id = mr_tex->getID(); } - // get emissive texture - LLPointer emissive_tex = get_texture(folder, model_in, material_in.emissiveTexture.index); - LLUUID emissive_id; if (emissive_tex != nullptr) { + emissive_tex->forceToSaveRawImage(0, F32_MAX); emissive_id = emissive_tex->getID(); } - // get normal map - LLPointer normal_tex = get_texture(folder, model_in, material_in.normalTexture.index); - - LLUUID normal_id; - if (normal_tex != nullptr) - { - normal_id = normal_tex->getID(); - } - mME->setAlbedoId(albedo_id); mME->setMetallicRoughnessId(mr_id); mME->setEmissiveId(emissive_id); -- cgit v1.2.3 From 63daefb39afba64110a48572ac629c83fb31a7c7 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Sat, 25 Jun 2022 16:50:23 +0300 Subject: SL-17640 Materials Upload UI #3 Fixed issues in button layout Added 'unsaved changes' notification --- indra/newview/llmaterialeditor.cpp | 75 +++++++++++++++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 5 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 3c9d722b87..e3206947d5 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -47,6 +47,7 @@ // Default constructor LLMaterialEditor::LLMaterialEditor(const LLSD& key) : LLFloater(key) + , mHasUnsavedChanges(false) { } @@ -66,9 +67,44 @@ BOOL LLMaterialEditor::postBuild() childSetAction("save_as", boost::bind(&LLMaterialEditor::onClickSaveAs, this)); childSetAction("cancel", boost::bind(&LLMaterialEditor::onClickCancel, this)); + boost::function changes_callback = [this](LLUICtrl * ctrl, void*) { setHasUnsavedChanges(true); }; + + childSetCommitCallback("double sided", changes_callback, NULL); + + // Albedo + childSetCommitCallback("albedo color", changes_callback, NULL); + childSetCommitCallback("transparency", changes_callback, NULL); + childSetCommitCallback("alpha mode", changes_callback, NULL); + childSetCommitCallback("alpha cutoff", changes_callback, NULL); + + // Metallic-Roughness + childSetCommitCallback("metalness factor", changes_callback, NULL); + childSetCommitCallback("roughness factor", changes_callback, NULL); + + // Metallic-Roughness + childSetCommitCallback("metalness factor", changes_callback, NULL); + childSetCommitCallback("roughness factor", changes_callback, NULL); + + // Emissive + childSetCommitCallback("emissive color", changes_callback, NULL); + + childSetVisible("unsaved_changes", mHasUnsavedChanges); + return LLFloater::postBuild(); } +void LLMaterialEditor::onClickCloseBtn(bool app_quitting) +{ + if (app_quitting) + { + closeFloater(app_quitting); + } + else + { + onClickCancel(); + } +} + LLUUID LLMaterialEditor::getAlbedoId() { return mAlbedoTextureCtrl->getValue().asUUID(); @@ -230,10 +266,19 @@ void LLMaterialEditor::setDoubleSided(bool double_sided) childSetValue("double sided", double_sided); } +void LLMaterialEditor::setHasUnsavedChanges(bool value) +{ + if (value != mHasUnsavedChanges) + { + mHasUnsavedChanges = value; + childSetVisible("unsaved_changes", value); + } +} + void LLMaterialEditor::onCommitAlbedoTexture(LLUICtrl * ctrl, const LLSD & data) { // might be better to use arrays, to have a single callback - // and not to repeat the same thing for each tecture controls + // and not to repeat the same thing for each tecture control LLUUID new_val = mAlbedoTextureCtrl->getValue().asUUID(); if (new_val == mAlbedoTextureUploadId && mAlbedoTextureUploadId.notNull()) { @@ -243,6 +288,7 @@ void LLMaterialEditor::onCommitAlbedoTexture(LLUICtrl * ctrl, const LLSD & data) { childSetValue("albedo_upload_fee", getString("no_upload_fee_string")); } + setHasUnsavedChanges(true); } void LLMaterialEditor::onCommitMetallicTexture(LLUICtrl * ctrl, const LLSD & data) @@ -256,6 +302,7 @@ void LLMaterialEditor::onCommitMetallicTexture(LLUICtrl * ctrl, const LLSD & dat { childSetValue("metallic_upload_fee", getString("no_upload_fee_string")); } + setHasUnsavedChanges(true); } void LLMaterialEditor::onCommitEmissiveTexture(LLUICtrl * ctrl, const LLSD & data) @@ -269,6 +316,7 @@ void LLMaterialEditor::onCommitEmissiveTexture(LLUICtrl * ctrl, const LLSD & dat { childSetValue("emissive_upload_fee", getString("no_upload_fee_string")); } + setHasUnsavedChanges(true); } void LLMaterialEditor::onCommitNormalTexture(LLUICtrl * ctrl, const LLSD & data) @@ -282,6 +330,7 @@ void LLMaterialEditor::onCommitNormalTexture(LLUICtrl * ctrl, const LLSD & data) { childSetValue("normal_upload_fee", getString("no_upload_fee_string")); } + setHasUnsavedChanges(true); } @@ -386,10 +435,10 @@ void LLMaterialEditor::onClickSaveAs() LLSD args; args["DESC"] = mMaterialName; - LLNotificationsUtil::add("SaveMaterialAs", args, LLSD(), boost::bind(&LLMaterialEditor::onSaveAsCommitCallback, this, _1, _2)); + LLNotificationsUtil::add("SaveMaterialAs", args, LLSD(), boost::bind(&LLMaterialEditor::onSaveAsMsgCallback, this, _1, _2)); } -void LLMaterialEditor::onSaveAsCommitCallback(const LLSD& notification, const LLSD& response) +void LLMaterialEditor::onSaveAsMsgCallback(const LLSD& notification, const LLSD& response) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); if (0 == option) @@ -410,8 +459,23 @@ void LLMaterialEditor::onSaveAsCommitCallback(const LLSD& notification, const LL void LLMaterialEditor::onClickCancel() { - // Todo: confirm usaved changes - closeFloater(); + if (mHasUnsavedChanges) + { + LLNotificationsUtil::add("UsavedMaterialChanges", LLSD(), LLSD(), boost::bind(&LLMaterialEditor::onCancelMsgCallback, this, _1, _2)); + } + else + { + closeFloater(); + } +} + +void LLMaterialEditor::onCancelMsgCallback(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (0 == option) + { + closeFloater(); + } } class LLMaterialFilePicker : public LLFilePickerThread @@ -701,6 +765,7 @@ void LLMaterialFilePicker::loadMaterial(const std::string& filename) std::string new_material = LLTrans::getString("New Material"); mME->setMaterialName(new_material); + mME->setHasUnsavedChanges(true); mME->openFloater(); mME->applyToSelection(); -- cgit v1.2.3 From 231c618a844cee26a3779b703c88d8807df872e6 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 27 Jun 2022 09:59:11 -0500 Subject: SL-17653 Make changes in material editor apply to selection immediately and enable "apply now" checkbox in color swatches. --- indra/newview/llmaterialeditor.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index e3206947d5..7335669f09 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -37,6 +37,7 @@ #include "llviewertexture.h" #include "llselectmgr.h" #include "llvovolume.h" +#include "llcolorswatch.h" #include "tinygltf/tiny_gltf.h" @@ -73,6 +74,7 @@ BOOL LLMaterialEditor::postBuild() // Albedo childSetCommitCallback("albedo color", changes_callback, NULL); + getChild("albedo color")->setCanApplyImmediately(TRUE); childSetCommitCallback("transparency", changes_callback, NULL); childSetCommitCallback("alpha mode", changes_callback, NULL); childSetCommitCallback("alpha cutoff", changes_callback, NULL); @@ -87,6 +89,7 @@ BOOL LLMaterialEditor::postBuild() // Emissive childSetCommitCallback("emissive color", changes_callback, NULL); + getChild("emissive color")->setCanApplyImmediately(TRUE); childSetVisible("unsaved_changes", mHasUnsavedChanges); @@ -273,6 +276,9 @@ void LLMaterialEditor::setHasUnsavedChanges(bool value) mHasUnsavedChanges = value; childSetVisible("unsaved_changes", value); } + + // HACK -- apply any changes to selection immediately + applyToSelection(); } void LLMaterialEditor::onCommitAlbedoTexture(LLUICtrl * ctrl, const LLSD & data) -- cgit v1.2.3 From fbb6eb216f5dc06ff5c7c1cabc6ab46a94918e1b Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink Date: Mon, 27 Jun 2022 10:10:00 -0700 Subject: Initial pass at SL-17602 saving material to inventory from material editor floater. --- indra/newview/llmaterialeditor.cpp | 45 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 8b4d3b832b..828b368063 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -27,11 +27,18 @@ #include "llviewerprecompiledheaders.h" #include "llmaterialeditor.h" + +#include "llagent.h" #include "llcombobox.h" +#include "llinventorymodel.h" #include "llviewermenufile.h" #include "llappviewer.h" #include "llviewertexture.h" +#include "llnotificationsutil.h" +#include "llsdutil.h" #include "llselectmgr.h" +#include "llviewerinventory.h" +#include "llviewerregion.h" #include "llvovolume.h" #include "tinygltf/tiny_gltf.h" @@ -266,6 +273,44 @@ void LLMaterialEditor::onClickSave() std::string dump = str.str(); LL_INFOS() << dump << LL_ENDL; + + // gen a new uuid for this asset + LLTransactionID tid; + tid.generate(); // timestamp-based randomization + uniquification + LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); + std::string res_name = "New Material"; + std::string res_desc = "Saved Material"; + U32 next_owner_perm = LLPermissions::DEFAULT.getMaskNextOwner(); + LLUUID parent = gInventory.findCategoryUUIDForType(LLFolderType::FT_MATERIAL); + const U8 subtype = NO_INV_SUBTYPE; // TODO maybe use AT_SETTINGS and LLSettingsType::ST_MATERIAL ? + + create_inventory_item(gAgent.getID(), gAgent.getSessionID(), parent, tid, res_name, res_desc, + LLAssetType::AT_MATERIAL, LLInventoryType::IT_MATERIAL, subtype, next_owner_perm, + new LLBoostFuncInventoryCallback([output=dump](LLUUID const & inv_item_id){ + // from reference in LLSettingsVOBase::createInventoryItem()/updateInventoryItem() + LLResourceUploadInfo::ptr_t uploadInfo = + std::make_shared( + inv_item_id, + LLAssetType::AT_SETTINGS, // TODO switch to AT_MATERIAL + output, + [](LLUUID item_id, LLUUID new_asset_id, LLUUID new_item_id, LLSD response) { + LL_INFOS("Material") << "inventory item uploaded. item: " << item_id << " asset: " << new_asset_id << " new_item_id: " << new_item_id << " response: " << response << LL_ENDL; + LLSD params = llsd::map("ASSET_ID", new_asset_id); + LLNotificationsUtil::add("MaterialCreated", params); + }); + + const LLViewerRegion* region = gAgent.getRegion(); + if (region) + { + std::string agent_url(region->getCapability("UpdateSettingsAgentInventory")); + if (agent_url.empty()) + { + LL_ERRS() << "missing required agent inventory cap url" << LL_ENDL; + } + LLViewerAssetUpload::EnqueueInventoryUpload(agent_url, uploadInfo); + } + }) + ); } class LLMaterialFilePicker : public LLFilePickerThread -- cgit v1.2.3 From 00a04b87a9fae83fd42419a5b3ace632095405ef Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 27 Jun 2022 22:30:14 +0300 Subject: SL-17640 Fix name usage, fix "apply now" This reverts commit 231c618a844cee26a3779b703c88d8807df872e6, instead color swatched get enabled 'apply now' in xml. --- indra/newview/llmaterialeditor.cpp | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 1744bf9033..f1166fbc0d 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -42,7 +42,6 @@ #include "llviewerinventory.h" #include "llviewerregion.h" #include "llvovolume.h" -#include "llcolorswatch.h" #include "tinygltf/tiny_gltf.h" @@ -73,13 +72,17 @@ BOOL LLMaterialEditor::postBuild() childSetAction("save_as", boost::bind(&LLMaterialEditor::onClickSaveAs, this)); childSetAction("cancel", boost::bind(&LLMaterialEditor::onClickCancel, this)); - boost::function changes_callback = [this](LLUICtrl * ctrl, void*) { setHasUnsavedChanges(true); }; + boost::function changes_callback = [this](LLUICtrl * ctrl, void*) + { + setHasUnsavedChanges(true); + // Apply changes to object live + applyToSelection(); + }; childSetCommitCallback("double sided", changes_callback, NULL); // Albedo childSetCommitCallback("albedo color", changes_callback, NULL); - getChild("albedo color")->setCanApplyImmediately(TRUE); childSetCommitCallback("transparency", changes_callback, NULL); childSetCommitCallback("alpha mode", changes_callback, NULL); childSetCommitCallback("alpha cutoff", changes_callback, NULL); @@ -94,10 +97,13 @@ BOOL LLMaterialEditor::postBuild() // Emissive childSetCommitCallback("emissive color", changes_callback, NULL); - getChild("emissive color")->setCanApplyImmediately(TRUE); childSetVisible("unsaved_changes", mHasUnsavedChanges); + // Todo: + // Disable/enable setCanApplyImmediately() based on + // working from inventory, upload or editing inworld + return LLFloater::postBuild(); } @@ -281,9 +287,6 @@ void LLMaterialEditor::setHasUnsavedChanges(bool value) mHasUnsavedChanges = value; childSetVisible("unsaved_changes", value); } - - // HACK -- apply any changes to selection immediately - applyToSelection(); } void LLMaterialEditor::onCommitAlbedoTexture(LLUICtrl * ctrl, const LLSD & data) @@ -300,6 +303,7 @@ void LLMaterialEditor::onCommitAlbedoTexture(LLUICtrl * ctrl, const LLSD & data) childSetValue("albedo_upload_fee", getString("no_upload_fee_string")); } setHasUnsavedChanges(true); + applyToSelection(); } void LLMaterialEditor::onCommitMetallicTexture(LLUICtrl * ctrl, const LLSD & data) @@ -314,6 +318,7 @@ void LLMaterialEditor::onCommitMetallicTexture(LLUICtrl * ctrl, const LLSD & dat childSetValue("metallic_upload_fee", getString("no_upload_fee_string")); } setHasUnsavedChanges(true); + applyToSelection(); } void LLMaterialEditor::onCommitEmissiveTexture(LLUICtrl * ctrl, const LLSD & data) @@ -328,6 +333,7 @@ void LLMaterialEditor::onCommitEmissiveTexture(LLUICtrl * ctrl, const LLSD & dat childSetValue("emissive_upload_fee", getString("no_upload_fee_string")); } setHasUnsavedChanges(true); + applyToSelection(); } void LLMaterialEditor::onCommitNormalTexture(LLUICtrl * ctrl, const LLSD & data) @@ -342,6 +348,7 @@ void LLMaterialEditor::onCommitNormalTexture(LLUICtrl * ctrl, const LLSD & data) childSetValue("normal_upload_fee", getString("no_upload_fee_string")); } setHasUnsavedChanges(true); + applyToSelection(); } @@ -444,13 +451,12 @@ void LLMaterialEditor::onClickSave() LLTransactionID tid; tid.generate(); // timestamp-based randomization + uniquification LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); - std::string res_name = "New Material"; std::string res_desc = "Saved Material"; U32 next_owner_perm = LLPermissions::DEFAULT.getMaskNextOwner(); LLUUID parent = gInventory.findCategoryUUIDForType(LLFolderType::FT_MATERIAL); const U8 subtype = NO_INV_SUBTYPE; // TODO maybe use AT_SETTINGS and LLSettingsType::ST_MATERIAL ? - create_inventory_item(gAgent.getID(), gAgent.getSessionID(), parent, tid, res_name, res_desc, + create_inventory_item(gAgent.getID(), gAgent.getSessionID(), parent, tid, mMaterialName, res_desc, LLAssetType::AT_MATERIAL, LLInventoryType::IT_MATERIAL, subtype, next_owner_perm, new LLBoostFuncInventoryCallback([output=dump](LLUUID const & inv_item_id){ // from reference in LLSettingsVOBase::createInventoryItem()/updateInventoryItem() @@ -827,6 +833,10 @@ void LLMaterialEditor::importMaterial() void LLMaterialEditor::applyToSelection() { + // Todo: associate with a specific 'selection' instead + // of modifying something that is selected + // This should be disabled when working from agent's + // inventory and for initial upload LLViewerObject* objectp = LLSelectMgr::instance().getSelection()->getFirstObject(); if (objectp && objectp->getVolume()) { -- cgit v1.2.3 From 57805cac68bbc67ecb8a8e76c0ced2ce9b622dd1 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 28 Jun 2022 15:15:57 -0500 Subject: SL-17379 More complete integration of material asset type --- indra/newview/llmaterialeditor.cpp | 630 ++++++++++++++++++++++++++++++++----- 1 file changed, 558 insertions(+), 72 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index f1166fbc0d..ada5bb3882 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -42,8 +42,14 @@ #include "llviewerinventory.h" #include "llviewerregion.h" #include "llvovolume.h" - +#include "roles_constants.h" #include "tinygltf/tiny_gltf.h" +#include "llviewerobjectlist.h" +#include "llfloaterreg.h" +#include "llfilesystem.h" +#include "llsdserialize.h" + +#include ///---------------------------------------------------------------------------- /// Class LLPreviewNotecard @@ -51,9 +57,14 @@ // Default constructor LLMaterialEditor::LLMaterialEditor(const LLSD& key) - : LLFloater(key) + : LLPreview(key) , mHasUnsavedChanges(false) { + const LLInventoryItem* item = getItem(); + if (item) + { + mAssetID = item->getAssetUUID(); + } } BOOL LLMaterialEditor::postBuild() @@ -104,7 +115,7 @@ BOOL LLMaterialEditor::postBuild() // Disable/enable setCanApplyImmediately() based on // working from inventory, upload or editing inworld - return LLFloater::postBuild(); + return LLPreview::postBuild(); } void LLMaterialEditor::onClickCloseBtn(bool app_quitting) @@ -149,7 +160,7 @@ LLColor4 LLMaterialEditor::getAlbedoColor() void LLMaterialEditor::setAlbedoColor(const LLColor4& color) { childSetValue("albedo color", color.getValue()); - childSetValue("transparency", color.mV[3]); + setTransparency(color.mV[3]); } F32 LLMaterialEditor::getTransparency() @@ -157,6 +168,11 @@ F32 LLMaterialEditor::getTransparency() return childGetValue("transparency").asReal(); } +void LLMaterialEditor::setTransparency(F32 transparency) +{ + childSetValue("transparency", transparency); +} + std::string LLMaterialEditor::getAlphaMode() { return childGetValue("alpha mode").asString(); @@ -375,11 +391,51 @@ static U32 write_texture(const LLUUID& id, tinygltf::Model& model) return texture_idx; } + void LLMaterialEditor::onClickSave() { applyToSelection(); + + saveIfNeeded(); +} + +std::string LLMaterialEditor::getGLTFJson(bool prettyprint) +{ tinygltf::Model model; + getGLTFModel(model); + + std::ostringstream str; + + tinygltf::TinyGLTF gltf; + + gltf.WriteGltfSceneToStream(&model, str, prettyprint, false); + + std::string dump = str.str(); + + return dump; +} + +void LLMaterialEditor::getGLBData(std::vector& data) +{ + tinygltf::Model model; + getGLTFModel(model); + + std::ostringstream str; + + tinygltf::TinyGLTF gltf; + + gltf.WriteGltfSceneToStream(&model, str, false, true); + + std::string dump = str.str(); + + data.resize(dump.length()); + + memcpy(&data[0], dump.c_str(), dump.length()); +} + +void LLMaterialEditor::getGLTFModel(tinygltf::Model& model) +{ model.materials.resize(1); tinygltf::PbrMetallicRoughness& pbrMaterial = model.materials[0].pbrMetallicRoughness; @@ -392,11 +448,11 @@ void LLMaterialEditor::onClickSave() model.materials[0].alphaMode = getAlphaMode(); LLUUID albedo_id = getAlbedoId(); - + if (albedo_id.notNull()) { U32 texture_idx = write_texture(albedo_id, model); - + pbrMaterial.baseColorTexture.index = texture_idx; } @@ -406,14 +462,14 @@ void LLMaterialEditor::onClickSave() pbrMaterial.metallicFactor = metalness; pbrMaterial.roughnessFactor = roughness; - + LLUUID mr_id = getMetallicRoughnessId(); if (mr_id.notNull()) { U32 texture_idx = write_texture(mr_id, model); pbrMaterial.metallicRoughnessTexture.index = texture_idx; } - + //write emissive LLColor4 emissive_color = getEmissiveColor(); model.materials[0].emissiveFactor.resize(3); @@ -437,54 +493,213 @@ void LLMaterialEditor::onClickSave() //write doublesided model.materials[0].doubleSided = getDoubleSided(); + model.asset.version = "2.0"; +} + +std::string LLMaterialEditor::getEncodedAsset() +{ + LLSD asset; + asset["version"] = "1.0"; + asset["type"] = "GLTF 2.0"; + asset["data"] = getGLTFJson(false); + std::ostringstream str; + LLSDSerialize::serialize(asset, str, LLSDSerialize::LLSD_BINARY); - tinygltf::TinyGLTF gltf; - model.asset.version = "2.0"; - gltf.WriteGltfSceneToStream(&model, str, true, false); + return str.str(); +} + +bool LLMaterialEditor::decodeAsset(const std::vector& buffer) +{ + LLSD asset; - std::string dump = str.str(); + std::istrstream str(&buffer[0], buffer.size()); + if (LLSDSerialize::deserialize(asset, str, buffer.size())) + { + if (asset.has("version") && asset["version"] == "1.0") + { + if (asset.has("type") && asset["type"] == "GLTF 2.0") + { + if (asset.has("data") && asset["data"].isString()) + { + std::string data = asset["data"]; + + tinygltf::TinyGLTF gltf; + tinygltf::TinyGLTF loader; + std::string error_msg; + std::string warn_msg; + + tinygltf::Model model_in; + + if (loader.LoadASCIIFromString(&model_in, &error_msg, &warn_msg, data.c_str(), data.length(), "")) + { + return setFromGltfModel(model_in, true); + } + else + { + LL_WARNS() << "Failed to decode material asset: " << LL_ENDL; + LL_WARNS() << warn_msg << LL_ENDL; + LL_WARNS() << error_msg << LL_ENDL; + } + } + } + } + } + else + { + LL_WARNS() << "Failed to deserialize material LLSD" << LL_ENDL; + } + + return false; +} - LL_INFOS() << mMaterialName << ": " << dump << LL_ENDL; - - // gen a new uuid for this asset - LLTransactionID tid; - tid.generate(); // timestamp-based randomization + uniquification - LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); - std::string res_desc = "Saved Material"; - U32 next_owner_perm = LLPermissions::DEFAULT.getMaskNextOwner(); - LLUUID parent = gInventory.findCategoryUUIDForType(LLFolderType::FT_MATERIAL); - const U8 subtype = NO_INV_SUBTYPE; // TODO maybe use AT_SETTINGS and LLSettingsType::ST_MATERIAL ? - - create_inventory_item(gAgent.getID(), gAgent.getSessionID(), parent, tid, mMaterialName, res_desc, - LLAssetType::AT_MATERIAL, LLInventoryType::IT_MATERIAL, subtype, next_owner_perm, - new LLBoostFuncInventoryCallback([output=dump](LLUUID const & inv_item_id){ - // from reference in LLSettingsVOBase::createInventoryItem()/updateInventoryItem() - LLResourceUploadInfo::ptr_t uploadInfo = - std::make_shared( - inv_item_id, - LLAssetType::AT_SETTINGS, // TODO switch to AT_MATERIAL - output, - [](LLUUID item_id, LLUUID new_asset_id, LLUUID new_item_id, LLSD response) { - LL_INFOS("Material") << "inventory item uploaded. item: " << item_id << " asset: " << new_asset_id << " new_item_id: " << new_item_id << " response: " << response << LL_ENDL; - LLSD params = llsd::map("ASSET_ID", new_asset_id); - LLNotificationsUtil::add("MaterialCreated", params); +bool LLMaterialEditor::saveIfNeeded(LLInventoryItem* copyitem, bool sync) +{ + std::string buffer = getEncodedAsset(); + + const LLInventoryItem* item = getItem(); + // save it out to database + if (item) + { + const LLViewerRegion* region = gAgent.getRegion(); + if (!region) + { + LL_WARNS() << "Not connected to a region, cannot save material." << LL_ENDL; + return false; + } + std::string agent_url = region->getCapability("UpdateMaterialAgentInventory"); + std::string task_url = region->getCapability("UpdateMaterialTaskInventory"); + + if (!agent_url.empty() && !task_url.empty()) + { + std::string url; + LLResourceUploadInfo::ptr_t uploadInfo; + + if (mObjectUUID.isNull() && !agent_url.empty()) + { + uploadInfo = std::make_shared(mItemUUID, LLAssetType::AT_MATERIAL, buffer, + [](LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD) { + LLMaterialEditor::finishInventoryUpload(itemId, newAssetId, newItemId); }); + url = agent_url; + } + else if (!mObjectUUID.isNull() && !task_url.empty()) + { + LLUUID object_uuid(mObjectUUID); + uploadInfo = std::make_shared(mObjectUUID, mItemUUID, LLAssetType::AT_MATERIAL, buffer, + [object_uuid](LLUUID itemId, LLUUID, LLUUID newAssetId, LLSD) { + LLMaterialEditor::finishTaskUpload(itemId, newAssetId, object_uuid); + }); + url = task_url; + } - const LLViewerRegion* region = gAgent.getRegion(); - if (region) + if (!url.empty() && uploadInfo) { - std::string agent_url(region->getCapability("UpdateSettingsAgentInventory")); - if (agent_url.empty()) - { - LL_ERRS() << "missing required agent inventory cap url" << LL_ENDL; - } - LLViewerAssetUpload::EnqueueInventoryUpload(agent_url, uploadInfo); + mAssetStatus = PREVIEW_ASSET_LOADING; + setEnabled(false); + + LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo); } - }) - ); + + } + else // !gAssetStorage + { + LL_WARNS() << "Not connected to an materials capable region." << LL_ENDL; + return false; + } + + if (mCloseAfterSave) + { + closeFloater(); + } + } + else + { //make a new inventory item + // gen a new uuid for this asset + LLTransactionID tid; + tid.generate(); // timestamp-based randomization + uniquification + LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); + std::string res_desc = "Saved Material"; + U32 next_owner_perm = LLPermissions::DEFAULT.getMaskNextOwner(); + LLUUID parent = gInventory.findCategoryUUIDForType(LLFolderType::FT_MATERIAL); + const U8 subtype = NO_INV_SUBTYPE; // TODO maybe use AT_SETTINGS and LLSettingsType::ST_MATERIAL ? + + create_inventory_item(gAgent.getID(), gAgent.getSessionID(), parent, tid, mMaterialName, res_desc, + LLAssetType::AT_MATERIAL, LLInventoryType::IT_MATERIAL, subtype, next_owner_perm, + new LLBoostFuncInventoryCallback([output = buffer](LLUUID const& inv_item_id) { + // from reference in LLSettingsVOBase::createInventoryItem()/updateInventoryItem() + LLResourceUploadInfo::ptr_t uploadInfo = + std::make_shared( + inv_item_id, + LLAssetType::AT_MATERIAL, + output, + [](LLUUID item_id, LLUUID new_asset_id, LLUUID new_item_id, LLSD response) { + LL_INFOS("Material") << "inventory item uploaded. item: " << item_id << " asset: " << new_asset_id << " new_item_id: " << new_item_id << " response: " << response << LL_ENDL; + LLSD params = llsd::map("ASSET_ID", new_asset_id); + LLNotificationsUtil::add("MaterialCreated", params); + }); + + const LLViewerRegion* region = gAgent.getRegion(); + if (region) + { + std::string agent_url(region->getCapability("UpdateMaterialAgentInventory")); + if (agent_url.empty()) + { + LL_ERRS() << "missing required agent inventory cap url" << LL_ENDL; + } + LLViewerAssetUpload::EnqueueInventoryUpload(agent_url, uploadInfo); + } + }) + ); + } + + return true; +} + +void LLMaterialEditor::finishInventoryUpload(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId) +{ + // Update the UI with the new asset. + LLMaterialEditor* me = LLFloaterReg::findTypedInstance("material_editor", LLSD(itemId)); + if (me) + { + if (newItemId.isNull()) + { + me->setAssetId(newAssetId); + me->refreshFromInventory(); + } + else + { + me->refreshFromInventory(newItemId); + } + } } +void LLMaterialEditor::finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID taskId) +{ + + LLSD floater_key; + floater_key["taskid"] = taskId; + floater_key["itemid"] = itemId; + LLMaterialEditor* me = LLFloaterReg::findTypedInstance("material_editor", LLSD(itemId)); + if (me) + { + me->setAssetId(newAssetId); + me->refreshFromInventory(); + } +} + +void LLMaterialEditor::refreshFromInventory(const LLUUID& new_item_id) +{ + if (new_item_id.notNull()) + { + mItemUUID = new_item_id; + setKey(LLSD(new_item_id)); + } + LL_DEBUGS() << "LLPreviewNotecard::refreshFromInventory()" << LL_ENDL; + loadAsset(); +} + + void LLMaterialEditor::onClickSaveAs() { LLSD args; @@ -806,16 +1021,7 @@ void LLMaterialFilePicker::loadMaterial(const std::string& filename) mME->setEmissiveId(emissive_id); mME->setNormalId(normal_id); - mME->setAlphaMode(material_in.alphaMode); - mME->setAlphaCutoff(material_in.alphaCutoff); - - mME->setAlbedoColor(get_color(material_in.pbrMetallicRoughness.baseColorFactor)); - mME->setEmissiveColor(get_color(material_in.emissiveFactor)); - - mME->setMetalnessFactor(material_in.pbrMetallicRoughness.metallicFactor); - mME->setRoughnessFactor(material_in.pbrMetallicRoughness.roughnessFactor); - - mME->setDoubleSided(material_in.doubleSided); + mME->setFromGltfModel(model_in); std::string new_material = LLTrans::getString("New Material"); mME->setMaterialName(new_material); @@ -826,6 +1032,81 @@ void LLMaterialFilePicker::loadMaterial(const std::string& filename) mME->applyToSelection(); } +bool LLMaterialEditor::setFromGltfModel(tinygltf::Model& model, bool set_textures) +{ + if (model.materials.size() > 0) + { + tinygltf::Material& material_in = model.materials[0]; + + if (set_textures) + { + S32 index; + LLUUID id; + + // get albedo texture + index = material_in.pbrMetallicRoughness.baseColorTexture.index; + if (index >= 0) + { + id.set(model.images[index].uri); + setAlbedoId(id); + } + else + { + setAlbedoId(LLUUID::null); + } + + // get normal map + index = material_in.normalTexture.index; + if (index >= 0) + { + id.set(model.images[index].uri); + setNormalId(id); + } + else + { + setNormalId(LLUUID::null); + } + + // get metallic-roughness texture + index = material_in.pbrMetallicRoughness.metallicRoughnessTexture.index; + if (index >= 0) + { + id.set(model.images[index].uri); + setMetallicRoughnessId(id); + } + else + { + setMetallicRoughnessId(LLUUID::null); + } + + // get emissive texture + index = material_in.emissiveTexture.index; + if (index >= 0) + { + id.set(model.images[index].uri); + setEmissiveId(id); + } + else + { + setEmissiveId(LLUUID::null); + } + } + + setAlphaMode(material_in.alphaMode); + setAlphaCutoff(material_in.alphaCutoff); + + setAlbedoColor(get_color(material_in.pbrMetallicRoughness.baseColorFactor)); + setEmissiveColor(get_color(material_in.emissiveFactor)); + + setMetalnessFactor(material_in.pbrMetallicRoughness.metallicFactor); + setRoughnessFactor(material_in.pbrMetallicRoughness.roughnessFactor); + + setDoubleSided(material_in.doubleSided); + } + + return true; +} + void LLMaterialEditor::importMaterial() { (new LLMaterialFilePicker(this))->getFile(); @@ -841,22 +1122,7 @@ void LLMaterialEditor::applyToSelection() if (objectp && objectp->getVolume()) { LLGLTFMaterial* mat = new LLGLTFMaterial(); - mat->mAlbedoColor = getAlbedoColor(); - mat->mAlbedoColor.mV[3] = getTransparency(); - mat->mAlbedoId = getAlbedoId(); - - mat->mNormalId = getNormalId(); - - mat->mMetallicRoughnessId = getMetallicRoughnessId(); - mat->mMetallicFactor = getMetalnessFactor(); - mat->mRoughnessFactor = getRoughnessFactor(); - - mat->mEmissiveColor = getEmissiveColor(); - mat->mEmissiveId = getEmissiveId(); - - mat->mDoubleSided = getDoubleSided(); - mat->setAlphaMode(getAlphaMode()); - + getGLTFMaterial(mat); LLVOVolume* vobjp = (LLVOVolume*)objectp; for (int i = 0; i < vobjp->getNumTEs(); ++i) { @@ -867,3 +1133,223 @@ void LLMaterialEditor::applyToSelection() vobjp->markForUpdate(TRUE); } } + +void LLMaterialEditor::getGLTFMaterial(LLGLTFMaterial* mat) +{ + mat->mAlbedoColor = getAlbedoColor(); + mat->mAlbedoColor.mV[3] = getTransparency(); + mat->mAlbedoId = getAlbedoId(); + + mat->mNormalId = getNormalId(); + + mat->mMetallicRoughnessId = getMetallicRoughnessId(); + mat->mMetallicFactor = getMetalnessFactor(); + mat->mRoughnessFactor = getRoughnessFactor(); + + mat->mEmissiveColor = getEmissiveColor(); + mat->mEmissiveId = getEmissiveId(); + + mat->mDoubleSided = getDoubleSided(); + mat->setAlphaMode(getAlphaMode()); +} + +void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat) +{ + setAlbedoColor(mat->mAlbedoColor); + setAlbedoId(mat->mAlbedoId); + setNormalId(mat->mNormalId); + + setMetallicRoughnessId(mat->mMetallicRoughnessId); + setMetalnessFactor(mat->mMetallicFactor); + setRoughnessFactor(mat->mRoughnessFactor); + + setEmissiveColor(mat->mEmissiveColor); + setEmissiveId(mat->mEmissiveId); + + setDoubleSided(mat->mDoubleSided); + setAlphaMode(mat->getAlphaMode()); +} + +void LLMaterialEditor::loadAsset() +{ + // derived from LLPreviewNotecard::loadAsset + + // TODO: see commented out "editor" references and make them do something appropriate to the UI + + // request the asset. + const LLInventoryItem* item = getItem(); + + bool fail = false; + + if (item) + { + LLPermissions perm(item->getPermissions()); + BOOL is_owner = gAgent.allowOperation(PERM_OWNER, perm, GP_OBJECT_MANIPULATE); + BOOL allow_copy = gAgent.allowOperation(PERM_COPY, perm, GP_OBJECT_MANIPULATE); + BOOL allow_modify = canModify(mObjectUUID, item); + BOOL source_library = mObjectUUID.isNull() && gInventory.isObjectDescendentOf(mItemUUID, gInventory.getLibraryRootFolderID()); + + if (allow_copy || gAgent.isGodlike()) + { + mAssetID = item->getAssetUUID(); + if (mAssetID.isNull()) + { + mAssetStatus = PREVIEW_ASSET_LOADED; + } + else + { + LLHost source_sim = LLHost(); + LLSD* user_data = new LLSD(); + + if (mObjectUUID.notNull()) + { + LLViewerObject* objectp = gObjectList.findObject(mObjectUUID); + if (objectp && objectp->getRegion()) + { + source_sim = objectp->getRegion()->getHost(); + } + else + { + // The object that we're trying to look at disappeared, bail. + LL_WARNS() << "Can't find object " << mObjectUUID << " associated with notecard." << LL_ENDL; + mAssetID.setNull(); + /*editor->setText(getString("no_object")); + editor->makePristine(); + editor->setEnabled(FALSE);*/ + mAssetStatus = PREVIEW_ASSET_LOADED; + return; + } + user_data->with("taskid", mObjectUUID).with("itemid", mItemUUID); + } + else + { + user_data = new LLSD(mItemUUID); + } + + gAssetStorage->getInvItemAsset(source_sim, + gAgent.getID(), + gAgent.getSessionID(), + item->getPermissions().getOwner(), + mObjectUUID, + item->getUUID(), + item->getAssetUUID(), + item->getType(), + &onLoadComplete, + (void*)user_data, + TRUE); + mAssetStatus = PREVIEW_ASSET_LOADING; + } + } + else + { + mAssetID.setNull(); + /*editor->setText(getString("not_allowed")); + editor->makePristine(); + editor->setEnabled(FALSE);*/ + mAssetStatus = PREVIEW_ASSET_LOADED; + } + + if (!allow_modify) + { + //editor->setEnabled(FALSE); + //getChildView("lock")->setVisible(TRUE); + //getChildView("Edit")->setEnabled(FALSE); + } + + if ((allow_modify || is_owner) && !source_library) + { + //getChildView("Delete")->setEnabled(TRUE); + } + } + else if (mObjectUUID.notNull() && mItemUUID.notNull()) + { + LLViewerObject* objectp = gObjectList.findObject(mObjectUUID); + if (objectp && (objectp->isInventoryPending() || objectp->isInventoryDirty())) + { + // It's a material in object's inventory and we failed to get it because inventory is not up to date. + // Subscribe for callback and retry at inventoryChanged() + registerVOInventoryListener(objectp, NULL); //removes previous listener + + if (objectp->isInventoryDirty()) + { + objectp->requestInventory(); + } + } + else + { + fail = true; + } + } + else + { + fail = true; + } + + if (fail) + { + /*editor->setText(LLStringUtil::null); + editor->makePristine(); + editor->setEnabled(TRUE);*/ + // Don't set asset status here; we may not have set the item id yet + // (e.g. when this gets called initially) + //mAssetStatus = PREVIEW_ASSET_LOADED; + } +} + +// static +void LLMaterialEditor::onLoadComplete(const LLUUID& asset_uuid, + LLAssetType::EType type, + void* user_data, S32 status, LLExtStat ext_status) +{ + LL_INFOS() << "LLMaterialEditor::onLoadComplete()" << LL_ENDL; + LLSD* floater_key = (LLSD*)user_data; + LLMaterialEditor* editor = LLFloaterReg::findTypedInstance("material_editor", *floater_key); + if (editor) + { + if (0 == status) + { + LLFileSystem file(asset_uuid, type, LLFileSystem::READ); + + S32 file_length = file.getSize(); + + std::vector buffer(file_length + 1); + file.read((U8*)&buffer[0], file_length); + + editor->decodeAsset(buffer); + + BOOL modifiable = editor->canModify(editor->mObjectID, editor->getItem()); + editor->setEnabled(modifiable); + editor->mAssetStatus = PREVIEW_ASSET_LOADED; + } + else + { + if (LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status || + LL_ERR_FILE_EMPTY == status) + { + LLNotificationsUtil::add("MaterialMissing"); + } + else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status) + { + LLNotificationsUtil::add("MaterialNoPermissions"); + } + else + { + LLNotificationsUtil::add("UnableToLoadMaterial"); + } + + LL_WARNS() << "Problem loading material: " << status << LL_ENDL; + editor->mAssetStatus = PREVIEW_ASSET_ERROR; + } + } + delete floater_key; +} + +void LLMaterialEditor::inventoryChanged(LLViewerObject* object, + LLInventoryObject::object_list_t* inventory, + S32 serial_num, + void* user_data) +{ + removeVOInventoryListener(); + loadAsset(); +} + -- cgit v1.2.3 From 84bbe45fb582722619f77ae5ecaeef52a94abf27 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 29 Jun 2022 11:56:40 -0500 Subject: SL-17602 WIP - Texture uploads form material editor now work but the names are garbage and the resulting material asset has the wrong UUIDs --- indra/newview/llmaterialeditor.cpp | 90 +++++++++++++++++++++++++++++++++----- 1 file changed, 78 insertions(+), 12 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index ada5bb3882..2455ad2926 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -48,6 +48,9 @@ #include "llfloaterreg.h" #include "llfilesystem.h" #include "llsdserialize.h" +#include "llimagej2c.h" +#include "llviewertexturelist.h" +#include "llfloaterperms.h" #include @@ -316,6 +319,7 @@ void LLMaterialEditor::onCommitAlbedoTexture(LLUICtrl * ctrl, const LLSD & data) } else { + mAlbedoJ2C = nullptr; childSetValue("albedo_upload_fee", getString("no_upload_fee_string")); } setHasUnsavedChanges(true); @@ -331,6 +335,7 @@ void LLMaterialEditor::onCommitMetallicTexture(LLUICtrl * ctrl, const LLSD & dat } else { + mMetallicRoughnessJ2C = nullptr; childSetValue("metallic_upload_fee", getString("no_upload_fee_string")); } setHasUnsavedChanges(true); @@ -346,6 +351,7 @@ void LLMaterialEditor::onCommitEmissiveTexture(LLUICtrl * ctrl, const LLSD & dat } else { + mEmissiveJ2C = nullptr; childSetValue("emissive_upload_fee", getString("no_upload_fee_string")); } setHasUnsavedChanges(true); @@ -361,6 +367,7 @@ void LLMaterialEditor::onCommitNormalTexture(LLUICtrl * ctrl, const LLSD & data) } else { + mNormalJ2C = nullptr; childSetValue("normal_upload_fee", getString("no_upload_fee_string")); } setHasUnsavedChanges(true); @@ -395,7 +402,6 @@ static U32 write_texture(const LLUUID& id, tinygltf::Model& model) void LLMaterialEditor::onClickSave() { applyToSelection(); - saveIfNeeded(); } @@ -557,6 +563,8 @@ bool LLMaterialEditor::saveIfNeeded(LLInventoryItem* copyitem, bool sync) { std::string buffer = getEncodedAsset(); + saveTextures(); + const LLInventoryItem* item = getItem(); // save it out to database if (item) @@ -615,6 +623,7 @@ bool LLMaterialEditor::saveIfNeeded(LLInventoryItem* copyitem, bool sync) } else { //make a new inventory item +#if 1 // gen a new uuid for this asset LLTransactionID tid; tid.generate(); // timestamp-based randomization + uniquification @@ -651,6 +660,7 @@ bool LLMaterialEditor::saveIfNeeded(LLInventoryItem* copyitem, bool sync) } }) ); +#endif } return true; @@ -793,10 +803,9 @@ const tinygltf::Image* get_image_from_texture_index(const tinygltf::Model& model return nullptr; } -static LLImageRaw* get_texture(const std::string& folder, const tinygltf::Model& model, S32 texture_index) +static LLImageRaw* get_texture(const std::string& folder, const tinygltf::Model& model, S32 texture_index, std::string& name) { const tinygltf::Image* image = get_image_from_texture_index(model, texture_index); - LLImageRaw* rawImage = nullptr; if (image != nullptr && @@ -804,6 +813,7 @@ static LLImageRaw* get_texture(const std::string& folder, const tinygltf::Model& !image->image.empty() && image->component <= 4) { + name = image->name; rawImage = new LLImageRaw(&image->image[0], image->width, image->height, image->component); rawImage->verticalFlip(); } @@ -850,18 +860,23 @@ static void pack_textures(tinygltf::Model& model, tinygltf::Material& material, LLPointer& albedo_tex, LLPointer& normal_tex, LLPointer& mr_tex, - LLPointer& emissive_tex) + LLPointer& emissive_tex, + LLPointer& albedo_j2c, + LLPointer& normal_j2c, + LLPointer& mr_j2c, + LLPointer& emissive_j2c) { - // TODO: downscale if needed if (albedo_img) { albedo_tex = LLViewerTextureManager::getFetchedTexture(albedo_img, FTType::FTT_LOCAL_FILE, true); + albedo_j2c = LLViewerTextureList::convertToUploadFile(albedo_img); } if (normal_img) { strip_alpha_channel(normal_img); normal_tex = LLViewerTextureManager::getFetchedTexture(normal_img, FTType::FTT_LOCAL_FILE, true); + normal_j2c = LLViewerTextureList::convertToUploadFile(normal_img); } if (mr_img) @@ -895,12 +910,14 @@ static void pack_textures(tinygltf::Model& model, tinygltf::Material& material, if (mr_img) { mr_tex = LLViewerTextureManager::getFetchedTexture(mr_img, FTType::FTT_LOCAL_FILE, true); + mr_j2c = LLViewerTextureList::convertToUploadFile(mr_img); } if (emissive_img) { strip_alpha_channel(emissive_img); emissive_tex = LLViewerTextureManager::getFetchedTexture(emissive_img, FTType::FTT_LOCAL_FILE, true); + emissive_j2c = LLViewerTextureList::convertToUploadFile(emissive_img); } } @@ -966,18 +983,19 @@ void LLMaterialFilePicker::loadMaterial(const std::string& filename) model_out.materials.resize(1); // get albedo texture - LLPointer albedo_img = get_texture(folder, model_in, material_in.pbrMetallicRoughness.baseColorTexture.index); + LLPointer albedo_img = get_texture(folder, model_in, material_in.pbrMetallicRoughness.baseColorTexture.index, mME->mAlbedoName); // get normal map - LLPointer normal_img = get_texture(folder, model_in, material_in.normalTexture.index); + LLPointer normal_img = get_texture(folder, model_in, material_in.normalTexture.index, mME->mNormalName); // get metallic-roughness texture - LLPointer mr_img = get_texture(folder, model_in, material_in.pbrMetallicRoughness.metallicRoughnessTexture.index); + LLPointer mr_img = get_texture(folder, model_in, material_in.pbrMetallicRoughness.metallicRoughnessTexture.index, mME->mMetallicRoughnessName); // get emissive texture - LLPointer emissive_img = get_texture(folder, model_in, material_in.emissiveTexture.index); + LLPointer emissive_img = get_texture(folder, model_in, material_in.emissiveTexture.index, mME->mEmissiveName); // get occlusion map if needed LLPointer occlusion_img; if (material_in.occlusionTexture.index != material_in.pbrMetallicRoughness.metallicRoughnessTexture.index) { - occlusion_img = get_texture(folder, model_in, material_in.occlusionTexture.index); + std::string tmp; + occlusion_img = get_texture(folder, model_in, material_in.occlusionTexture.index, tmp); } LLPointer albedo_tex; @@ -986,12 +1004,12 @@ void LLMaterialFilePicker::loadMaterial(const std::string& filename) LLPointer emissive_tex; pack_textures(model_in, material_in, albedo_img, normal_img, mr_img, emissive_img, occlusion_img, - albedo_tex, normal_tex, mr_tex, emissive_tex); + albedo_tex, normal_tex, mr_tex, emissive_tex, mME->mAlbedoJ2C, mME->mNormalJ2C, mME->mMetallicRoughnessJ2C, mME->mEmissiveJ2C); LLUUID albedo_id; if (albedo_tex != nullptr) { - albedo_tex->forceToSaveRawImage(0, F32_MAX); + albedo_tex->forceToSaveRawImage(0, F32_MAX); albedo_id = albedo_tex->getID(); } @@ -1353,3 +1371,51 @@ void LLMaterialEditor::inventoryChanged(LLViewerObject* object, loadAsset(); } + +void LLMaterialEditor::saveTexture(LLImageJ2C* img, const std::string& name, const LLUUID& asset_id) +{ + if (img == nullptr || img->getDataSize() == 0) + { + return; + } + + // copy image bytes into string + std::string buffer; + buffer.assign((const char*) img->getData(), img->getDataSize()); + + U32 expected_upload_cost = 10; // TODO: where do we get L$10 for textures from? + + LLAssetStorage::LLStoreAssetCallback callback; + + LLResourceUploadInfo::ptr_t uploadInfo(std::make_shared( + buffer, + asset_id, + name, + name, + 0, + LLFolderType::FT_TEXTURE, + LLInventoryType::IT_TEXTURE, + LLAssetType::AT_TEXTURE, + LLFloaterPerms::getNextOwnerPerms("Uploads"), + LLFloaterPerms::getGroupPerms("Uploads"), + LLFloaterPerms::getEveryonePerms("Uploads"), + expected_upload_cost, + false)); + + upload_new_resource(uploadInfo, callback, nullptr); +} + +void LLMaterialEditor::saveTextures() +{ + saveTexture(mAlbedoJ2C, mAlbedoName, mAlbedoTextureUploadId); + saveTexture(mNormalJ2C, mNormalName, mNormalTextureUploadId); + saveTexture(mEmissiveJ2C, mEmissiveName, mEmissiveTextureUploadId); + saveTexture(mMetallicRoughnessJ2C, mMetallicRoughnessName, mMetallicTextureUploadId); + + // discard upload buffers once textures have been saved + mAlbedoJ2C = nullptr; + mNormalJ2C = nullptr; + mEmissiveJ2C = nullptr; + mMetallicRoughnessJ2C = nullptr; +} + -- cgit v1.2.3 From 6f6df8ed71702f0ee8d21a2b583818ae360dd093 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 29 Jun 2022 21:42:44 -0500 Subject: SL-17685 Drag and drop material support --- indra/newview/llmaterialeditor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 2455ad2926..9fb9f723cd 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -43,7 +43,6 @@ #include "llviewerregion.h" #include "llvovolume.h" #include "roles_constants.h" -#include "tinygltf/tiny_gltf.h" #include "llviewerobjectlist.h" #include "llfloaterreg.h" #include "llfilesystem.h" @@ -52,6 +51,7 @@ #include "llviewertexturelist.h" #include "llfloaterperms.h" +#include "tinygltf/tiny_gltf.h" #include ///---------------------------------------------------------------------------- -- cgit v1.2.3 From 68dfa1f5501f58d1ca158aeabcc3fd07e8a2e70f Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 30 Jun 2022 21:03:21 +0300 Subject: SL-17640 Use LLAgentBenefitsMgr for upload cost --- indra/newview/llmaterialeditor.cpp | 54 +++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 9fb9f723cd..67d963bb63 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -29,6 +29,7 @@ #include "llmaterialeditor.h" #include "llagent.h" +#include "llagentbenefits.h" #include "llappviewer.h" #include "llcombobox.h" #include "llinventorymodel.h" @@ -86,6 +87,12 @@ BOOL LLMaterialEditor::postBuild() childSetAction("save_as", boost::bind(&LLMaterialEditor::onClickSaveAs, this)); childSetAction("cancel", boost::bind(&LLMaterialEditor::onClickCancel, this)); + S32 upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(); + getChild("albedo_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); + getChild("metallic_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); + getChild("emissive_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); + getChild("normal_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); + boost::function changes_callback = [this](LLUICtrl * ctrl, void*) { setHasUnsavedChanges(true); @@ -142,7 +149,12 @@ void LLMaterialEditor::setAlbedoId(const LLUUID& id) { mAlbedoTextureCtrl->setValue(id); mAlbedoTextureCtrl->setDefaultImageAssetID(id); +} +void LLMaterialEditor::setAlbedoUploadId(const LLUUID& id) +{ + // Might be better to use local textures and + // assign a fee in case of a local texture if (id.notNull()) { // todo: this does not account for posibility of texture @@ -151,6 +163,7 @@ void LLMaterialEditor::setAlbedoId(const LLUUID& id) // Only set if we will need to upload this texture mAlbedoTextureUploadId = id; } + setHasUnsavedChanges(true); } LLColor4 LLMaterialEditor::getAlbedoColor() @@ -211,7 +224,10 @@ void LLMaterialEditor::setMetallicRoughnessId(const LLUUID& id) { mMetallicTextureCtrl->setValue(id); mMetallicTextureCtrl->setDefaultImageAssetID(id); +} +void LLMaterialEditor::setMetallicRoughnessUploadId(const LLUUID& id) +{ if (id.notNull()) { // todo: this does not account for posibility of texture @@ -219,6 +235,7 @@ void LLMaterialEditor::setMetallicRoughnessId(const LLUUID& id) childSetValue("metallic_upload_fee", getString("upload_fee_string")); mMetallicTextureUploadId = id; } + setHasUnsavedChanges(true); } F32 LLMaterialEditor::getMetalnessFactor() @@ -250,7 +267,10 @@ void LLMaterialEditor::setEmissiveId(const LLUUID& id) { mEmissiveTextureCtrl->setValue(id); mEmissiveTextureCtrl->setDefaultImageAssetID(id); +} +void LLMaterialEditor::setEmissiveUploadId(const LLUUID& id) +{ if (id.notNull()) { // todo: this does not account for posibility of texture @@ -258,6 +278,7 @@ void LLMaterialEditor::setEmissiveId(const LLUUID& id) childSetValue("emissive_upload_fee", getString("upload_fee_string")); mEmissiveTextureUploadId = id; } + setHasUnsavedChanges(true); } LLColor4 LLMaterialEditor::getEmissiveColor() @@ -279,7 +300,10 @@ void LLMaterialEditor::setNormalId(const LLUUID& id) { mNormalTextureCtrl->setValue(id); mNormalTextureCtrl->setDefaultImageAssetID(id); +} +void LLMaterialEditor::setNormalUploadId(const LLUUID& id) +{ if (id.notNull()) { // todo: this does not account for posibility of texture @@ -287,6 +311,7 @@ void LLMaterialEditor::setNormalId(const LLUUID& id) childSetValue("normal_upload_fee", getString("upload_fee_string")); mNormalTextureUploadId = id; } + setHasUnsavedChanges(true); } bool LLMaterialEditor::getDoubleSided() @@ -306,6 +331,27 @@ void LLMaterialEditor::setHasUnsavedChanges(bool value) mHasUnsavedChanges = value; childSetVisible("unsaved_changes", value); } + + S32 upload_texture_count = 0; + if (mAlbedoTextureUploadId.notNull() && mAlbedoTextureUploadId == getAlbedoId()) + { + upload_texture_count++; + } + if (mMetallicTextureUploadId.notNull() && mMetallicTextureUploadId == getMetallicRoughnessId()) + { + upload_texture_count++; + } + if (mEmissiveTextureUploadId.notNull() && mEmissiveTextureUploadId == getEmissiveId()) + { + upload_texture_count++; + } + if (mNormalTextureUploadId.notNull() && mNormalTextureUploadId == getNormalId()) + { + upload_texture_count++; + } + + S32 upload_cost = upload_texture_count * LLAgentBenefitsMgr::current().getTextureUploadCost(); + getChild("total_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); } void LLMaterialEditor::onCommitAlbedoTexture(LLUICtrl * ctrl, const LLSD & data) @@ -866,6 +912,8 @@ static void pack_textures(tinygltf::Model& model, tinygltf::Material& material, LLPointer& mr_j2c, LLPointer& emissive_j2c) { + // todo: consider using LLLocalBitmapMgr or storing textures' pointers somewhere in floater + // otherwise images won't exist for long if texture ctrl temporaly switches to something else if (albedo_img) { albedo_tex = LLViewerTextureManager::getFetchedTexture(albedo_img, FTType::FTT_LOCAL_FILE, true); @@ -1035,9 +1083,13 @@ void LLMaterialFilePicker::loadMaterial(const std::string& filename) } mME->setAlbedoId(albedo_id); + mME->setAlbedoUploadId(albedo_id); mME->setMetallicRoughnessId(mr_id); + mME->setMetallicRoughnessUploadId(mr_id); mME->setEmissiveId(emissive_id); + mME->setEmissiveUploadId(emissive_id); mME->setNormalId(normal_id); + mME->setNormalUploadId(normal_id); mME->setFromGltfModel(model_in); @@ -1383,7 +1435,7 @@ void LLMaterialEditor::saveTexture(LLImageJ2C* img, const std::string& name, con std::string buffer; buffer.assign((const char*) img->getData(), img->getDataSize()); - U32 expected_upload_cost = 10; // TODO: where do we get L$10 for textures from? + U32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(); LLAssetStorage::LLStoreAssetCallback callback; -- cgit v1.2.3 From dd2bb260217a68d9686e26d0f3514a68008f5ab1 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 30 Jun 2022 23:33:08 +0300 Subject: SL-17640 Handle unsaved changes better --- indra/newview/llmaterialeditor.cpp | 84 +++++++++++++++++++++++++------------- 1 file changed, 55 insertions(+), 29 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 67d963bb63..52979259df 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -365,7 +365,11 @@ void LLMaterialEditor::onCommitAlbedoTexture(LLUICtrl * ctrl, const LLSD & data) } else { - mAlbedoJ2C = nullptr; + // Texture picker has 'apply now' with 'cancel' support. + // Keep mAlbedoJ2C and mAlbedoFetched, it's our storage in + // case user decides to cancel changes. + // Without mAlbedoFetched, viewer will eventually cleanup + // the texture that is not in use childSetValue("albedo_upload_fee", getString("no_upload_fee_string")); } setHasUnsavedChanges(true); @@ -381,7 +385,6 @@ void LLMaterialEditor::onCommitMetallicTexture(LLUICtrl * ctrl, const LLSD & dat } else { - mMetallicRoughnessJ2C = nullptr; childSetValue("metallic_upload_fee", getString("no_upload_fee_string")); } setHasUnsavedChanges(true); @@ -397,7 +400,6 @@ void LLMaterialEditor::onCommitEmissiveTexture(LLUICtrl * ctrl, const LLSD & dat } else { - mEmissiveJ2C = nullptr; childSetValue("emissive_upload_fee", getString("no_upload_fee_string")); } setHasUnsavedChanges(true); @@ -413,7 +415,6 @@ void LLMaterialEditor::onCommitNormalTexture(LLUICtrl * ctrl, const LLSD & data) } else { - mNormalJ2C = nullptr; childSetValue("normal_upload_fee", getString("no_upload_fee_string")); } setHasUnsavedChanges(true); @@ -666,6 +667,10 @@ bool LLMaterialEditor::saveIfNeeded(LLInventoryItem* copyitem, bool sync) { closeFloater(); } + else + { + setHasUnsavedChanges(false); + } } else { //make a new inventory item @@ -706,6 +711,9 @@ bool LLMaterialEditor::saveIfNeeded(LLInventoryItem* copyitem, bool sync) } }) ); + + // We do not update floater with uploaded asset yet, so just close it. + closeFloater(); #endif } @@ -912,8 +920,6 @@ static void pack_textures(tinygltf::Model& model, tinygltf::Material& material, LLPointer& mr_j2c, LLPointer& emissive_j2c) { - // todo: consider using LLLocalBitmapMgr or storing textures' pointers somewhere in floater - // otherwise images won't exist for long if texture ctrl temporaly switches to something else if (albedo_img) { albedo_tex = LLViewerTextureManager::getFetchedTexture(albedo_img, FTType::FTT_LOCAL_FILE, true); @@ -1046,40 +1052,36 @@ void LLMaterialFilePicker::loadMaterial(const std::string& filename) occlusion_img = get_texture(folder, model_in, material_in.occlusionTexture.index, tmp); } - LLPointer albedo_tex; - LLPointer normal_tex; - LLPointer mr_tex; - LLPointer emissive_tex; - pack_textures(model_in, material_in, albedo_img, normal_img, mr_img, emissive_img, occlusion_img, - albedo_tex, normal_tex, mr_tex, emissive_tex, mME->mAlbedoJ2C, mME->mNormalJ2C, mME->mMetallicRoughnessJ2C, mME->mEmissiveJ2C); + mME->mAlbedoFetched, mME->mNormalFetched, mME->mMetallicRoughnessFetched, mME->mEmissiveFetched, + mME->mAlbedoJ2C, mME->mNormalJ2C, mME->mMetallicRoughnessJ2C, mME->mEmissiveJ2C); LLUUID albedo_id; - if (albedo_tex != nullptr) + if (mME->mAlbedoFetched.notNull()) { - albedo_tex->forceToSaveRawImage(0, F32_MAX); - albedo_id = albedo_tex->getID(); + mME->mAlbedoFetched->forceToSaveRawImage(0, F32_MAX); + albedo_id = mME->mAlbedoFetched->getID(); } LLUUID normal_id; - if (normal_tex != nullptr) + if (mME->mNormalFetched.notNull()) { - normal_tex->forceToSaveRawImage(0, F32_MAX); - normal_id = normal_tex->getID(); + mME->mNormalFetched->forceToSaveRawImage(0, F32_MAX); + normal_id = mME->mNormalFetched->getID(); } LLUUID mr_id; - if (mr_tex != nullptr) + if (mME->mMetallicRoughnessFetched.notNull()) { - mr_tex->forceToSaveRawImage(0, F32_MAX); - mr_id = mr_tex->getID(); + mME->mMetallicRoughnessFetched->forceToSaveRawImage(0, F32_MAX); + mr_id = mME->mMetallicRoughnessFetched->getID(); } LLUUID emissive_id; - if (emissive_tex != nullptr) + if (mME->mEmissiveFetched.notNull()) { - emissive_tex->forceToSaveRawImage(0, F32_MAX); - emissive_id = emissive_tex->getID(); + mME->mEmissiveFetched->forceToSaveRawImage(0, F32_MAX); + emissive_id = mME->mEmissiveFetched->getID(); } mME->setAlbedoId(albedo_id); @@ -1426,7 +1428,9 @@ void LLMaterialEditor::inventoryChanged(LLViewerObject* object, void LLMaterialEditor::saveTexture(LLImageJ2C* img, const std::string& name, const LLUUID& asset_id) { - if (img == nullptr || img->getDataSize() == 0) + if (asset_id.isNull() + || img == nullptr + || img->getDataSize() == 0) { return; } @@ -1459,15 +1463,37 @@ void LLMaterialEditor::saveTexture(LLImageJ2C* img, const std::string& name, con void LLMaterialEditor::saveTextures() { - saveTexture(mAlbedoJ2C, mAlbedoName, mAlbedoTextureUploadId); - saveTexture(mNormalJ2C, mNormalName, mNormalTextureUploadId); - saveTexture(mEmissiveJ2C, mEmissiveName, mEmissiveTextureUploadId); - saveTexture(mMetallicRoughnessJ2C, mMetallicRoughnessName, mMetallicTextureUploadId); + if (mAlbedoTextureUploadId == getAlbedoId()) + { + saveTexture(mAlbedoJ2C, mAlbedoName, mAlbedoTextureUploadId); + } + if (mNormalTextureUploadId == getNormalId()) + { + saveTexture(mNormalJ2C, mNormalName, mNormalTextureUploadId); + } + if (mMetallicTextureUploadId == getMetallicRoughnessId()) + { + saveTexture(mMetallicRoughnessJ2C, mMetallicRoughnessName, mMetallicTextureUploadId); + } + if (mEmissiveTextureUploadId == getEmissiveId()) + { + saveTexture(mEmissiveJ2C, mEmissiveName, mEmissiveTextureUploadId); + } // discard upload buffers once textures have been saved mAlbedoJ2C = nullptr; mNormalJ2C = nullptr; mEmissiveJ2C = nullptr; mMetallicRoughnessJ2C = nullptr; + + mAlbedoFetched = nullptr; + mNormalFetched = nullptr; + mMetallicRoughnessFetched = nullptr; + mEmissiveFetched = nullptr; + + mAlbedoTextureUploadId.setNull(); + mNormalTextureUploadId.setNull(); + mMetallicTextureUploadId.setNull(); + mEmissiveTextureUploadId.setNull(); } -- cgit v1.2.3 From cfddc1b539a69155bfae1f7fa672ca202a772505 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 6 Jul 2022 01:03:00 +0300 Subject: SL-17640 'Save As' should create a new item Also fixed floater not using inventory item's name, some of the permissions --- indra/newview/llmaterialeditor.cpp | 240 +++++++++++++++++++++++++------------ 1 file changed, 161 insertions(+), 79 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 52979259df..4f8558277d 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -55,8 +55,24 @@ #include "tinygltf/tiny_gltf.h" #include + +class LLMaterialEditorCopiedCallback : public LLInventoryCallback +{ +public: + LLMaterialEditorCopiedCallback(const std::string &buffer, const LLUUID &old_item_id) : mBuffer(buffer), mOldItemId(old_item_id) {} + + virtual void fire(const LLUUID& inv_item_id) + { + LLMaterialEditor::finishSaveAs(mOldItemId, inv_item_id, mBuffer); + } + +private: + std::string mBuffer; + LLUUID mOldItemId; +}; + ///---------------------------------------------------------------------------- -/// Class LLPreviewNotecard +/// Class LLMaterialEditor ///---------------------------------------------------------------------------- // Default constructor @@ -354,6 +370,16 @@ void LLMaterialEditor::setHasUnsavedChanges(bool value) getChild("total_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); } +void LLMaterialEditor::setCanSaveAs(BOOL value) +{ + childSetEnabled("save_as", value); +} + +void LLMaterialEditor::setCanSave(BOOL value) +{ + childSetEnabled("save", value); +} + void LLMaterialEditor::onCommitAlbedoTexture(LLUICtrl * ctrl, const LLSD & data) { // might be better to use arrays, to have a single callback @@ -606,7 +632,7 @@ bool LLMaterialEditor::decodeAsset(const std::vector& buffer) return false; } -bool LLMaterialEditor::saveIfNeeded(LLInventoryItem* copyitem, bool sync) +bool LLMaterialEditor::saveIfNeeded() { std::string buffer = getEncodedAsset(); @@ -616,50 +642,8 @@ bool LLMaterialEditor::saveIfNeeded(LLInventoryItem* copyitem, bool sync) // save it out to database if (item) { - const LLViewerRegion* region = gAgent.getRegion(); - if (!region) + if (!saveToInventoryItem(buffer, mItemUUID, mObjectUUID)) { - LL_WARNS() << "Not connected to a region, cannot save material." << LL_ENDL; - return false; - } - std::string agent_url = region->getCapability("UpdateMaterialAgentInventory"); - std::string task_url = region->getCapability("UpdateMaterialTaskInventory"); - - if (!agent_url.empty() && !task_url.empty()) - { - std::string url; - LLResourceUploadInfo::ptr_t uploadInfo; - - if (mObjectUUID.isNull() && !agent_url.empty()) - { - uploadInfo = std::make_shared(mItemUUID, LLAssetType::AT_MATERIAL, buffer, - [](LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD) { - LLMaterialEditor::finishInventoryUpload(itemId, newAssetId, newItemId); - }); - url = agent_url; - } - else if (!mObjectUUID.isNull() && !task_url.empty()) - { - LLUUID object_uuid(mObjectUUID); - uploadInfo = std::make_shared(mObjectUUID, mItemUUID, LLAssetType::AT_MATERIAL, buffer, - [object_uuid](LLUUID itemId, LLUUID, LLUUID newAssetId, LLSD) { - LLMaterialEditor::finishTaskUpload(itemId, newAssetId, object_uuid); - }); - url = task_url; - } - - if (!url.empty() && uploadInfo) - { - mAssetStatus = PREVIEW_ASSET_LOADING; - setEnabled(false); - - LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo); - } - - } - else // !gAssetStorage - { - LL_WARNS() << "Not connected to an materials capable region." << LL_ENDL; return false; } @@ -669,7 +653,8 @@ bool LLMaterialEditor::saveIfNeeded(LLInventoryItem* copyitem, bool sync) } else { - setHasUnsavedChanges(false); + mAssetStatus = PREVIEW_ASSET_LOADING; + setEnabled(false); } } else @@ -699,6 +684,8 @@ bool LLMaterialEditor::saveIfNeeded(LLInventoryItem* copyitem, bool sync) LLNotificationsUtil::add("MaterialCreated", params); }); + // todo: apply permissions from textures here if server doesn't + // if any texture is 'no transfer', material should be 'no transfer' as well const LLViewerRegion* region = gAgent.getRegion(); if (region) { @@ -720,6 +707,63 @@ bool LLMaterialEditor::saveIfNeeded(LLInventoryItem* copyitem, bool sync) return true; } +// static +bool LLMaterialEditor::saveToInventoryItem(const std::string &buffer, const LLUUID &item_id, const LLUUID &task_id) +{ + const LLViewerRegion* region = gAgent.getRegion(); + if (!region) + { + LL_WARNS() << "Not connected to a region, cannot save material." << LL_ENDL; + return false; + } + std::string agent_url = region->getCapability("UpdateMaterialAgentInventory"); + std::string task_url = region->getCapability("UpdateMaterialTaskInventory"); + + if (!agent_url.empty() && !task_url.empty()) + { + std::string url; + LLResourceUploadInfo::ptr_t uploadInfo; + + if (task_id.isNull() && !agent_url.empty()) + { + uploadInfo = std::make_shared(item_id, LLAssetType::AT_MATERIAL, buffer, + [](LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD) { + LLMaterialEditor::finishInventoryUpload(itemId, newAssetId, newItemId); + }); + url = agent_url; + } + else if (!task_id.isNull() && !task_url.empty()) + { + LLUUID object_uuid(task_id); + uploadInfo = std::make_shared(task_id, item_id, LLAssetType::AT_MATERIAL, buffer, + [object_uuid](LLUUID itemId, LLUUID, LLUUID newAssetId, LLSD) { + LLMaterialEditor::finishTaskUpload(itemId, newAssetId, object_uuid); + }); + url = task_url; + } + + if (!url.empty() && uploadInfo) + { + LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo); + } + else + { + return false; + } + + } + else // !gAssetStorage + { + LL_WARNS() << "Not connected to an materials capable region." << LL_ENDL; + return false; + } + + // todo: apply permissions from textures here if server doesn't + // if any texture is 'no transfer', material should be 'no transfer' as well + + return true; +} + void LLMaterialEditor::finishInventoryUpload(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId) { // Update the UI with the new asset. @@ -731,19 +775,20 @@ void LLMaterialEditor::finishInventoryUpload(LLUUID itemId, LLUUID newAssetId, L me->setAssetId(newAssetId); me->refreshFromInventory(); } - else + else if (newItemId.notNull()) { + // Not supposed to happen? me->refreshFromInventory(newItemId); } + else + { + me->refreshFromInventory(itemId); + } } } void LLMaterialEditor::finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID taskId) { - - LLSD floater_key; - floater_key["taskid"] = taskId; - floater_key["itemid"] = itemId; LLMaterialEditor* me = LLFloaterReg::findTypedInstance("material_editor", LLSD(itemId)); if (me) { @@ -752,6 +797,34 @@ void LLMaterialEditor::finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID } } +void LLMaterialEditor::finishSaveAs(const LLUUID &oldItemId, const LLUUID &newItemId, const std::string &buffer) +{ + LLMaterialEditor* me = LLFloaterReg::findTypedInstance("material_editor", LLSD(oldItemId)); + LLViewerInventoryItem* item = gInventory.getItem(newItemId); + if (item) + { + if (me) + { + me->mItemUUID = newItemId; + me->setKey(LLSD(newItemId)); // for findTypedInstance + me->setMaterialName(item->getName()); + if (!saveToInventoryItem(buffer, newItemId, LLUUID::null)) + { + me->setEnabled(true); + } + } + else + { + saveToInventoryItem(buffer, newItemId, LLUUID::null); + } + } + else if (me) + { + me->setEnabled(true); + LL_WARNS() << "Item does not exist" << LL_ENDL; + } +} + void LLMaterialEditor::refreshFromInventory(const LLUUID& new_item_id) { if (new_item_id.notNull()) @@ -778,11 +851,38 @@ void LLMaterialEditor::onSaveAsMsgCallback(const LLSD& notification, const LLSD& if (0 == option) { std::string new_name = response["message"].asString(); - LLStringUtil::trim(new_name); + LLInventoryObject::correctInventoryName(new_name); if (!new_name.empty()) { - setMaterialName(new_name); - onClickSave(); + const LLInventoryItem* item = getItem(); + if (item) + { + const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); + LLUUID parent_id = item->getParentUUID(); + if (mObjectUUID.notNull() || marketplacelistings_id == parent_id || gInventory.isObjectDescendentOf(item->getUUID(), gInventory.getLibraryRootFolderID())) + { + parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MATERIAL); + } + + // A two step process, first copy an existing item, then create new asset + std::string buffer = getEncodedAsset(); + LLPointer cb = new LLMaterialEditorCopiedCallback(buffer, item->getUUID()); + copy_inventory_item( + gAgent.getID(), + item->getPermissions().getOwner(), + item->getUUID(), + parent_id, + new_name, + cb); + + mAssetStatus = PREVIEW_ASSET_LOADING; + setEnabled(false); + } + else + { + setMaterialName(new_name); + onClickSave(); + } } else { @@ -1256,17 +1356,20 @@ void LLMaterialEditor::loadAsset() if (item) { LLPermissions perm(item->getPermissions()); - BOOL is_owner = gAgent.allowOperation(PERM_OWNER, perm, GP_OBJECT_MANIPULATE); BOOL allow_copy = gAgent.allowOperation(PERM_COPY, perm, GP_OBJECT_MANIPULATE); BOOL allow_modify = canModify(mObjectUUID, item); BOOL source_library = mObjectUUID.isNull() && gInventory.isObjectDescendentOf(mItemUUID, gInventory.getLibraryRootFolderID()); - if (allow_copy || gAgent.isGodlike()) + setCanSaveAs(allow_copy); + setCanSave(allow_modify && !source_library); + setMaterialName(item->getName()); + { mAssetID = item->getAssetUUID(); if (mAssetID.isNull()) { mAssetStatus = PREVIEW_ASSET_LOADED; + setHasUnsavedChanges(false); } else { @@ -1285,10 +1388,8 @@ void LLMaterialEditor::loadAsset() // The object that we're trying to look at disappeared, bail. LL_WARNS() << "Can't find object " << mObjectUUID << " associated with notecard." << LL_ENDL; mAssetID.setNull(); - /*editor->setText(getString("no_object")); - editor->makePristine(); - editor->setEnabled(FALSE);*/ mAssetStatus = PREVIEW_ASSET_LOADED; + setHasUnsavedChanges(false); return; } user_data->with("taskid", mObjectUUID).with("itemid", mItemUUID); @@ -1312,26 +1413,6 @@ void LLMaterialEditor::loadAsset() mAssetStatus = PREVIEW_ASSET_LOADING; } } - else - { - mAssetID.setNull(); - /*editor->setText(getString("not_allowed")); - editor->makePristine(); - editor->setEnabled(FALSE);*/ - mAssetStatus = PREVIEW_ASSET_LOADED; - } - - if (!allow_modify) - { - //editor->setEnabled(FALSE); - //getChildView("lock")->setVisible(TRUE); - //getChildView("Edit")->setEnabled(FALSE); - } - - if ((allow_modify || is_owner) && !source_library) - { - //getChildView("Delete")->setEnabled(TRUE); - } } else if (mObjectUUID.notNull() && mItemUUID.notNull()) { @@ -1391,6 +1472,7 @@ void LLMaterialEditor::onLoadComplete(const LLUUID& asset_uuid, BOOL modifiable = editor->canModify(editor->mObjectID, editor->getItem()); editor->setEnabled(modifiable); + editor->setHasUnsavedChanges(false); editor->mAssetStatus = PREVIEW_ASSET_LOADED; } else -- cgit v1.2.3 From 40a1154ec9e5b98bdeec408aa8cce7a10919d602 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 19 Jul 2022 19:56:16 +0300 Subject: SL-17640 Check account balance before uploading --- indra/newview/llmaterialeditor.cpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 4f8558277d..fe50689c1e 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -40,6 +40,7 @@ #include "llviewertexture.h" #include "llsdutil.h" #include "llselectmgr.h" +#include "llstatusbar.h" // can_afford_transaction() #include "llviewerinventory.h" #include "llviewerregion.h" #include "llvovolume.h" @@ -79,6 +80,7 @@ private: LLMaterialEditor::LLMaterialEditor(const LLSD& key) : LLPreview(key) , mHasUnsavedChanges(false) + , mExpectedUploadCost(0) { const LLInventoryItem* item = getItem(); if (item) @@ -366,8 +368,8 @@ void LLMaterialEditor::setHasUnsavedChanges(bool value) upload_texture_count++; } - S32 upload_cost = upload_texture_count * LLAgentBenefitsMgr::current().getTextureUploadCost(); - getChild("total_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); + mExpectedUploadCost = upload_texture_count * LLAgentBenefitsMgr::current().getTextureUploadCost(); + getChild("total_upload_fee")->setTextArg("[FEE]", llformat("%d", mExpectedUploadCost)); } void LLMaterialEditor::setCanSaveAs(BOOL value) @@ -474,6 +476,14 @@ static U32 write_texture(const LLUUID& id, tinygltf::Model& model) void LLMaterialEditor::onClickSave() { + if (!can_afford_transaction(mExpectedUploadCost)) + { + LLSD args; + args["COST"] = llformat("%d", mExpectedUploadCost); + LLNotificationsUtil::add("ErrorCannotAffordUpload", args); + return; + } + applyToSelection(); saveIfNeeded(); } @@ -839,6 +849,14 @@ void LLMaterialEditor::refreshFromInventory(const LLUUID& new_item_id) void LLMaterialEditor::onClickSaveAs() { + if (!can_afford_transaction(mExpectedUploadCost)) + { + LLSD args; + args["COST"] = llformat("%d", mExpectedUploadCost); + LLNotificationsUtil::add("ErrorCannotAffordUpload", args); + return; + } + LLSD args; args["DESC"] = mMaterialName; -- cgit v1.2.3 From 206d8a0e3124caee7778c9a1e1d44a9aaa4150de Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 20 Jul 2022 18:50:14 +0300 Subject: SL-17690 Uploaded material asset references wrong texture UUIDs Upload textures first, then get ids and upload material on callback --- indra/newview/llmaterialeditor.cpp | 159 +++++++++++++++++++++++++++++++++---- 1 file changed, 144 insertions(+), 15 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index fe50689c1e..47ae2ab4d1 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -57,6 +57,11 @@ #include +const std::string MATERIAL_ALBEDO_DEFAULT_NAME = "Albedo"; +const std::string MATERIAL_NORMAL_DEFAULT_NAME = "Normal"; +const std::string MATERIAL_METALLIC_DEFAULT_NAME = "Metallic Roughness"; +const std::string MATERIAL_EMISSIVE_DEFAULT_NAME = "Emissive"; + class LLMaterialEditorCopiedCallback : public LLInventoryCallback { public: @@ -81,6 +86,7 @@ LLMaterialEditor::LLMaterialEditor(const LLSD& key) : LLPreview(key) , mHasUnsavedChanges(false) , mExpectedUploadCost(0) + , mUploadingTexturesCount(0) { const LLInventoryItem* item = getItem(); if (item) @@ -644,9 +650,22 @@ bool LLMaterialEditor::decodeAsset(const std::vector& buffer) bool LLMaterialEditor::saveIfNeeded() { + if (mUploadingTexturesCount > 0) + { + // upload already in progress + // wait until textures upload + // will retry saving on callback + return true; + } + + if (saveTextures() > 0) + { + // started texture upload + setEnabled(false); + return true; + } + std::string buffer = getEncodedAsset(); - - saveTextures(); const LLInventoryItem* item = getItem(); // save it out to database @@ -1179,6 +1198,11 @@ void LLMaterialFilePicker::loadMaterial(const std::string& filename) { mME->mAlbedoFetched->forceToSaveRawImage(0, F32_MAX); albedo_id = mME->mAlbedoFetched->getID(); + + if (mME->mAlbedoName.empty()) + { + mME->mAlbedoName = MATERIAL_ALBEDO_DEFAULT_NAME; + } } LLUUID normal_id; @@ -1186,6 +1210,11 @@ void LLMaterialFilePicker::loadMaterial(const std::string& filename) { mME->mNormalFetched->forceToSaveRawImage(0, F32_MAX); normal_id = mME->mNormalFetched->getID(); + + if (mME->mNormalName.empty()) + { + mME->mNormalName = MATERIAL_NORMAL_DEFAULT_NAME; + } } LLUUID mr_id; @@ -1193,6 +1222,11 @@ void LLMaterialFilePicker::loadMaterial(const std::string& filename) { mME->mMetallicRoughnessFetched->forceToSaveRawImage(0, F32_MAX); mr_id = mME->mMetallicRoughnessFetched->getID(); + + if (mME->mMetallicRoughnessName.empty()) + { + mME->mMetallicRoughnessName = MATERIAL_METALLIC_DEFAULT_NAME; + } } LLUUID emissive_id; @@ -1200,6 +1234,11 @@ void LLMaterialFilePicker::loadMaterial(const std::string& filename) { mME->mEmissiveFetched->forceToSaveRawImage(0, F32_MAX); emissive_id = mME->mEmissiveFetched->getID(); + + if (mME->mEmissiveName.empty()) + { + mME->mEmissiveName = MATERIAL_EMISSIVE_DEFAULT_NAME; + } } mME->setAlbedoId(albedo_id); @@ -1526,7 +1565,7 @@ void LLMaterialEditor::inventoryChanged(LLViewerObject* object, } -void LLMaterialEditor::saveTexture(LLImageJ2C* img, const std::string& name, const LLUUID& asset_id) +void LLMaterialEditor::saveTexture(LLImageJ2C* img, const std::string& name, const LLUUID& asset_id, upload_callback_f cb) { if (asset_id.isNull() || img == nullptr @@ -1541,7 +1580,6 @@ void LLMaterialEditor::saveTexture(LLImageJ2C* img, const std::string& name, con U32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(); - LLAssetStorage::LLStoreAssetCallback callback; LLResourceUploadInfo::ptr_t uploadInfo(std::make_shared( buffer, @@ -1556,28 +1594,114 @@ void LLMaterialEditor::saveTexture(LLImageJ2C* img, const std::string& name, con LLFloaterPerms::getGroupPerms("Uploads"), LLFloaterPerms::getEveryonePerms("Uploads"), expected_upload_cost, - false)); + false, + cb)); - upload_new_resource(uploadInfo, callback, nullptr); + upload_new_resource(uploadInfo); } -void LLMaterialEditor::saveTextures() +S32 LLMaterialEditor::saveTextures() { - if (mAlbedoTextureUploadId == getAlbedoId()) + S32 work_count = 0; + LLSD key = getKey(); // must be locally declared for lambda's capture to work + if (mAlbedoTextureUploadId == getAlbedoId() && mAlbedoTextureUploadId.notNull()) { - saveTexture(mAlbedoJ2C, mAlbedoName, mAlbedoTextureUploadId); + mUploadingTexturesCount++; + work_count++; + saveTexture(mAlbedoJ2C, mAlbedoName, mAlbedoTextureUploadId, [key](LLUUID newAssetId, LLSD response) + { + LLMaterialEditor* me = LLFloaterReg::findTypedInstance("material_editor", key); + if (me) + { + if (response["success"].asBoolean()) + { + me->setAlbedoId(newAssetId); + } + else + { + // To make sure that we won't retry (some failures can cb immediately) + me->setAlbedoId(LLUUID::null); + } + me->mUploadingTexturesCount--; + + // try saving + me->saveIfNeeded(); + } + }); } - if (mNormalTextureUploadId == getNormalId()) + if (mNormalTextureUploadId == getNormalId() && mNormalTextureUploadId.notNull()) { - saveTexture(mNormalJ2C, mNormalName, mNormalTextureUploadId); + mUploadingTexturesCount++; + work_count++; + saveTexture(mNormalJ2C, mNormalName, mNormalTextureUploadId, [key](LLUUID newAssetId, LLSD response) + { + LLMaterialEditor* me = LLFloaterReg::findTypedInstance("material_editor", key); + if (me) + { + if (response["success"].asBoolean()) + { + me->setNormalId(newAssetId); + } + else + { + me->setNormalId(LLUUID::null); + } + me->setNormalId(newAssetId); + me->mUploadingTexturesCount--; + + // try saving + me->saveIfNeeded(); + } + }); } - if (mMetallicTextureUploadId == getMetallicRoughnessId()) + if (mMetallicTextureUploadId == getMetallicRoughnessId() && mMetallicTextureUploadId.notNull()) { - saveTexture(mMetallicRoughnessJ2C, mMetallicRoughnessName, mMetallicTextureUploadId); + mUploadingTexturesCount++; + work_count++; + saveTexture(mMetallicRoughnessJ2C, mMetallicRoughnessName, mMetallicTextureUploadId, [key](LLUUID newAssetId, LLSD response) + { + LLMaterialEditor* me = LLFloaterReg::findTypedInstance("material_editor", key); + if (me) + { + if (response["success"].asBoolean()) + { + me->setMetallicRoughnessId(newAssetId); + } + else + { + me->setMetallicRoughnessId(LLUUID::null); + } + me->mUploadingTexturesCount--; + + // try saving + me->saveIfNeeded(); + } + }); } - if (mEmissiveTextureUploadId == getEmissiveId()) + + if (mEmissiveTextureUploadId == getEmissiveId() && mEmissiveTextureUploadId.notNull()) { - saveTexture(mEmissiveJ2C, mEmissiveName, mEmissiveTextureUploadId); + mUploadingTexturesCount++; + work_count++; + saveTexture(mEmissiveJ2C, mEmissiveName, mEmissiveTextureUploadId, [key](LLUUID newAssetId, LLSD response) + { + LLMaterialEditor* me = LLFloaterReg::findTypedInstance("material_editor", LLSD(key)); + if (me) + { + if (response["success"].asBoolean()) + { + me->setEmissiveId(newAssetId); + } + else + { + me->setEmissiveId(LLUUID::null); + } + me->mUploadingTexturesCount--; + + // try saving + me->saveIfNeeded(); + } + }); } // discard upload buffers once textures have been saved @@ -1595,5 +1719,10 @@ void LLMaterialEditor::saveTextures() mNormalTextureUploadId.setNull(); mMetallicTextureUploadId.setNull(); mEmissiveTextureUploadId.setNull(); + + // asset storage can callback immediately, causing a decrease + // of mUploadingTexturesCount, report amount of work scheduled + // not amount of work remaining + return work_count; } -- cgit v1.2.3 From eec96559d41fd74a4fa1137336941a6c20036eba Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 2 Aug 2022 00:59:21 +0300 Subject: SL-17653 Fix live material preview not working Material was immediately dropped due to not having an id. This is a placeholder untill build floater gets a proper way to select materials. --- indra/newview/llmaterialeditor.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 47ae2ab4d1..57cd74e0f2 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1343,18 +1343,26 @@ void LLMaterialEditor::importMaterial() void LLMaterialEditor::applyToSelection() { - // Todo: associate with a specific 'selection' instead - // of modifying something that is selected - // This should be disabled when working from agent's - // inventory and for initial upload + // Todo: fix this, this is a hack, not a proper live preview LLViewerObject* objectp = LLSelectMgr::instance().getSelection()->getFirstObject(); - if (objectp && objectp->getVolume()) + if (objectp && objectp->getVolume() && objectp->permModify()) { LLGLTFMaterial* mat = new LLGLTFMaterial(); getGLTFMaterial(mat); LLVOVolume* vobjp = (LLVOVolume*)objectp; for (int i = 0; i < vobjp->getNumTEs(); ++i) { + // this is here just to prevent material from immediately resetting + if (mAssetID.notNull()) + { + vobjp->setRenderMaterialID(i, mAssetID); + } + else + { + const LLUUID placeholder("984e183e-7811-4b05-a502-d79c6f978a98"); + vobjp->setRenderMaterialID(i, placeholder); + } + vobjp->getTE(i)->setGLTFMaterial(mat); vobjp->updateTEMaterialTextures(i); } -- cgit v1.2.3 From 49278013ef3af18f4565f46aeb67368e6439ae46 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 8 Aug 2022 23:24:29 +0300 Subject: SL-17653 Apply selection to faces and linkset instead of just first object --- indra/newview/llmaterialeditor.cpp | 52 +++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 23 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 57cd74e0f2..0e252518cb 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -62,6 +62,7 @@ const std::string MATERIAL_NORMAL_DEFAULT_NAME = "Normal"; const std::string MATERIAL_METALLIC_DEFAULT_NAME = "Metallic Roughness"; const std::string MATERIAL_EMISSIVE_DEFAULT_NAME = "Emissive"; + class LLMaterialEditorCopiedCallback : public LLInventoryCallback { public: @@ -1341,34 +1342,39 @@ void LLMaterialEditor::importMaterial() (new LLMaterialFilePicker(this))->getFile(); } -void LLMaterialEditor::applyToSelection() +class LLRemderMaterialFunctor : public LLSelectedTEFunctor { - // Todo: fix this, this is a hack, not a proper live preview - LLViewerObject* objectp = LLSelectMgr::instance().getSelection()->getFirstObject(); - if (objectp && objectp->getVolume() && objectp->permModify()) +public: + LLRemderMaterialFunctor(LLGLTFMaterial *mat, const LLUUID &id) + : mMat(mat), mMatId(id) { - LLGLTFMaterial* mat = new LLGLTFMaterial(); - getGLTFMaterial(mat); - LLVOVolume* vobjp = (LLVOVolume*)objectp; - for (int i = 0; i < vobjp->getNumTEs(); ++i) - { - // this is here just to prevent material from immediately resetting - if (mAssetID.notNull()) - { - vobjp->setRenderMaterialID(i, mAssetID); - } - else - { - const LLUUID placeholder("984e183e-7811-4b05-a502-d79c6f978a98"); - vobjp->setRenderMaterialID(i, placeholder); - } + } - vobjp->getTE(i)->setGLTFMaterial(mat); - vobjp->updateTEMaterialTextures(i); + virtual bool apply(LLViewerObject* objectp, S32 te) + { + if (objectp && objectp->permModify() && objectp->getVolume()) + { + LLVOVolume* vobjp = (LLVOVolume*)objectp; + vobjp->setRenderMaterialID(te, mMatId); + vobjp->getTE(te)->setGLTFMaterial(mMat); + vobjp->updateTEMaterialTextures(te); } - - vobjp->markForUpdate(TRUE); + return true; } +private: + LLGLTFMaterial *mMat; + LLUUID mMatId; +}; + +void LLMaterialEditor::applyToSelection() +{ + LLGLTFMaterial* mat = new LLGLTFMaterial(); + getGLTFMaterial(mat); + const LLUUID placeholder("984e183e-7811-4b05-a502-d79c6f978a98"); + LLUUID asset_id = mAssetID.notNull() ? mAssetID : placeholder; + LLRemderMaterialFunctor mat_func(mat, mAssetID); + LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); + selected_objects->applyToTEs(&mat_func); } void LLMaterialEditor::getGLTFMaterial(LLGLTFMaterial* mat) -- cgit v1.2.3 From e73fd2a2f28a01c1ab1e0dee63ba4d2ca73c9634 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 9 Aug 2022 00:21:45 +0300 Subject: SL-17653 Perially done restoration functionality --- indra/newview/llmaterialeditor.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 0e252518cb..13e250ec3b 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -165,6 +165,15 @@ void LLMaterialEditor::onClickCloseBtn(bool app_quitting) } } +void LLMaterialEditor::onClose(bool app_quitting) +{ + // todo: will only revert whatever was recently selected, + // Later should work based of tools floater + LLSelectMgr::getInstance()->selectionRevertGLTFMaterials(); + + LLPreview::onClose(app_quitting); +} + LLUUID LLMaterialEditor::getAlbedoId() { return mAlbedoTextureCtrl->getValue().asUUID(); @@ -1362,17 +1371,17 @@ public: return true; } private: - LLGLTFMaterial *mMat; + LLPointer mMat; LLUUID mMatId; }; void LLMaterialEditor::applyToSelection() { - LLGLTFMaterial* mat = new LLGLTFMaterial(); + LLPointer mat = new LLGLTFMaterial(); getGLTFMaterial(mat); const LLUUID placeholder("984e183e-7811-4b05-a502-d79c6f978a98"); LLUUID asset_id = mAssetID.notNull() ? mAssetID : placeholder; - LLRemderMaterialFunctor mat_func(mat, mAssetID); + LLRemderMaterialFunctor mat_func(mat, asset_id); LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); selected_objects->applyToTEs(&mat_func); } -- cgit v1.2.3 From 3b416b3e98fe80b1d9b26352551e2d5860016b78 Mon Sep 17 00:00:00 2001 From: Callum Linden Date: Mon, 8 Aug 2022 16:40:25 -0700 Subject: SL-17695 Give materials and textures imported by Material Editor a sensible name - first pass - likely need to be refined but may be good enough for now --- indra/newview/llmaterialeditor.cpp | 245 ++++++++++++++++++++++++++++++++++++- 1 file changed, 242 insertions(+), 3 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 57cd74e0f2..c7fa2b6426 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -62,6 +62,7 @@ const std::string MATERIAL_NORMAL_DEFAULT_NAME = "Normal"; const std::string MATERIAL_METALLIC_DEFAULT_NAME = "Metallic Roughness"; const std::string MATERIAL_EMISSIVE_DEFAULT_NAME = "Emissive"; + class LLMaterialEditorCopiedCallback : public LLInventoryCallback { public: @@ -648,6 +649,54 @@ bool LLMaterialEditor::decodeAsset(const std::vector& buffer) return false; } +/** + * Build a description of the material we just imported. + * Currently this means a list of the textures present but we + * may eventually want to make it more complete - will be guided + * by what the content creators say they need. + */ +const std::string LLMaterialEditor::buildMaterialDescription() +{ + std::ostringstream desc; + desc << LLTrans::getString("Material Texture Name Header"); + + // add the texture names for each just so long as the material + // we loaded has an entry for it (i think testing the texture + // control UUI for NULL is a valid metric for if it was loaded + // or not but I suspect this code will change a lot so may need + // to revisit + if (!mAlbedoTextureCtrl->getValue().asUUID().isNull()) + { + desc << mAlbedoName; + desc << ", "; + } + if (!mMetallicTextureCtrl->getValue().asUUID().isNull()) + { + desc << mMetallicRoughnessName; + desc << ", "; + } + if (!mEmissiveTextureCtrl->getValue().asUUID().isNull()) + { + desc << mEmissiveName; + desc << ", "; + } + if (!mNormalTextureCtrl->getValue().asUUID().isNull()) + { + desc << mNormalName; + } + + // trim last char if it's a ',' in case there is no normal texture + // present and the code above inserts one + // (no need to check for string length - always has initial string) + std::string::iterator iter = desc.str().end() - 1; + if (*iter == ',') + { + desc.str().erase(iter); + } + + return desc.str(); +} + bool LLMaterialEditor::saveIfNeeded() { if (mUploadingTexturesCount > 0) @@ -693,7 +742,7 @@ bool LLMaterialEditor::saveIfNeeded() LLTransactionID tid; tid.generate(); // timestamp-based randomization + uniquification LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); - std::string res_desc = "Saved Material"; + std::string res_desc = buildMaterialDescription(); U32 next_owner_perm = LLPermissions::DEFAULT.getMaskNextOwner(); LLUUID parent = gInventory.findCategoryUUIDForType(LLFolderType::FT_MATERIAL); const U8 subtype = NO_INV_SUBTYPE; // TODO maybe use AT_SETTINGS and LLSettingsType::ST_MATERIAL ? @@ -1252,8 +1301,7 @@ void LLMaterialFilePicker::loadMaterial(const std::string& filename) mME->setFromGltfModel(model_in); - std::string new_material = LLTrans::getString("New Material"); - mME->setMaterialName(new_material); + mME->setFromGltfMetaData(filename_lc, model_in); mME->setHasUnsavedChanges(true); mME->openFloater(); @@ -1336,6 +1384,197 @@ bool LLMaterialEditor::setFromGltfModel(tinygltf::Model& model, bool set_texture return true; } +/** + * Build a texture name from the contents of the (in tinyGLFT parlance) + * Image URI. This often is filepath to the original image on the users' + * local file system. + */ +const std::string LLMaterialEditor::getImageNameFromUri(std::string image_uri, const std::string texture_type) +{ + // getBaseFileName() works differently on each platform and file patchs + // can contain both types of delimiter so unify them then extract the + // base name (no path or extension) + std::replace(image_uri.begin(), image_uri.end(), '\\', gDirUtilp->getDirDelimiter()[0]); + std::replace(image_uri.begin(), image_uri.end(), '/', gDirUtilp->getDirDelimiter()[0]); + const bool strip_extension = true; + std::string stripped_uri = gDirUtilp->getBaseFileName(image_uri, strip_extension); + + // sometimes they can be really long and unwieldy - 64 chars is enough for anyone :) + const int max_texture_name_length = 64; + if (stripped_uri.length() > max_texture_name_length) + { + stripped_uri = stripped_uri.substr(0, max_texture_name_length - 1); + } + + // We intend to append the type of texture (Albedo, emissive etc.) to the + // name of the texture but sometimes the creator already did that. To try + // to avoid repeats (not perfect), we look for the texture type in the name + // and if we find it, do not append the type, later on. One way this fails + // (and it's fine for now) is I see some texture/image uris have a name like + // "metallic roughness" and of course, that doesn't match our predefined + // name "metallicroughness" - might fix later.. + bool name_includes_type = false; + std::string stripped_uri_lower = stripped_uri; + LLStringUtil::toLower(stripped_uri_lower); + stripped_uri_lower.erase(std::remove_if(stripped_uri_lower.begin(), stripped_uri_lower.end(), isspace), stripped_uri_lower.end()); + std::string texture_type_lower = texture_type; + LLStringUtil::toLower(texture_type_lower); + texture_type_lower.erase(std::remove_if(texture_type_lower.begin(), texture_type_lower.end(), isspace), texture_type_lower.end()); + if (stripped_uri_lower.find(texture_type_lower) != std::string::npos) + { + name_includes_type = true; + } + + // uri doesn't include the type at all + if (name_includes_type == false) + { + // uri doesn't include the type and the uri is not empty + // so we can include everything + if (stripped_uri.length() > 0) + { + // example "DamagedHelmet: base layer (Albedo)" + return STRINGIZE( + mMaterialNameShort << + ": " << + stripped_uri << + " (" << + texture_type << + ")" + ); + } + else + // uri doesn't include the type (because the uri is empty) so + // reorganize the string a bit to include the name and type + { + // example "DamagedHelmet: (Emissive)" + return STRINGIZE( + mMaterialNameShort << + " (" << + texture_type << + ")" + ); + } + } + else + // uri includes the type so just use it directly with the + // name of the material + { + return STRINGIZE( + // example: AlienBust: normal_layer + mMaterialNameShort << + ": " << + stripped_uri + ); + } +} + +/** + * Update the metadata for the material based on what we find in the loaded + * data (along with some assumptions and interpretations...). Fields include + * the name of the material and the names of the composite textures. + */ +void LLMaterialEditor::setFromGltfMetaData(const std::string& filename, tinygltf::Model& model) +{ + // Use the name (without any path/extension) of the file that was + // uploaded as the base of the material name. Then if the name of the + // scene is present and not blank, append that and use the result as + // the name of the material. This is a first pass at creating a + // naming scheme that is useful to real content creators and hopefully + // avoid 500 materials in your inventory called "scene" or "Default" + const bool strip_extension = true; + std::string base_filename = gDirUtilp->getBaseFileName(filename, strip_extension); + + // Extract the name of the scene. Note it is often blank or some very + // generic name like "Scene" or "Default" so using this in the name + // is less useful than you might imagine. + std::string scene_name; + if (model.scenes.size() > 0) + { + tinygltf::Scene& scene_in = model.scenes[0]; + if (scene_in.name.length()) + { + scene_name = scene_in.name; + } + else + { + // scene name is empty so no point using it + } + } + else + { + // scene name isn't present so no point using it + } + + // If we have a valid scene name, use it to build the short and + // long versions of the material name. The long version is used + // as you might expect, for the material name. The short version is + // used as part of the image/texture name - the theory is that will + // allow content creators to track the material and the corresponding + // textures + if (scene_name.length()) + { + mMaterialNameShort = base_filename; + + mMaterialName = STRINGIZE( + base_filename << + " " << + "(" << + scene_name << + ")" + ); + } + else + // otherwise, just use the trimmed filename as is + { + mMaterialNameShort = base_filename; + mMaterialName = base_filename; + } + + // We also set the title of the floater to match the + // name of the material + setTitle(mMaterialName); + + /** + * Extract / derive the names of each composite texture. For each, the + * index in the first material (we only support 1 material currently) is + * used to to determine which of the "Images" is used. If the index is -1 + * then that texture type is not present in the material (Seems to be + * quite common that a material is missing 1 or more types of texture) + */ + if (model.materials.size() > 0) + { + const tinygltf::Material& first_material = model.materials[0]; + + mAlbedoName = MATERIAL_ALBEDO_DEFAULT_NAME; + int index = first_material.pbrMetallicRoughness.baseColorTexture.index; + if (index > -1 && index < model.images.size()) + { + mAlbedoName = getImageNameFromUri(model.images[index].uri, MATERIAL_ALBEDO_DEFAULT_NAME); + } + + mEmissiveName = MATERIAL_EMISSIVE_DEFAULT_NAME; + index = first_material.emissiveTexture.index; + if (index > -1 && index < model.images.size()) + { + mEmissiveName = getImageNameFromUri(model.images[index].uri, MATERIAL_EMISSIVE_DEFAULT_NAME); + } + + mMetallicRoughnessName = MATERIAL_METALLIC_DEFAULT_NAME; + index = first_material.pbrMetallicRoughness.metallicRoughnessTexture.index; + if (index > -1 && index < model.images.size()) + { + mMetallicRoughnessName = getImageNameFromUri(model.images[index].uri, MATERIAL_METALLIC_DEFAULT_NAME); + } + + mNormalName = MATERIAL_NORMAL_DEFAULT_NAME; + index = first_material.normalTexture.index; + if (index > -1 && index < model.images.size()) + { + mNormalName = getImageNameFromUri(model.images[index].uri, MATERIAL_NORMAL_DEFAULT_NAME); + } + } +} + void LLMaterialEditor::importMaterial() { (new LLMaterialFilePicker(this))->getFile(); -- cgit v1.2.3 From c989e202f2cc2703b7e11bc769f412f350f24445 Mon Sep 17 00:00:00 2001 From: Callum Linden Date: Tue, 9 Aug 2022 10:38:33 -0700 Subject: SL-17695 minor cleanup pass to make the PR a bit easier to read --- indra/newview/llmaterialeditor.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index c7fa2b6426..ecaca1255b 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -62,7 +62,6 @@ const std::string MATERIAL_NORMAL_DEFAULT_NAME = "Normal"; const std::string MATERIAL_METALLIC_DEFAULT_NAME = "Metallic Roughness"; const std::string MATERIAL_EMISSIVE_DEFAULT_NAME = "Emissive"; - class LLMaterialEditorCopiedCallback : public LLInventoryCallback { public: @@ -1406,13 +1405,13 @@ const std::string LLMaterialEditor::getImageNameFromUri(std::string image_uri, c stripped_uri = stripped_uri.substr(0, max_texture_name_length - 1); } - // We intend to append the type of texture (Albedo, emissive etc.) to the + // We intend to append the type of texture (albedo, emissive etc.) to the // name of the texture but sometimes the creator already did that. To try // to avoid repeats (not perfect), we look for the texture type in the name // and if we find it, do not append the type, later on. One way this fails // (and it's fine for now) is I see some texture/image uris have a name like // "metallic roughness" and of course, that doesn't match our predefined - // name "metallicroughness" - might fix later.. + // name "metallicroughness" - consider fix later.. bool name_includes_type = false; std::string stripped_uri_lower = stripped_uri; LLStringUtil::toLower(stripped_uri_lower); @@ -1443,8 +1442,9 @@ const std::string LLMaterialEditor::getImageNameFromUri(std::string image_uri, c ); } else - // uri doesn't include the type (because the uri is empty) so - // reorganize the string a bit to include the name and type + // uri doesn't include the type (because the uri is empty) + // so we must reorganize the string a bit to include the name + // and an explicit name type { // example "DamagedHelmet: (Emissive)" return STRINGIZE( @@ -1470,8 +1470,9 @@ const std::string LLMaterialEditor::getImageNameFromUri(std::string image_uri, c /** * Update the metadata for the material based on what we find in the loaded - * data (along with some assumptions and interpretations...). Fields include - * the name of the material and the names of the composite textures. + * file (along with some assumptions and interpretations...). Fields include + * the name of the material, a material description and the names of the + * composite textures. */ void LLMaterialEditor::setFromGltfMetaData(const std::string& filename, tinygltf::Model& model) { -- cgit v1.2.3 From 8645ffe172e1e847758249af7536eef71e430a17 Mon Sep 17 00:00:00 2001 From: Callum Linden Date: Wed, 10 Aug 2022 12:52:14 -0700 Subject: SL-17695 Sensible names for material properties - sanitize the various names we use to store inventory items using a built in function --- indra/newview/llmaterialeditor.cpp | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index ecaca1255b..ce2b229de9 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -42,6 +42,7 @@ #include "llselectmgr.h" #include "llstatusbar.h" // can_afford_transaction() #include "llviewerinventory.h" +#include "llinventory.h" #include "llviewerregion.h" #include "llvovolume.h" #include "roles_constants.h" @@ -693,6 +694,9 @@ const std::string LLMaterialEditor::buildMaterialDescription() desc.str().erase(iter); } + // sanitize the material description so that it's compatible with the inventory + LLInventoryObject::correctInventoryName(desc.str()); + return desc.str(); } @@ -1531,6 +1535,10 @@ void LLMaterialEditor::setFromGltfMetaData(const std::string& filename, tinygltf mMaterialName = base_filename; } + // sanitize the material name so that it's compatible with the inventory + LLInventoryObject::correctInventoryName(mMaterialName); + LLInventoryObject::correctInventoryName(mMaterialNameShort); + // We also set the title of the floater to match the // name of the material setTitle(mMaterialName); @@ -1547,31 +1555,43 @@ void LLMaterialEditor::setFromGltfMetaData(const std::string& filename, tinygltf const tinygltf::Material& first_material = model.materials[0]; mAlbedoName = MATERIAL_ALBEDO_DEFAULT_NAME; + // note: unlike the other textures, albedo doesn't have its own entry + // in the tinyGLTF Material struct. Rather, it is taken from a + // sub-texture in the pbrMetallicRoughness member int index = first_material.pbrMetallicRoughness.baseColorTexture.index; if (index > -1 && index < model.images.size()) { - mAlbedoName = getImageNameFromUri(model.images[index].uri, MATERIAL_ALBEDO_DEFAULT_NAME); + // sanitize the name we decide to use for each texture + std::string texture_name = getImageNameFromUri(model.images[index].uri, MATERIAL_ALBEDO_DEFAULT_NAME); + LLInventoryObject::correctInventoryName(texture_name); + mAlbedoName = texture_name; } mEmissiveName = MATERIAL_EMISSIVE_DEFAULT_NAME; index = first_material.emissiveTexture.index; if (index > -1 && index < model.images.size()) { - mEmissiveName = getImageNameFromUri(model.images[index].uri, MATERIAL_EMISSIVE_DEFAULT_NAME); + std::string texture_name = getImageNameFromUri(model.images[index].uri, MATERIAL_EMISSIVE_DEFAULT_NAME); + LLInventoryObject::correctInventoryName(texture_name); + mEmissiveName = texture_name; } mMetallicRoughnessName = MATERIAL_METALLIC_DEFAULT_NAME; index = first_material.pbrMetallicRoughness.metallicRoughnessTexture.index; if (index > -1 && index < model.images.size()) { - mMetallicRoughnessName = getImageNameFromUri(model.images[index].uri, MATERIAL_METALLIC_DEFAULT_NAME); + std::string texture_name = getImageNameFromUri(model.images[index].uri, MATERIAL_METALLIC_DEFAULT_NAME); + LLInventoryObject::correctInventoryName(texture_name); + mMetallicRoughnessName = texture_name; } mNormalName = MATERIAL_NORMAL_DEFAULT_NAME; index = first_material.normalTexture.index; if (index > -1 && index < model.images.size()) { - mNormalName = getImageNameFromUri(model.images[index].uri, MATERIAL_NORMAL_DEFAULT_NAME); + std::string texture_name = getImageNameFromUri(model.images[index].uri, MATERIAL_NORMAL_DEFAULT_NAME); + LLInventoryObject::correctInventoryName(texture_name); + mNormalName = texture_name; } } } -- cgit v1.2.3 From e7f562e6d8912573c255c8a6621c4f57d7df4b5c Mon Sep 17 00:00:00 2001 From: Callum Prentice Date: Mon, 15 Aug 2022 13:47:22 -0700 Subject: Fix for SL-17695 'Give materials and textures imported by Material Editor a sensible name' - compile error on mac/clang because it's more picky - as it should be in this case --- indra/newview/llmaterialeditor.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index ffeb2db4df..7b17fb5fdf 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -705,9 +705,13 @@ const std::string LLMaterialEditor::buildMaterialDescription() } // sanitize the material description so that it's compatible with the inventory - LLInventoryObject::correctInventoryName(desc.str()); + // note: split this up because clang doesn't like operating directly on the + // str() - error: lvalue reference to type 'basic_string<...>' cannot bind to a + // temporary of type 'basic_string<...>' + std::string inv_desc = desc.str(); + LLInventoryObject::correctInventoryName(inv_desc); - return desc.str(); + return inv_desc; } bool LLMaterialEditor::saveIfNeeded() -- cgit v1.2.3 From 4bb419031c130402a5589ff698e28e230a0c123a Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 19 Aug 2022 01:45:47 +0300 Subject: SL-17653 Basic local gltf materials --- indra/newview/llmaterialeditor.cpp | 103 +++++-------------------------------- 1 file changed, 12 insertions(+), 91 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 7b17fb5fdf..9743976e33 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -55,6 +55,7 @@ #include "llfloaterperms.h" #include "tinygltf/tiny_gltf.h" +#include "lltinygltfhelper.h" #include @@ -1046,38 +1047,6 @@ void LLMaterialFilePicker::notify(const std::vector& filenames) } } -const tinygltf::Image* get_image_from_texture_index(const tinygltf::Model& model, S32 texture_index) -{ - if (texture_index >= 0) - { - S32 source_idx = model.textures[texture_index].source; - if (source_idx >= 0) - { - return &(model.images[source_idx]); - } - } - - return nullptr; -} - -static LLImageRaw* get_texture(const std::string& folder, const tinygltf::Model& model, S32 texture_index, std::string& name) -{ - const tinygltf::Image* image = get_image_from_texture_index(model, texture_index); - LLImageRaw* rawImage = nullptr; - - if (image != nullptr && - image->bits == 8 && - !image->image.empty() && - image->component <= 4) - { - name = image->name; - rawImage = new LLImageRaw(&image->image[0], image->width, image->height, image->component); - rawImage->verticalFlip(); - } - - return rawImage; -} - static void strip_alpha_channel(LLPointer& img) { if (img->getComponents() == 4) @@ -1108,16 +1077,12 @@ static void copy_red_channel(LLPointer& src_img, LLPointer& albedo_img, LLPointer& normal_img, LLPointer& mr_img, LLPointer& emissive_img, LLPointer& occlusion_img, - LLPointer& albedo_tex, - LLPointer& normal_tex, - LLPointer& mr_tex, - LLPointer& emissive_tex, LLPointer& albedo_j2c, LLPointer& normal_j2c, LLPointer& mr_j2c, @@ -1125,70 +1090,25 @@ static void pack_textures(tinygltf::Model& model, tinygltf::Material& material, { if (albedo_img) { - albedo_tex = LLViewerTextureManager::getFetchedTexture(albedo_img, FTType::FTT_LOCAL_FILE, true); albedo_j2c = LLViewerTextureList::convertToUploadFile(albedo_img); } if (normal_img) { - strip_alpha_channel(normal_img); - normal_tex = LLViewerTextureManager::getFetchedTexture(normal_img, FTType::FTT_LOCAL_FILE, true); normal_j2c = LLViewerTextureList::convertToUploadFile(normal_img); } if (mr_img) { - strip_alpha_channel(mr_img); - - if (occlusion_img && material.pbrMetallicRoughness.metallicRoughnessTexture.index != material.occlusionTexture.index) - { - // occlusion is a distinct texture from pbrMetallicRoughness - // pack into mr red channel - int occlusion_idx = material.occlusionTexture.index; - int mr_idx = material.pbrMetallicRoughness.metallicRoughnessTexture.index; - if (occlusion_idx != mr_idx) - { - //scale occlusion image to match resolution of mr image - occlusion_img->scale(mr_img->getWidth(), mr_img->getHeight()); - - copy_red_channel(occlusion_img, mr_img); - } - } - } - else if (occlusion_img) - { - //no mr but occlusion exists, make a white mr_img and copy occlusion red channel over - mr_img = new LLImageRaw(occlusion_img->getWidth(), occlusion_img->getHeight(), 3); - mr_img->clear(255, 255, 255); - copy_red_channel(occlusion_img, mr_img); - - } - - if (mr_img) - { - mr_tex = LLViewerTextureManager::getFetchedTexture(mr_img, FTType::FTT_LOCAL_FILE, true); mr_j2c = LLViewerTextureList::convertToUploadFile(mr_img); } if (emissive_img) { - strip_alpha_channel(emissive_img); - emissive_tex = LLViewerTextureManager::getFetchedTexture(emissive_img, FTType::FTT_LOCAL_FILE, true); emissive_j2c = LLViewerTextureList::convertToUploadFile(emissive_img); } } -static LLColor4 get_color(const std::vector& in) -{ - LLColor4 out; - for (S32 i = 0; i < llmin((S32) in.size(), 4); ++i) - { - out.mV[i] = in[i]; - } - - return out; -} - void LLMaterialFilePicker::textureLoadedCallback(BOOL success, LLViewerFetchedTexture* src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata) { } @@ -1240,23 +1160,24 @@ void LLMaterialFilePicker::loadMaterial(const std::string& filename) model_out.materials.resize(1); // get albedo texture - LLPointer albedo_img = get_texture(folder, model_in, material_in.pbrMetallicRoughness.baseColorTexture.index, mME->mAlbedoName); + LLPointer albedo_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.pbrMetallicRoughness.baseColorTexture.index, mME->mAlbedoName); // get normal map - LLPointer normal_img = get_texture(folder, model_in, material_in.normalTexture.index, mME->mNormalName); + LLPointer normal_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.normalTexture.index, mME->mNormalName); // get metallic-roughness texture - LLPointer mr_img = get_texture(folder, model_in, material_in.pbrMetallicRoughness.metallicRoughnessTexture.index, mME->mMetallicRoughnessName); + LLPointer mr_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.pbrMetallicRoughness.metallicRoughnessTexture.index, mME->mMetallicRoughnessName); // get emissive texture - LLPointer emissive_img = get_texture(folder, model_in, material_in.emissiveTexture.index, mME->mEmissiveName); + LLPointer emissive_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.emissiveTexture.index, mME->mEmissiveName); // get occlusion map if needed LLPointer occlusion_img; if (material_in.occlusionTexture.index != material_in.pbrMetallicRoughness.metallicRoughnessTexture.index) { std::string tmp; - occlusion_img = get_texture(folder, model_in, material_in.occlusionTexture.index, tmp); + occlusion_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.occlusionTexture.index, tmp); } - pack_textures(model_in, material_in, albedo_img, normal_img, mr_img, emissive_img, occlusion_img, - mME->mAlbedoFetched, mME->mNormalFetched, mME->mMetallicRoughnessFetched, mME->mEmissiveFetched, + LLTinyGLTFHelper::initFetchedTextures(material_in, albedo_img, normal_img, mr_img, emissive_img, occlusion_img, + mME->mAlbedoFetched, mME->mNormalFetched, mME->mMetallicRoughnessFetched, mME->mEmissiveFetched); + pack_textures(albedo_img, normal_img, mr_img, emissive_img, occlusion_img, mME->mAlbedoJ2C, mME->mNormalJ2C, mME->mMetallicRoughnessJ2C, mME->mEmissiveJ2C); LLUUID albedo_id; @@ -1389,8 +1310,8 @@ bool LLMaterialEditor::setFromGltfModel(tinygltf::Model& model, bool set_texture setAlphaMode(material_in.alphaMode); setAlphaCutoff(material_in.alphaCutoff); - setAlbedoColor(get_color(material_in.pbrMetallicRoughness.baseColorFactor)); - setEmissiveColor(get_color(material_in.emissiveFactor)); + setAlbedoColor(LLTinyGLTFHelper::getColor(material_in.pbrMetallicRoughness.baseColorFactor)); + setEmissiveColor(LLTinyGLTFHelper::getColor(material_in.emissiveFactor)); setMetalnessFactor(material_in.pbrMetallicRoughness.metallicFactor); setRoughnessFactor(material_in.pbrMetallicRoughness.roughnessFactor); -- cgit v1.2.3 From 0d217dc73c6530dcbceb306c4609e2d72da6d70b Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Sat, 20 Aug 2022 01:04:42 +0300 Subject: SL-17653 Local gltf materials #2 --- indra/newview/llmaterialeditor.cpp | 97 +++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 48 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 9743976e33..95f96c95f2 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1019,18 +1019,15 @@ void LLMaterialEditor::onCancelMsgCallback(const LLSD& notification, const LLSD& class LLMaterialFilePicker : public LLFilePickerThread { public: - LLMaterialFilePicker(LLMaterialEditor* me); + LLMaterialFilePicker(); virtual void notify(const std::vector& filenames); - void loadMaterial(const std::string& filename); static void textureLoadedCallback(BOOL success, LLViewerFetchedTexture* src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata); -private: - LLMaterialEditor* mME; + }; -LLMaterialFilePicker::LLMaterialFilePicker(LLMaterialEditor* me) +LLMaterialFilePicker::LLMaterialFilePicker() : LLFilePickerThread(LLFilePicker::FFLOAD_MATERIAL) { - mME = me; } void LLMaterialFilePicker::notify(const std::vector& filenames) @@ -1043,7 +1040,11 @@ void LLMaterialFilePicker::notify(const std::vector& filenames) if (filenames.size() > 0) { - loadMaterial(filenames[0]); + LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor"); + if (me) + { + me->loadMaterialFromFile(filenames[0]); + } } } @@ -1114,7 +1115,7 @@ void LLMaterialFilePicker::textureLoadedCallback(BOOL success, LLViewerFetchedTe } -void LLMaterialFilePicker::loadMaterial(const std::string& filename) +void LLMaterialEditor::loadMaterialFromFile(const std::string& filename) { tinygltf::TinyGLTF loader; std::string error_msg; @@ -1160,13 +1161,13 @@ void LLMaterialFilePicker::loadMaterial(const std::string& filename) model_out.materials.resize(1); // get albedo texture - LLPointer albedo_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.pbrMetallicRoughness.baseColorTexture.index, mME->mAlbedoName); + LLPointer albedo_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.pbrMetallicRoughness.baseColorTexture.index, mAlbedoName); // get normal map - LLPointer normal_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.normalTexture.index, mME->mNormalName); + LLPointer normal_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.normalTexture.index, mNormalName); // get metallic-roughness texture - LLPointer mr_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.pbrMetallicRoughness.metallicRoughnessTexture.index, mME->mMetallicRoughnessName); + LLPointer mr_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.pbrMetallicRoughness.metallicRoughnessTexture.index, mMetallicRoughnessName); // get emissive texture - LLPointer emissive_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.emissiveTexture.index, mME->mEmissiveName); + LLPointer emissive_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.emissiveTexture.index, mEmissiveName); // get occlusion map if needed LLPointer occlusion_img; if (material_in.occlusionTexture.index != material_in.pbrMetallicRoughness.metallicRoughnessTexture.index) @@ -1176,75 +1177,75 @@ void LLMaterialFilePicker::loadMaterial(const std::string& filename) } LLTinyGLTFHelper::initFetchedTextures(material_in, albedo_img, normal_img, mr_img, emissive_img, occlusion_img, - mME->mAlbedoFetched, mME->mNormalFetched, mME->mMetallicRoughnessFetched, mME->mEmissiveFetched); + mAlbedoFetched, mNormalFetched, mMetallicRoughnessFetched, mEmissiveFetched); pack_textures(albedo_img, normal_img, mr_img, emissive_img, occlusion_img, - mME->mAlbedoJ2C, mME->mNormalJ2C, mME->mMetallicRoughnessJ2C, mME->mEmissiveJ2C); + mAlbedoJ2C, mNormalJ2C, mMetallicRoughnessJ2C, mEmissiveJ2C); LLUUID albedo_id; - if (mME->mAlbedoFetched.notNull()) + if (mAlbedoFetched.notNull()) { - mME->mAlbedoFetched->forceToSaveRawImage(0, F32_MAX); - albedo_id = mME->mAlbedoFetched->getID(); + mAlbedoFetched->forceToSaveRawImage(0, F32_MAX); + albedo_id = mAlbedoFetched->getID(); - if (mME->mAlbedoName.empty()) + if (mAlbedoName.empty()) { - mME->mAlbedoName = MATERIAL_ALBEDO_DEFAULT_NAME; + mAlbedoName = MATERIAL_ALBEDO_DEFAULT_NAME; } } LLUUID normal_id; - if (mME->mNormalFetched.notNull()) + if (mNormalFetched.notNull()) { - mME->mNormalFetched->forceToSaveRawImage(0, F32_MAX); - normal_id = mME->mNormalFetched->getID(); + mNormalFetched->forceToSaveRawImage(0, F32_MAX); + normal_id = mNormalFetched->getID(); - if (mME->mNormalName.empty()) + if (mNormalName.empty()) { - mME->mNormalName = MATERIAL_NORMAL_DEFAULT_NAME; + mNormalName = MATERIAL_NORMAL_DEFAULT_NAME; } } LLUUID mr_id; - if (mME->mMetallicRoughnessFetched.notNull()) + if (mMetallicRoughnessFetched.notNull()) { - mME->mMetallicRoughnessFetched->forceToSaveRawImage(0, F32_MAX); - mr_id = mME->mMetallicRoughnessFetched->getID(); + mMetallicRoughnessFetched->forceToSaveRawImage(0, F32_MAX); + mr_id = mMetallicRoughnessFetched->getID(); - if (mME->mMetallicRoughnessName.empty()) + if (mMetallicRoughnessName.empty()) { - mME->mMetallicRoughnessName = MATERIAL_METALLIC_DEFAULT_NAME; + mMetallicRoughnessName = MATERIAL_METALLIC_DEFAULT_NAME; } } LLUUID emissive_id; - if (mME->mEmissiveFetched.notNull()) + if (mEmissiveFetched.notNull()) { - mME->mEmissiveFetched->forceToSaveRawImage(0, F32_MAX); - emissive_id = mME->mEmissiveFetched->getID(); + mEmissiveFetched->forceToSaveRawImage(0, F32_MAX); + emissive_id = mEmissiveFetched->getID(); - if (mME->mEmissiveName.empty()) + if (mEmissiveName.empty()) { - mME->mEmissiveName = MATERIAL_EMISSIVE_DEFAULT_NAME; + mEmissiveName = MATERIAL_EMISSIVE_DEFAULT_NAME; } } - mME->setAlbedoId(albedo_id); - mME->setAlbedoUploadId(albedo_id); - mME->setMetallicRoughnessId(mr_id); - mME->setMetallicRoughnessUploadId(mr_id); - mME->setEmissiveId(emissive_id); - mME->setEmissiveUploadId(emissive_id); - mME->setNormalId(normal_id); - mME->setNormalUploadId(normal_id); + setAlbedoId(albedo_id); + setAlbedoUploadId(albedo_id); + setMetallicRoughnessId(mr_id); + setMetallicRoughnessUploadId(mr_id); + setEmissiveId(emissive_id); + setEmissiveUploadId(emissive_id); + setNormalId(normal_id); + setNormalUploadId(normal_id); - mME->setFromGltfModel(model_in); + setFromGltfModel(model_in); - mME->setFromGltfMetaData(filename_lc, model_in); + setFromGltfMetaData(filename_lc, model_in); - mME->setHasUnsavedChanges(true); - mME->openFloater(); + setHasUnsavedChanges(true); + openFloater(); - mME->applyToSelection(); + applyToSelection(); } bool LLMaterialEditor::setFromGltfModel(tinygltf::Model& model, bool set_textures) @@ -1533,7 +1534,7 @@ void LLMaterialEditor::setFromGltfMetaData(const std::string& filename, tinygltf void LLMaterialEditor::importMaterial() { - (new LLMaterialFilePicker(this))->getFile(); + (new LLMaterialFilePicker())->getFile(); } class LLRemderMaterialFunctor : public LLSelectedTEFunctor -- cgit v1.2.3 From 8a91c1394745a28cb78e7432eaa481b6cedd7408 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 22 Aug 2022 22:11:58 +0300 Subject: SL-17653 Local gltf materials #3 --- indra/newview/llmaterialeditor.cpp | 30 ------------------------------ 1 file changed, 30 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 95f96c95f2..2052f252b3 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1048,36 +1048,6 @@ void LLMaterialFilePicker::notify(const std::vector& filenames) } } -static void strip_alpha_channel(LLPointer& img) -{ - if (img->getComponents() == 4) - { - LLImageRaw* tmp = new LLImageRaw(img->getWidth(), img->getHeight(), 3); - tmp->copyUnscaled4onto3(img); - img = tmp; - } -} - -// copy red channel from src_img to dst_img -// PRECONDITIONS: -// dst_img must be 3 component -// src_img and dst_image must have the same dimensions -static void copy_red_channel(LLPointer& src_img, LLPointer& dst_img) -{ - llassert(src_img->getWidth() == dst_img->getWidth() && src_img->getHeight() == dst_img->getHeight()); - llassert(dst_img->getComponents() == 3); - - U32 pixel_count = dst_img->getWidth() * dst_img->getHeight(); - U8* src = src_img->getData(); - U8* dst = dst_img->getData(); - S8 src_components = src_img->getComponents(); - - for (U32 i = 0; i < pixel_count; ++i) - { - dst[i * 3] = src[i * src_components]; - } -} - static void pack_textures( LLPointer& albedo_img, LLPointer& normal_img, -- cgit v1.2.3 From 47ecbca24d5ec11ee5cd940fe9db55022fab8dbe Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 30 Aug 2022 16:43:05 -0500 Subject: SL-17987 Fix for material editor not initializing to GLTF defaults when loading a null material asset. --- indra/newview/llmaterialeditor.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 2052f252b3..f05f0344bd 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1605,6 +1605,7 @@ void LLMaterialEditor::loadAsset() if (mAssetID.isNull()) { mAssetStatus = PREVIEW_ASSET_LOADED; + loadDefaults(); setHasUnsavedChanges(false); } else @@ -1905,3 +1906,9 @@ S32 LLMaterialEditor::saveTextures() return work_count; } +void LLMaterialEditor::loadDefaults() +{ + tinygltf::Model model_in; + model_in.materials.resize(1); + setFromGltfModel(model_in, true); +} -- cgit v1.2.3 From e0c226b04d6f2ac566a9ea5841509f7cdfa98c11 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 1 Sep 2022 18:06:15 -0500 Subject: SL-18078, SL-18065 -- Experimentally allow uploading of lossless normal maps, fix for crash on shutdown. --- indra/newview/llmaterialeditor.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index f05f0344bd..5acf0600b6 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1059,24 +1059,39 @@ static void pack_textures( LLPointer& mr_j2c, LLPointer& emissive_j2c) { + // NOTE : remove log spam and lossless vs lossy comparisons when the logs are no longer useful + if (albedo_img) { albedo_j2c = LLViewerTextureList::convertToUploadFile(albedo_img); + LL_INFOS() << "Albedo: " << albedo_j2c->getDataSize() << LL_ENDL; } if (normal_img) { normal_j2c = LLViewerTextureList::convertToUploadFile(normal_img); + + LLPointer test; + test = LLViewerTextureList::convertToUploadFile(normal_img, 1024, true); + + S32 lossy_bytes = normal_j2c->getDataSize(); + S32 lossless_bytes = test->getDataSize(); + + LL_INFOS() << llformat("Lossless vs Lossy: (%d/%d) = %.2f", lossless_bytes, lossy_bytes, (F32)lossless_bytes / lossy_bytes) << LL_ENDL; + + normal_j2c = test; } if (mr_img) { mr_j2c = LLViewerTextureList::convertToUploadFile(mr_img); + LL_INFOS() << "Metallic/Roughness: " << mr_j2c->getDataSize() << LL_ENDL; } if (emissive_img) { emissive_j2c = LLViewerTextureList::convertToUploadFile(emissive_img); + LL_INFOS() << "Emissive: " << emissive_j2c->getDataSize() << LL_ENDL; } } -- cgit v1.2.3 From 7229dfcc59943f025219721701b2bda471a2ae25 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Fri, 2 Sep 2022 16:12:49 -0700 Subject: SL-17701: PBR: Add support for gltf Alpha MASK (cutoff) --- indra/newview/llmaterialeditor.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 5acf0600b6..6461aa71a6 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1574,6 +1574,7 @@ void LLMaterialEditor::getGLTFMaterial(LLGLTFMaterial* mat) mat->mDoubleSided = getDoubleSided(); mat->setAlphaMode(getAlphaMode()); + mat->mAlphaCutoff = getAlphaCutoff(); } void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat) @@ -1591,6 +1592,7 @@ void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat) setDoubleSided(mat->mDoubleSided); setAlphaMode(mat->getAlphaMode()); + setAlphaCutoff(mat->mAlphaCutoff); } void LLMaterialEditor::loadAsset() -- cgit v1.2.3 From 5d918f98eaacc0eec84edcf23a40d6f6c93807c3 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 15 Sep 2022 00:01:03 +0300 Subject: SL-18161 Add PBR materials to Uploads in preferences --- indra/newview/llmaterialeditor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 6461aa71a6..477f834a22 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -762,7 +762,7 @@ bool LLMaterialEditor::saveIfNeeded() LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); std::string res_desc = buildMaterialDescription(); U32 next_owner_perm = LLPermissions::DEFAULT.getMaskNextOwner(); - LLUUID parent = gInventory.findCategoryUUIDForType(LLFolderType::FT_MATERIAL); + LLUUID parent = gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_MATERIAL); const U8 subtype = NO_INV_SUBTYPE; // TODO maybe use AT_SETTINGS and LLSettingsType::ST_MATERIAL ? create_inventory_item(gAgent.getID(), gAgent.getSessionID(), parent, tid, mMaterialName, res_desc, -- cgit v1.2.3 From 6afd635da4b49a81223b51f0b3ecf174416e697e Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 15 Sep 2022 23:12:06 +0300 Subject: SL-18125 Material asset creation pulls wrong set of permissions --- indra/newview/llmaterialeditor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 477f834a22..b4e5e14885 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -761,7 +761,7 @@ bool LLMaterialEditor::saveIfNeeded() tid.generate(); // timestamp-based randomization + uniquification LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); std::string res_desc = buildMaterialDescription(); - U32 next_owner_perm = LLPermissions::DEFAULT.getMaskNextOwner(); + U32 next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Uploads"); LLUUID parent = gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_MATERIAL); const U8 subtype = NO_INV_SUBTYPE; // TODO maybe use AT_SETTINGS and LLSettingsType::ST_MATERIAL ? -- cgit v1.2.3 From b2cf07f53ca9f0ab82d466063af8307631c50f31 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 17 Sep 2022 01:12:52 -0500 Subject: WIP - switch PBR implementations --- indra/newview/llmaterialeditor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index b4e5e14885..bdc66a85fc 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -204,14 +204,14 @@ void LLMaterialEditor::setAlbedoUploadId(const LLUUID& id) LLColor4 LLMaterialEditor::getAlbedoColor() { - LLColor4 ret = LLColor4(childGetValue("albedo color")); + LLColor4 ret = linearColor4(LLColor4(childGetValue("albedo color"))); ret.mV[3] = getTransparency(); return ret; } void LLMaterialEditor::setAlbedoColor(const LLColor4& color) { - childSetValue("albedo color", color.getValue()); + childSetValue("albedo color", srgbColor4(color).getValue()); setTransparency(color.mV[3]); } -- cgit v1.2.3 From 524e5f06b7665cf7b26f451998a418d2cfe9ae13 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 22 Sep 2022 20:15:38 +0300 Subject: SL-18001 Fix LLMaterialEditor::applyToSelection() --- indra/newview/llmaterialeditor.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index bdc66a85fc..4efbf19572 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -32,6 +32,9 @@ #include "llagentbenefits.h" #include "llappviewer.h" #include "llcombobox.h" +#include "llfloaterreg.h" +#include "llfilesystem.h" +#include "llgltfmateriallist.h" #include "llinventorymodel.h" #include "llnotificationsutil.h" #include "lltexturectrl.h" @@ -47,8 +50,6 @@ #include "llvovolume.h" #include "roles_constants.h" #include "llviewerobjectlist.h" -#include "llfloaterreg.h" -#include "llfilesystem.h" #include "llsdserialize.h" #include "llimagej2c.h" #include "llviewertexturelist.h" @@ -1525,8 +1526,8 @@ void LLMaterialEditor::importMaterial() class LLRemderMaterialFunctor : public LLSelectedTEFunctor { public: - LLRemderMaterialFunctor(LLGLTFMaterial *mat, const LLUUID &id) - : mMat(mat), mMatId(id) + LLRemderMaterialFunctor(const LLUUID &id) + : mMatId(id) { } @@ -1535,24 +1536,23 @@ public: if (objectp && objectp->permModify() && objectp->getVolume()) { LLVOVolume* vobjp = (LLVOVolume*)objectp; - vobjp->setRenderMaterialID(te, mMatId); - vobjp->getTE(te)->setGLTFMaterial(mMat); + vobjp->setRenderMaterialID(te, mMatId, false /*preview only*/); vobjp->updateTEMaterialTextures(te); } return true; } private: - LLPointer mMat; LLUUID mMatId; }; void LLMaterialEditor::applyToSelection() { + // Placehodler. Will be removed once override systems gets finished. LLPointer mat = new LLGLTFMaterial(); getGLTFMaterial(mat); const LLUUID placeholder("984e183e-7811-4b05-a502-d79c6f978a98"); - LLUUID asset_id = mAssetID.notNull() ? mAssetID : placeholder; - LLRemderMaterialFunctor mat_func(mat, asset_id); + gGLTFMaterialList.addMaterial(placeholder, mat); + LLRemderMaterialFunctor mat_func(placeholder); LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); selected_objects->applyToTEs(&mat_func); } -- cgit v1.2.3 From 8f1d22686551f4d6783d03cd3685085ed7fcb96c Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 23 Sep 2022 11:19:56 -0500 Subject: SL-18134 Rename Albedo to Base Color to be more consistent with GLTF spec --- indra/newview/llmaterialeditor.cpp | 152 ++++++++++++++++++------------------- 1 file changed, 76 insertions(+), 76 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 4efbf19572..12d21cf284 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -60,7 +60,7 @@ #include -const std::string MATERIAL_ALBEDO_DEFAULT_NAME = "Albedo"; +const std::string MATERIAL_BASE_COLOR_DEFAULT_NAME = "Base Color"; const std::string MATERIAL_NORMAL_DEFAULT_NAME = "Normal"; const std::string MATERIAL_METALLIC_DEFAULT_NAME = "Metallic Roughness"; const std::string MATERIAL_EMISSIVE_DEFAULT_NAME = "Emissive"; @@ -101,12 +101,12 @@ LLMaterialEditor::LLMaterialEditor(const LLSD& key) BOOL LLMaterialEditor::postBuild() { - mAlbedoTextureCtrl = getChild("albedo_texture"); + mBaseColorTextureCtrl = getChild("base_color_texture"); mMetallicTextureCtrl = getChild("metallic_roughness_texture"); mEmissiveTextureCtrl = getChild("emissive_texture"); mNormalTextureCtrl = getChild("normal_texture"); - mAlbedoTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitAlbedoTexture, this, _1, _2)); + mBaseColorTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitBaseColorTexture, this, _1, _2)); mMetallicTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitMetallicTexture, this, _1, _2)); mEmissiveTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitEmissiveTexture, this, _1, _2)); mNormalTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitNormalTexture, this, _1, _2)); @@ -116,7 +116,7 @@ BOOL LLMaterialEditor::postBuild() childSetAction("cancel", boost::bind(&LLMaterialEditor::onClickCancel, this)); S32 upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(); - getChild("albedo_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); + getChild("base_color_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); getChild("metallic_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); getChild("emissive_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); getChild("normal_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); @@ -130,8 +130,8 @@ BOOL LLMaterialEditor::postBuild() childSetCommitCallback("double sided", changes_callback, NULL); - // Albedo - childSetCommitCallback("albedo color", changes_callback, NULL); + // BaseColor + childSetCommitCallback("base color", changes_callback, NULL); childSetCommitCallback("transparency", changes_callback, NULL); childSetCommitCallback("alpha mode", changes_callback, NULL); childSetCommitCallback("alpha cutoff", changes_callback, NULL); @@ -177,18 +177,18 @@ void LLMaterialEditor::onClose(bool app_quitting) LLPreview::onClose(app_quitting); } -LLUUID LLMaterialEditor::getAlbedoId() +LLUUID LLMaterialEditor::getBaseColorId() { - return mAlbedoTextureCtrl->getValue().asUUID(); + return mBaseColorTextureCtrl->getValue().asUUID(); } -void LLMaterialEditor::setAlbedoId(const LLUUID& id) +void LLMaterialEditor::setBaseColorId(const LLUUID& id) { - mAlbedoTextureCtrl->setValue(id); - mAlbedoTextureCtrl->setDefaultImageAssetID(id); + mBaseColorTextureCtrl->setValue(id); + mBaseColorTextureCtrl->setDefaultImageAssetID(id); } -void LLMaterialEditor::setAlbedoUploadId(const LLUUID& id) +void LLMaterialEditor::setBaseColorUploadId(const LLUUID& id) { // Might be better to use local textures and // assign a fee in case of a local texture @@ -196,23 +196,23 @@ void LLMaterialEditor::setAlbedoUploadId(const LLUUID& id) { // todo: this does not account for posibility of texture // being from inventory, need to check that - childSetValue("albedo_upload_fee", getString("upload_fee_string")); + childSetValue("base_color_upload_fee", getString("upload_fee_string")); // Only set if we will need to upload this texture - mAlbedoTextureUploadId = id; + mBaseColorTextureUploadId = id; } setHasUnsavedChanges(true); } -LLColor4 LLMaterialEditor::getAlbedoColor() +LLColor4 LLMaterialEditor::getBaseColor() { - LLColor4 ret = linearColor4(LLColor4(childGetValue("albedo color"))); + LLColor4 ret = linearColor4(LLColor4(childGetValue("base color"))); ret.mV[3] = getTransparency(); return ret; } -void LLMaterialEditor::setAlbedoColor(const LLColor4& color) +void LLMaterialEditor::setBaseColor(const LLColor4& color) { - childSetValue("albedo color", srgbColor4(color).getValue()); + childSetValue("base color", srgbColor4(color).getValue()); setTransparency(color.mV[3]); } @@ -370,7 +370,7 @@ void LLMaterialEditor::setHasUnsavedChanges(bool value) } S32 upload_texture_count = 0; - if (mAlbedoTextureUploadId.notNull() && mAlbedoTextureUploadId == getAlbedoId()) + if (mBaseColorTextureUploadId.notNull() && mBaseColorTextureUploadId == getBaseColorId()) { upload_texture_count++; } @@ -401,23 +401,23 @@ void LLMaterialEditor::setCanSave(BOOL value) childSetEnabled("save", value); } -void LLMaterialEditor::onCommitAlbedoTexture(LLUICtrl * ctrl, const LLSD & data) +void LLMaterialEditor::onCommitBaseColorTexture(LLUICtrl * ctrl, const LLSD & data) { // might be better to use arrays, to have a single callback // and not to repeat the same thing for each tecture control - LLUUID new_val = mAlbedoTextureCtrl->getValue().asUUID(); - if (new_val == mAlbedoTextureUploadId && mAlbedoTextureUploadId.notNull()) + LLUUID new_val = mBaseColorTextureCtrl->getValue().asUUID(); + if (new_val == mBaseColorTextureUploadId && mBaseColorTextureUploadId.notNull()) { - childSetValue("albedo_upload_fee", getString("upload_fee_string")); + childSetValue("base_color_upload_fee", getString("upload_fee_string")); } else { // Texture picker has 'apply now' with 'cancel' support. - // Keep mAlbedoJ2C and mAlbedoFetched, it's our storage in + // Keep mBaseColorJ2C and mBaseColorFetched, it's our storage in // case user decides to cancel changes. - // Without mAlbedoFetched, viewer will eventually cleanup + // Without mBaseColorFetched, viewer will eventually cleanup // the texture that is not in use - childSetValue("albedo_upload_fee", getString("no_upload_fee_string")); + childSetValue("base_color_upload_fee", getString("no_upload_fee_string")); } setHasUnsavedChanges(true); applyToSelection(); @@ -547,19 +547,19 @@ void LLMaterialEditor::getGLTFModel(tinygltf::Model& model) model.materials.resize(1); tinygltf::PbrMetallicRoughness& pbrMaterial = model.materials[0].pbrMetallicRoughness; - // write albedo - LLColor4 albedo_color = getAlbedoColor(); - albedo_color.mV[3] = getTransparency(); - write_color(albedo_color, pbrMaterial.baseColorFactor); + // write base color + LLColor4 base_color = getBaseColor(); + base_color.mV[3] = getTransparency(); + write_color(base_color, pbrMaterial.baseColorFactor); model.materials[0].alphaCutoff = getAlphaCutoff(); model.materials[0].alphaMode = getAlphaMode(); - LLUUID albedo_id = getAlbedoId(); + LLUUID base_color_id = getBaseColorId(); - if (albedo_id.notNull()) + if (base_color_id.notNull()) { - U32 texture_idx = write_texture(albedo_id, model); + U32 texture_idx = write_texture(base_color_id, model); pbrMaterial.baseColorTexture.index = texture_idx; } @@ -677,9 +677,9 @@ const std::string LLMaterialEditor::buildMaterialDescription() // control UUI for NULL is a valid metric for if it was loaded // or not but I suspect this code will change a lot so may need // to revisit - if (!mAlbedoTextureCtrl->getValue().asUUID().isNull()) + if (!mBaseColorTextureCtrl->getValue().asUUID().isNull()) { - desc << mAlbedoName; + desc << mBaseColorName; desc << ", "; } if (!mMetallicTextureCtrl->getValue().asUUID().isNull()) @@ -1050,22 +1050,22 @@ void LLMaterialFilePicker::notify(const std::vector& filenames) } static void pack_textures( - LLPointer& albedo_img, + LLPointer& base_color_img, LLPointer& normal_img, LLPointer& mr_img, LLPointer& emissive_img, LLPointer& occlusion_img, - LLPointer& albedo_j2c, + LLPointer& base_color_j2c, LLPointer& normal_j2c, LLPointer& mr_j2c, LLPointer& emissive_j2c) { // NOTE : remove log spam and lossless vs lossy comparisons when the logs are no longer useful - if (albedo_img) + if (base_color_img) { - albedo_j2c = LLViewerTextureList::convertToUploadFile(albedo_img); - LL_INFOS() << "Albedo: " << albedo_j2c->getDataSize() << LL_ENDL; + base_color_j2c = LLViewerTextureList::convertToUploadFile(base_color_img); + LL_INFOS() << "BaseColor: " << base_color_j2c->getDataSize() << LL_ENDL; } if (normal_img) @@ -1146,8 +1146,8 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename) model_out.asset.version = "2.0"; model_out.materials.resize(1); - // get albedo texture - LLPointer albedo_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.pbrMetallicRoughness.baseColorTexture.index, mAlbedoName); + // get base color texture + LLPointer base_color_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.pbrMetallicRoughness.baseColorTexture.index, mBaseColorName); // get normal map LLPointer normal_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.normalTexture.index, mNormalName); // get metallic-roughness texture @@ -1162,20 +1162,20 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename) occlusion_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.occlusionTexture.index, tmp); } - LLTinyGLTFHelper::initFetchedTextures(material_in, albedo_img, normal_img, mr_img, emissive_img, occlusion_img, - mAlbedoFetched, mNormalFetched, mMetallicRoughnessFetched, mEmissiveFetched); - pack_textures(albedo_img, normal_img, mr_img, emissive_img, occlusion_img, - mAlbedoJ2C, mNormalJ2C, mMetallicRoughnessJ2C, mEmissiveJ2C); + LLTinyGLTFHelper::initFetchedTextures(material_in, base_color_img, normal_img, mr_img, emissive_img, occlusion_img, + mBaseColorFetched, mNormalFetched, mMetallicRoughnessFetched, mEmissiveFetched); + pack_textures(base_color_img, normal_img, mr_img, emissive_img, occlusion_img, + mBaseColorJ2C, mNormalJ2C, mMetallicRoughnessJ2C, mEmissiveJ2C); - LLUUID albedo_id; - if (mAlbedoFetched.notNull()) + LLUUID base_color_id; + if (mBaseColorFetched.notNull()) { - mAlbedoFetched->forceToSaveRawImage(0, F32_MAX); - albedo_id = mAlbedoFetched->getID(); + mBaseColorFetched->forceToSaveRawImage(0, F32_MAX); + base_color_id = mBaseColorFetched->getID(); - if (mAlbedoName.empty()) + if (mBaseColorName.empty()) { - mAlbedoName = MATERIAL_ALBEDO_DEFAULT_NAME; + mBaseColorName = MATERIAL_BASE_COLOR_DEFAULT_NAME; } } @@ -1215,8 +1215,8 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename) } } - setAlbedoId(albedo_id); - setAlbedoUploadId(albedo_id); + setBaseColorId(base_color_id); + setBaseColorUploadId(base_color_id); setMetallicRoughnessId(mr_id); setMetallicRoughnessUploadId(mr_id); setEmissiveId(emissive_id); @@ -1245,16 +1245,16 @@ bool LLMaterialEditor::setFromGltfModel(tinygltf::Model& model, bool set_texture S32 index; LLUUID id; - // get albedo texture + // get base color texture index = material_in.pbrMetallicRoughness.baseColorTexture.index; if (index >= 0) { id.set(model.images[index].uri); - setAlbedoId(id); + setBaseColorId(id); } else { - setAlbedoId(LLUUID::null); + setBaseColorId(LLUUID::null); } // get normal map @@ -1297,7 +1297,7 @@ bool LLMaterialEditor::setFromGltfModel(tinygltf::Model& model, bool set_texture setAlphaMode(material_in.alphaMode); setAlphaCutoff(material_in.alphaCutoff); - setAlbedoColor(LLTinyGLTFHelper::getColor(material_in.pbrMetallicRoughness.baseColorFactor)); + setBaseColor(LLTinyGLTFHelper::getColor(material_in.pbrMetallicRoughness.baseColorFactor)); setEmissiveColor(LLTinyGLTFHelper::getColor(material_in.emissiveFactor)); setMetalnessFactor(material_in.pbrMetallicRoughness.metallicFactor); @@ -1331,7 +1331,7 @@ const std::string LLMaterialEditor::getImageNameFromUri(std::string image_uri, c stripped_uri = stripped_uri.substr(0, max_texture_name_length - 1); } - // We intend to append the type of texture (albedo, emissive etc.) to the + // We intend to append the type of texture (base color, emissive etc.) to the // name of the texture but sometimes the creator already did that. To try // to avoid repeats (not perfect), we look for the texture type in the name // and if we find it, do not append the type, later on. One way this fails @@ -1357,7 +1357,7 @@ const std::string LLMaterialEditor::getImageNameFromUri(std::string image_uri, c // so we can include everything if (stripped_uri.length() > 0) { - // example "DamagedHelmet: base layer (Albedo)" + // example "DamagedHelmet: base layer" return STRINGIZE( mMaterialNameShort << ": " << @@ -1476,17 +1476,17 @@ void LLMaterialEditor::setFromGltfMetaData(const std::string& filename, tinygltf { const tinygltf::Material& first_material = model.materials[0]; - mAlbedoName = MATERIAL_ALBEDO_DEFAULT_NAME; - // note: unlike the other textures, albedo doesn't have its own entry + mBaseColorName = MATERIAL_BASE_COLOR_DEFAULT_NAME; + // note: unlike the other textures, base color doesn't have its own entry // in the tinyGLTF Material struct. Rather, it is taken from a // sub-texture in the pbrMetallicRoughness member int index = first_material.pbrMetallicRoughness.baseColorTexture.index; if (index > -1 && index < model.images.size()) { // sanitize the name we decide to use for each texture - std::string texture_name = getImageNameFromUri(model.images[index].uri, MATERIAL_ALBEDO_DEFAULT_NAME); + std::string texture_name = getImageNameFromUri(model.images[index].uri, MATERIAL_BASE_COLOR_DEFAULT_NAME); LLInventoryObject::correctInventoryName(texture_name); - mAlbedoName = texture_name; + mBaseColorName = texture_name; } mEmissiveName = MATERIAL_EMISSIVE_DEFAULT_NAME; @@ -1559,9 +1559,9 @@ void LLMaterialEditor::applyToSelection() void LLMaterialEditor::getGLTFMaterial(LLGLTFMaterial* mat) { - mat->mAlbedoColor = getAlbedoColor(); - mat->mAlbedoColor.mV[3] = getTransparency(); - mat->mAlbedoId = getAlbedoId(); + mat->mBaseColor = getBaseColor(); + mat->mBaseColor.mV[3] = getTransparency(); + mat->mBaseColorId = getBaseColorId(); mat->mNormalId = getNormalId(); @@ -1579,8 +1579,8 @@ void LLMaterialEditor::getGLTFMaterial(LLGLTFMaterial* mat) void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat) { - setAlbedoColor(mat->mAlbedoColor); - setAlbedoId(mat->mAlbedoId); + setBaseColor(mat->mBaseColor); + setBaseColorId(mat->mBaseColorId); setNormalId(mat->mNormalId); setMetallicRoughnessId(mat->mMetallicRoughnessId); @@ -1801,23 +1801,23 @@ S32 LLMaterialEditor::saveTextures() { S32 work_count = 0; LLSD key = getKey(); // must be locally declared for lambda's capture to work - if (mAlbedoTextureUploadId == getAlbedoId() && mAlbedoTextureUploadId.notNull()) + if (mBaseColorTextureUploadId == getBaseColorId() && mBaseColorTextureUploadId.notNull()) { mUploadingTexturesCount++; work_count++; - saveTexture(mAlbedoJ2C, mAlbedoName, mAlbedoTextureUploadId, [key](LLUUID newAssetId, LLSD response) + saveTexture(mBaseColorJ2C, mBaseColorName, mBaseColorTextureUploadId, [key](LLUUID newAssetId, LLSD response) { LLMaterialEditor* me = LLFloaterReg::findTypedInstance("material_editor", key); if (me) { if (response["success"].asBoolean()) { - me->setAlbedoId(newAssetId); + me->setBaseColorId(newAssetId); } else { // To make sure that we won't retry (some failures can cb immediately) - me->setAlbedoId(LLUUID::null); + me->setBaseColorId(LLUUID::null); } me->mUploadingTexturesCount--; @@ -1902,17 +1902,17 @@ S32 LLMaterialEditor::saveTextures() } // discard upload buffers once textures have been saved - mAlbedoJ2C = nullptr; + mBaseColorJ2C = nullptr; mNormalJ2C = nullptr; mEmissiveJ2C = nullptr; mMetallicRoughnessJ2C = nullptr; - mAlbedoFetched = nullptr; + mBaseColorFetched = nullptr; mNormalFetched = nullptr; mMetallicRoughnessFetched = nullptr; mEmissiveFetched = nullptr; - mAlbedoTextureUploadId.setNull(); + mBaseColorTextureUploadId.setNull(); mNormalTextureUploadId.setNull(); mMetallicTextureUploadId.setNull(); mEmissiveTextureUploadId.setNull(); -- cgit v1.2.3 From 30b6d29b042f6f9a5054d80cad26960b83d8472b Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 26 Sep 2022 23:23:52 +0300 Subject: SL-17640 Material editor permissions support --- indra/newview/llmaterialeditor.cpp | 43 ++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 12d21cf284..a0ab771c7b 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -149,6 +149,8 @@ BOOL LLMaterialEditor::postBuild() childSetVisible("unsaved_changes", mHasUnsavedChanges); + getChild("total_upload_fee")->setTextArg("[FEE]", llformat("%d", 0)); + // Todo: // Disable/enable setCanApplyImmediately() based on // working from inventory, upload or editing inworld @@ -391,16 +393,43 @@ void LLMaterialEditor::setHasUnsavedChanges(bool value) getChild("total_upload_fee")->setTextArg("[FEE]", llformat("%d", mExpectedUploadCost)); } -void LLMaterialEditor::setCanSaveAs(BOOL value) +void LLMaterialEditor::setCanSaveAs(bool value) { childSetEnabled("save_as", value); } -void LLMaterialEditor::setCanSave(BOOL value) +void LLMaterialEditor::setCanSave(bool value) { childSetEnabled("save", value); } +void LLMaterialEditor::setEnableEditing(bool can_modify) +{ + childSetEnabled("double sided", can_modify); + + // BaseColor + childSetEnabled("base color", can_modify); + childSetEnabled("transparency", can_modify); + childSetEnabled("alpha mode", can_modify); + childSetEnabled("alpha cutoff", can_modify); + + // Metallic-Roughness + childSetEnabled("metalness factor", can_modify); + childSetEnabled("roughness factor", can_modify); + + // Metallic-Roughness + childSetEnabled("metalness factor", can_modify); + childSetEnabled("roughness factor", can_modify); + + // Emissive + childSetEnabled("emissive color", can_modify); + + mBaseColorTextureCtrl->setEnabled(can_modify); + mMetallicTextureCtrl->setEnabled(can_modify); + mEmissiveTextureCtrl->setEnabled(can_modify); + mNormalTextureCtrl->setEnabled(can_modify); +} + void LLMaterialEditor::onCommitBaseColorTexture(LLUICtrl * ctrl, const LLSD & data) { // might be better to use arrays, to have a single callback @@ -1624,6 +1653,7 @@ void LLMaterialEditor::loadAsset() mAssetStatus = PREVIEW_ASSET_LOADED; loadDefaults(); setHasUnsavedChanges(false); + setEnableEditing(allow_modify && !source_library); } else { @@ -1644,6 +1674,7 @@ void LLMaterialEditor::loadAsset() mAssetID.setNull(); mAssetStatus = PREVIEW_ASSET_LOADED; setHasUnsavedChanges(false); + setEnableEditing(allow_modify && !source_library); return; } user_data->with("taskid", mObjectUUID).with("itemid", mItemUUID); @@ -1653,6 +1684,8 @@ void LLMaterialEditor::loadAsset() user_data = new LLSD(mItemUUID); } + setEnableEditing(false); // wait for it to load + gAssetStorage->getInvItemAsset(source_sim, gAgent.getID(), gAgent.getSessionID(), @@ -1724,8 +1757,9 @@ void LLMaterialEditor::onLoadComplete(const LLUUID& asset_uuid, editor->decodeAsset(buffer); - BOOL modifiable = editor->canModify(editor->mObjectID, editor->getItem()); - editor->setEnabled(modifiable); + BOOL allow_modify = editor->canModify(editor->mObjectID, editor->getItem()); + BOOL source_library = editor->mObjectID.isNull() && gInventory.isObjectDescendentOf(editor->mItemUUID, gInventory.getLibraryRootFolderID()); + editor->setEnableEditing(allow_modify && !source_library); editor->setHasUnsavedChanges(false); editor->mAssetStatus = PREVIEW_ASSET_LOADED; } @@ -1744,6 +1778,7 @@ void LLMaterialEditor::onLoadComplete(const LLUUID& asset_uuid, { LLNotificationsUtil::add("UnableToLoadMaterial"); } + editor->setEnableEditing(false); LL_WARNS() << "Problem loading material: " << status << LL_ENDL; editor->mAssetStatus = PREVIEW_ASSET_ERROR; -- cgit v1.2.3 From 3e59ae1c43a70f41fba9cf6ba7d33aeed22d3a9f Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 27 Sep 2022 17:59:27 +0300 Subject: SL-17640 Support loading materials from multi-material files --- indra/newview/llmaterialeditor.cpp | 167 ++++++++++++++++++++++++++++++++----- 1 file changed, 144 insertions(+), 23 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index a0ab771c7b..4f51030fc0 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -65,6 +65,87 @@ const std::string MATERIAL_NORMAL_DEFAULT_NAME = "Normal"; const std::string MATERIAL_METALLIC_DEFAULT_NAME = "Metallic Roughness"; const std::string MATERIAL_EMISSIVE_DEFAULT_NAME = "Emissive"; +LLFloaterComboOptions::LLFloaterComboOptions() + : LLFloater(LLSD()) +{ + buildFromFile("floater_combobox_ok_cancel.xml"); +} + +LLFloaterComboOptions::~LLFloaterComboOptions() +{ + +} + +BOOL LLFloaterComboOptions::postBuild() +{ + mConfirmButton = getChild("combo_ok", TRUE); + mCancelButton = getChild("combo_cancel", TRUE); + mComboOptions = getChild("combo_options", TRUE); + mComboText = getChild("combo_text", TRUE); + + mConfirmButton->setCommitCallback([this](LLUICtrl* ctrl, const LLSD& param) {onConfirm(); }); + mCancelButton->setCommitCallback([this](LLUICtrl* ctrl, const LLSD& param) {onCancel(); }); + + return TRUE; +} + +LLFloaterComboOptions* LLFloaterComboOptions::showUI( + combo_callback callback, + const std::string &title, + const std::string &description, + const std::list &options) +{ + LLFloaterComboOptions* combo_picker = new LLFloaterComboOptions(); + if (combo_picker) + { + combo_picker->mCallback = callback; + combo_picker->setTitle(title); + + combo_picker->mComboText->setText(description); + + std::list::const_iterator iter = options.begin(); + std::list::const_iterator end = options.end(); + for (; iter != end; iter++) + { + combo_picker->mComboOptions->addSimpleElement(*iter); + } + combo_picker->mComboOptions->selectFirstItem(); + + combo_picker->openFloater(LLSD(title)); + combo_picker->setFocus(TRUE); + combo_picker->center(); + } + return combo_picker; +} + +LLFloaterComboOptions* LLFloaterComboOptions::showUI( + combo_callback callback, + const std::string &title, + const std::string &description, + const std::string &ok_text, + const std::string &cancel_text, + const std::list &options) +{ + LLFloaterComboOptions* combo_picker = showUI(callback, title, description, options); + if (combo_picker) + { + combo_picker->mConfirmButton->setLabel(ok_text); + combo_picker->mCancelButton->setLabel(cancel_text); + } + return combo_picker; +} + +void LLFloaterComboOptions::onConfirm() +{ + mCallback(mComboOptions->getSimple(), mComboOptions->getCurrentIndex()); + closeFloater(); +} + +void LLFloaterComboOptions::onCancel() +{ + mCallback(std::string(), -1); + closeFloater(); +} class LLMaterialEditorCopiedCallback : public LLInventoryCallback { @@ -1129,7 +1210,6 @@ void LLMaterialFilePicker::textureLoadedCallback(BOOL success, LLViewerFetchedTe { } - void LLMaterialEditor::loadMaterialFromFile(const std::string& filename) { tinygltf::TinyGLTF loader; @@ -1166,10 +1246,48 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename) return; } - std::string folder = gDirUtilp->getDirName(filename); + if (model_in.materials.size() == 1) + { + loadMaterial(model_in, filename_lc, 0); + } + else + { + std::list material_list; + std::vector::const_iterator mat_iter = model_in.materials.begin(); + std::vector::const_iterator mat_end = model_in.materials.end(); + for (; mat_iter != mat_end; mat_iter++) + { + std::string mat_name = mat_iter->name; + if (mat_name.empty()) + { + material_list.push_back("Material " + std::to_string(material_list.size())); + } + else + { + material_list.push_back(mat_name); + } + } + LLFloaterComboOptions::showUI( + [this, model_in, filename_lc](const std::string& option, S32 index) + { + loadMaterial(model_in, filename_lc, index); + }, + getString("material_selection_title"), + getString("material_selection_text"), + material_list + ); + } +} +void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std::string &filename_lc, S32 index) +{ + if (model_in.materials.size() < index) + { + return; + } + std::string folder = gDirUtilp->getDirName(filename_lc); - tinygltf::Material material_in = model_in.materials[0]; + tinygltf::Material material_in = model_in.materials[index]; tinygltf::Model model_out; model_out.asset.version = "2.0"; @@ -1195,13 +1313,13 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename) mBaseColorFetched, mNormalFetched, mMetallicRoughnessFetched, mEmissiveFetched); pack_textures(base_color_img, normal_img, mr_img, emissive_img, occlusion_img, mBaseColorJ2C, mNormalJ2C, mMetallicRoughnessJ2C, mEmissiveJ2C); - + LLUUID base_color_id; if (mBaseColorFetched.notNull()) { mBaseColorFetched->forceToSaveRawImage(0, F32_MAX); base_color_id = mBaseColorFetched->getID(); - + if (mBaseColorName.empty()) { mBaseColorName = MATERIAL_BASE_COLOR_DEFAULT_NAME; @@ -1253,9 +1371,9 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename) setNormalId(normal_id); setNormalUploadId(normal_id); - setFromGltfModel(model_in); + setFromGltfModel(model_in, index); - setFromGltfMetaData(filename_lc, model_in); + setFromGltfMetaData(filename_lc, model_in, index); setHasUnsavedChanges(true); openFloater(); @@ -1263,11 +1381,11 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename) applyToSelection(); } -bool LLMaterialEditor::setFromGltfModel(tinygltf::Model& model, bool set_textures) +bool LLMaterialEditor::setFromGltfModel(const tinygltf::Model& model, S32 index, bool set_textures) { - if (model.materials.size() > 0) + if (model.materials.size() > index) { - tinygltf::Material& material_in = model.materials[0]; + const tinygltf::Material& material_in = model.materials[index]; if (set_textures) { @@ -1429,7 +1547,7 @@ const std::string LLMaterialEditor::getImageNameFromUri(std::string image_uri, c * the name of the material, a material description and the names of the * composite textures. */ -void LLMaterialEditor::setFromGltfMetaData(const std::string& filename, tinygltf::Model& model) +void LLMaterialEditor::setFromGltfMetaData(const std::string& filename, const tinygltf::Model& model, S32 index) { // Use the name (without any path/extension) of the file that was // uploaded as the base of the material name. Then if the name of the @@ -1443,13 +1561,17 @@ void LLMaterialEditor::setFromGltfMetaData(const std::string& filename, tinygltf // Extract the name of the scene. Note it is often blank or some very // generic name like "Scene" or "Default" so using this in the name // is less useful than you might imagine. - std::string scene_name; - if (model.scenes.size() > 0) + std::string material_name; + if (model.materials.size() > index && !model.materials[index].name.empty()) + { + material_name = model.materials[index].name; + } + else if (model.scenes.size() > 0) { - tinygltf::Scene& scene_in = model.scenes[0]; + const tinygltf::Scene& scene_in = model.scenes[0]; if (scene_in.name.length()) { - scene_name = scene_in.name; + material_name = scene_in.name; } else { @@ -1461,13 +1583,13 @@ void LLMaterialEditor::setFromGltfMetaData(const std::string& filename, tinygltf // scene name isn't present so no point using it } - // If we have a valid scene name, use it to build the short and + // If we have a valid material or scene name, use it to build the short and // long versions of the material name. The long version is used // as you might expect, for the material name. The short version is // used as part of the image/texture name - the theory is that will // allow content creators to track the material and the corresponding // textures - if (scene_name.length()) + if (material_name.length()) { mMaterialNameShort = base_filename; @@ -1475,7 +1597,7 @@ void LLMaterialEditor::setFromGltfMetaData(const std::string& filename, tinygltf base_filename << " " << "(" << - scene_name << + material_name << ")" ); } @@ -1496,14 +1618,13 @@ void LLMaterialEditor::setFromGltfMetaData(const std::string& filename, tinygltf /** * Extract / derive the names of each composite texture. For each, the - * index in the first material (we only support 1 material currently) is - * used to to determine which of the "Images" is used. If the index is -1 - * then that texture type is not present in the material (Seems to be + * index is used to to determine which of the "Images" is used. If the index + * is -1 then that texture type is not present in the material (Seems to be * quite common that a material is missing 1 or more types of texture) */ - if (model.materials.size() > 0) + if (model.materials.size() > index) { - const tinygltf::Material& first_material = model.materials[0]; + const tinygltf::Material& first_material = model.materials[index]; mBaseColorName = MATERIAL_BASE_COLOR_DEFAULT_NAME; // note: unlike the other textures, base color doesn't have its own entry -- cgit v1.2.3 From 6b46793771a1d1db1601105604ac7bc82f8db7b3 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 28 Sep 2022 20:01:06 +0300 Subject: SL-18233 Double clicking material in an object shows notecard --- indra/newview/llmaterialeditor.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 4f51030fc0..1592235dba 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -180,6 +180,16 @@ LLMaterialEditor::LLMaterialEditor(const LLSD& key) } } +void LLMaterialEditor::setObjectID(const LLUUID& object_id) +{ + LLPreview::setObjectID(object_id); + const LLInventoryItem* item = getItem(); + if (item) + { + mAssetID = item->getAssetUUID(); + } +} + BOOL LLMaterialEditor::postBuild() { mBaseColorTextureCtrl = getChild("base_color_texture"); @@ -751,7 +761,8 @@ bool LLMaterialEditor::decodeAsset(const std::vector& buffer) if (loader.LoadASCIIFromString(&model_in, &error_msg, &warn_msg, data.c_str(), data.length(), "")) { - return setFromGltfModel(model_in, true); + // assets are only supposed to have one item + return setFromGltfModel(model_in, 0, true); } else { @@ -1878,8 +1889,8 @@ void LLMaterialEditor::onLoadComplete(const LLUUID& asset_uuid, editor->decodeAsset(buffer); - BOOL allow_modify = editor->canModify(editor->mObjectID, editor->getItem()); - BOOL source_library = editor->mObjectID.isNull() && gInventory.isObjectDescendentOf(editor->mItemUUID, gInventory.getLibraryRootFolderID()); + BOOL allow_modify = editor->canModify(editor->mObjectUUID, editor->getItem()); + BOOL source_library = editor->mObjectUUID.isNull() && gInventory.isObjectDescendentOf(editor->mItemUUID, gInventory.getLibraryRootFolderID()); editor->setEnableEditing(allow_modify && !source_library); editor->setHasUnsavedChanges(false); editor->mAssetStatus = PREVIEW_ASSET_LOADED; @@ -2083,5 +2094,5 @@ void LLMaterialEditor::loadDefaults() { tinygltf::Model model_in; model_in.materials.resize(1); - setFromGltfModel(model_in, true); + setFromGltfModel(model_in, 0, true); } -- cgit v1.2.3 From 144fb0c315b5db9ddb275110ca923965ff8bbb49 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 28 Sep 2022 20:18:21 +0300 Subject: SL-18233 Fixed editor not udpating after saving material from task inventory --- indra/newview/llmaterialeditor.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 1592235dba..3245c6629a 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1007,11 +1007,15 @@ void LLMaterialEditor::finishInventoryUpload(LLUUID itemId, LLUUID newAssetId, L void LLMaterialEditor::finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID taskId) { - LLMaterialEditor* me = LLFloaterReg::findTypedInstance("material_editor", LLSD(itemId)); + LLSD floater_key; + floater_key["taskid"] = taskId; + floater_key["itemid"] = itemId; + LLMaterialEditor* me = LLFloaterReg::findTypedInstance("material_editor", floater_key); if (me) { me->setAssetId(newAssetId); me->refreshFromInventory(); + me->setEnabled(true); } } @@ -1048,7 +1052,17 @@ void LLMaterialEditor::refreshFromInventory(const LLUUID& new_item_id) if (new_item_id.notNull()) { mItemUUID = new_item_id; - setKey(LLSD(new_item_id)); + if (mObjectUUID.isNull()) + { + setKey(LLSD(new_item_id)); + } + else + { + LLSD floater_key; + floater_key["taskid"] = new_item_id; + floater_key["itemid"] = mObjectUUID; + setKey(floater_key); + } } LL_DEBUGS() << "LLPreviewNotecard::refreshFromInventory()" << LL_ENDL; loadAsset(); -- cgit v1.2.3 From 411aa9f727efba971c8577cef4d6a31f096a6fea Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 29 Sep 2022 00:19:52 -0500 Subject: SL-18190 Fix for haze color being completely wrong (now it's just half wrong). --- indra/newview/llmaterialeditor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 3245c6629a..27694e9ce4 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -413,12 +413,12 @@ void LLMaterialEditor::setEmissiveUploadId(const LLUUID& id) LLColor4 LLMaterialEditor::getEmissiveColor() { - return LLColor4(childGetValue("emissive color")); + return linearColor4(LLColor4(childGetValue("emissive color"))); } void LLMaterialEditor::setEmissiveColor(const LLColor4& color) { - childSetValue("emissive color", color.getValue()); + childSetValue("emissive color", srgbColor4(color).getValue()); } LLUUID LLMaterialEditor::getNormalId() -- cgit v1.2.3 From 9346b45188462056698083f4f83fe8fecbe19bdf Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 29 Sep 2022 22:38:40 +0300 Subject: SL-17653 Multi-material file support for local materials --- indra/newview/llmaterialeditor.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 27694e9ce4..7270317b8c 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1176,6 +1176,8 @@ void LLMaterialFilePicker::notify(const std::vector& filenames) if (filenames.size() > 0) { + // Todo: there is no point creating LLMaterialEditor before + // loading material, just creates unnessesary work if decode fails LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor"); if (me) { @@ -1235,7 +1237,7 @@ void LLMaterialFilePicker::textureLoadedCallback(BOOL success, LLViewerFetchedTe { } -void LLMaterialEditor::loadMaterialFromFile(const std::string& filename) +void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 index) { tinygltf::TinyGLTF loader; std::string error_msg; @@ -1264,19 +1266,26 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename) return; } - if (model_in.materials.empty()) + if (model_in.materials.empty() || (index >= model_in.materials.size())) { // materials are missing LLNotificationsUtil::add("CannotUploadMaterial"); return; } - if (model_in.materials.size() == 1) + if (index >= 0) { + // Prespecified material + loadMaterial(model_in, filename_lc, index); + } + else if (model_in.materials.size() == 1) + { + // Only one, just load it loadMaterial(model_in, filename_lc, 0); } else { + // Promt user to select material std::list material_list; std::vector::const_iterator mat_iter = model_in.materials.begin(); std::vector::const_iterator mat_end = model_in.materials.end(); -- cgit v1.2.3 From 332ddc67de2de245a52d9db3be20f4ba8051f166 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 29 Sep 2022 23:17:49 +0300 Subject: SL-17653 Small change in material loading order --- indra/newview/llmaterialeditor.cpp | 80 ++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 47 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 7270317b8c..a72d38223f 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1152,40 +1152,6 @@ void LLMaterialEditor::onCancelMsgCallback(const LLSD& notification, const LLSD& } } -class LLMaterialFilePicker : public LLFilePickerThread -{ -public: - LLMaterialFilePicker(); - virtual void notify(const std::vector& filenames); - static void textureLoadedCallback(BOOL success, LLViewerFetchedTexture* src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata); - -}; - -LLMaterialFilePicker::LLMaterialFilePicker() - : LLFilePickerThread(LLFilePicker::FFLOAD_MATERIAL) -{ -} - -void LLMaterialFilePicker::notify(const std::vector& filenames) -{ - if (LLAppViewer::instance()->quitRequested()) - { - return; - } - - - if (filenames.size() > 0) - { - // Todo: there is no point creating LLMaterialEditor before - // loading material, just creates unnessesary work if decode fails - LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor"); - if (me) - { - me->loadMaterialFromFile(filenames[0]); - } - } -} - static void pack_textures( LLPointer& base_color_img, LLPointer& normal_img, @@ -1233,10 +1199,6 @@ static void pack_textures( } } -void LLMaterialFilePicker::textureLoadedCallback(BOOL success, LLViewerFetchedTexture* src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata) -{ -} - void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 index) { tinygltf::TinyGLTF loader; @@ -1266,22 +1228,31 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind return; } - if (model_in.materials.empty() || (index >= model_in.materials.size())) + if (model_in.materials.empty()) { // materials are missing LLNotificationsUtil::add("CannotUploadMaterial"); return; } + if (index >= 0 && model_in.materials.size() <= index) + { + // material is missing + LLNotificationsUtil::add("CannotUploadMaterial"); + return; + } + + LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor"); + if (index >= 0) { // Prespecified material - loadMaterial(model_in, filename_lc, index); + me->loadMaterial(model_in, filename_lc, index); } else if (model_in.materials.size() == 1) { // Only one, just load it - loadMaterial(model_in, filename_lc, 0); + me->loadMaterial(model_in, filename_lc, 0); } else { @@ -1302,12 +1273,12 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind } } LLFloaterComboOptions::showUI( - [this, model_in, filename_lc](const std::string& option, S32 index) + [me, model_in, filename_lc](const std::string& option, S32 index) { - loadMaterial(model_in, filename_lc, index); + me->loadMaterial(model_in, filename_lc, index); }, - getString("material_selection_title"), - getString("material_selection_text"), + me->getString("material_selection_title"), + me->getString("material_selection_text"), material_list ); } @@ -1315,7 +1286,7 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std::string &filename_lc, S32 index) { - if (model_in.materials.size() < index) + if (model_in.materials.size() <= index) { return; } @@ -1410,7 +1381,9 @@ void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std:: setFromGltfMetaData(filename_lc, model_in, index); setHasUnsavedChanges(true); + openFloater(); + setFocus(TRUE); applyToSelection(); } @@ -1704,7 +1677,20 @@ void LLMaterialEditor::setFromGltfMetaData(const std::string& filename, const ti void LLMaterialEditor::importMaterial() { - (new LLMaterialFilePicker())->getFile(); + LLFilePickerReplyThread::startPicker( + [](const std::vector& filenames, LLFilePicker::ELoadFilter load_filter, LLFilePicker::ESaveFilter save_filter) + { + if (LLAppViewer::instance()->quitRequested()) + { + return; + } + if (filenames.size() > 0) + { + LLMaterialEditor::loadMaterialFromFile(filenames[0], -1); + } + }, + LLFilePicker::FFLOAD_MATERIAL, + true); } class LLRemderMaterialFunctor : public LLSelectedTEFunctor -- cgit v1.2.3 From 1a437cbedf94de90d749f426dde09f2466693de2 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 4 Oct 2022 20:33:10 +0300 Subject: SL-18144 Bakes On Mesh not showing in-world as Albedo --- indra/newview/llmaterialeditor.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index a72d38223f..a2cd68259b 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1903,6 +1903,7 @@ void LLMaterialEditor::onLoadComplete(const LLUUID& asset_uuid, editor->setEnableEditing(allow_modify && !source_library); editor->setHasUnsavedChanges(false); editor->mAssetStatus = PREVIEW_ASSET_LOADED; + editor->setEnabled(true); // ready for use } else { -- cgit v1.2.3 From 2fa8bce1cffe932089a05ad1c7834bb20b435fcf Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 7 Oct 2022 23:46:01 +0300 Subject: SL-18326 GLTF material functionality in a Notecard --- indra/newview/llmaterialeditor.cpp | 166 ++++++++++++++++++++++++++++++------- 1 file changed, 136 insertions(+), 30 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index a2cd68259b..27b5d508e0 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1,6 +1,6 @@ /** * @file llmaterialeditor.cpp - * @brief Implementation of the notecard editor + * @brief Implementation of the gltf material editor * * $LicenseInfo:firstyear=2022&license=viewerlgpl$ * Second Life Viewer Source Code @@ -150,16 +150,44 @@ void LLFloaterComboOptions::onCancel() class LLMaterialEditorCopiedCallback : public LLInventoryCallback { public: - LLMaterialEditorCopiedCallback(const std::string &buffer, const LLUUID &old_item_id) : mBuffer(buffer), mOldItemId(old_item_id) {} + LLMaterialEditorCopiedCallback( + const std::string &buffer, + const LLSD &old_key, + bool has_unsaved_changes) + : mBuffer(buffer), + mOldKey(old_key), + mHasUnsavedChanges(has_unsaved_changes) + {} + + LLMaterialEditorCopiedCallback( + const LLSD &old_key, + const std::string &new_name) + : mOldKey(old_key), + mNewName(new_name), + mHasUnsavedChanges(false) + {} virtual void fire(const LLUUID& inv_item_id) { - LLMaterialEditor::finishSaveAs(mOldItemId, inv_item_id, mBuffer); + if (!mNewName.empty()) + { + // making a copy from a notecard doesn't change name, do it now + LLViewerInventoryItem* item = gInventory.getItem(inv_item_id); + if (item->getName() != mNewName) + { + LLSD updates; + updates["name"] = mNewName; + update_inventory_item(inv_item_id, updates, NULL); + } + } + LLMaterialEditor::finishSaveAs(mOldKey, inv_item_id, mBuffer, mHasUnsavedChanges); } private: std::string mBuffer; - LLUUID mOldItemId; + LLSD mOldKey; + std::string mNewName; + bool mHasUnsavedChanges; }; ///---------------------------------------------------------------------------- @@ -190,6 +218,15 @@ void LLMaterialEditor::setObjectID(const LLUUID& object_id) } } +void LLMaterialEditor::setAuxItem(const LLInventoryItem* item) +{ + LLPreview::setAuxItem(item); + if (item) + { + mAssetID = item->getAssetUUID(); + } +} + BOOL LLMaterialEditor::postBuild() { mBaseColorTextureCtrl = getChild("base_color_texture"); @@ -456,10 +493,25 @@ void LLMaterialEditor::setDoubleSided(bool double_sided) void LLMaterialEditor::setHasUnsavedChanges(bool value) { - if (value != mHasUnsavedChanges) + mHasUnsavedChanges = value; + childSetVisible("unsaved_changes", value); + + if (mHasUnsavedChanges) { - mHasUnsavedChanges = value; - childSetVisible("unsaved_changes", value); + const LLInventoryItem* item = getItem(); + if (item) + { + LLPermissions perm(item->getPermissions()); + bool allow_modify = canModify(mObjectUUID, item); + bool source_library = mObjectUUID.isNull() && gInventory.isObjectDescendentOf(mItemUUID, gInventory.getLibraryRootFolderID()); + bool source_notecard = mNotecardInventoryID.notNull(); + + setCanSave(allow_modify && !source_library && !source_notecard); + } + } + else + { + setCanSave(false); } S32 upload_texture_count = 0; @@ -1019,23 +1071,39 @@ void LLMaterialEditor::finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID } } -void LLMaterialEditor::finishSaveAs(const LLUUID &oldItemId, const LLUUID &newItemId, const std::string &buffer) +void LLMaterialEditor::finishSaveAs( + const LLSD &oldKey, + const LLUUID &newItemId, + const std::string &buffer, + bool has_unsaved_changes) { - LLMaterialEditor* me = LLFloaterReg::findTypedInstance("material_editor", LLSD(oldItemId)); + LLMaterialEditor* me = LLFloaterReg::findTypedInstance("material_editor", oldKey); LLViewerInventoryItem* item = gInventory.getItem(newItemId); if (item) { if (me) { me->mItemUUID = newItemId; + me->mObjectUUID = LLUUID::null; + me->mNotecardInventoryID = LLUUID::null; + me->mNotecardObjectID = LLUUID::null; + me->mAuxItem = nullptr; me->setKey(LLSD(newItemId)); // for findTypedInstance me->setMaterialName(item->getName()); - if (!saveToInventoryItem(buffer, newItemId, LLUUID::null)) + if (has_unsaved_changes) { + if (!saveToInventoryItem(buffer, newItemId, LLUUID::null)) + { + me->setEnabled(true); + } + } + else + { + me->loadAsset(); me->setEnabled(true); } } - else + else if(has_unsaved_changes) { saveToInventoryItem(buffer, newItemId, LLUUID::null); } @@ -1052,17 +1120,24 @@ void LLMaterialEditor::refreshFromInventory(const LLUUID& new_item_id) if (new_item_id.notNull()) { mItemUUID = new_item_id; - if (mObjectUUID.isNull()) + if (mNotecardInventoryID.notNull()) { - setKey(LLSD(new_item_id)); + LLSD floater_key; + floater_key["objectid"] = mNotecardObjectID; + floater_key["notecardid"] = mNotecardInventoryID; + setKey(floater_key); } - else + else if (mObjectUUID.notNull()) { LLSD floater_key; floater_key["taskid"] = new_item_id; floater_key["itemid"] = mObjectUUID; setKey(floater_key); } + else + { + setKey(LLSD(new_item_id)); + } } LL_DEBUGS() << "LLPreviewNotecard::refreshFromInventory()" << LL_ENDL; loadAsset(); @@ -1094,7 +1169,15 @@ void LLMaterialEditor::onSaveAsMsgCallback(const LLSD& notification, const LLSD& LLInventoryObject::correctInventoryName(new_name); if (!new_name.empty()) { - const LLInventoryItem* item = getItem(); + const LLInventoryItem* item; + if (mNotecardInventoryID.notNull()) + { + item = mAuxItem.get(); + } + else + { + item = getItem(); + } if (item) { const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); @@ -1105,15 +1188,27 @@ void LLMaterialEditor::onSaveAsMsgCallback(const LLSD& notification, const LLSD& } // A two step process, first copy an existing item, then create new asset - std::string buffer = getEncodedAsset(); - LLPointer cb = new LLMaterialEditorCopiedCallback(buffer, item->getUUID()); - copy_inventory_item( - gAgent.getID(), - item->getPermissions().getOwner(), - item->getUUID(), - parent_id, - new_name, - cb); + if (mNotecardInventoryID.notNull()) + { + LLPointer cb = new LLMaterialEditorCopiedCallback(getKey(), new_name); + copy_inventory_from_notecard(parent_id, + mNotecardObjectID, + mNotecardInventoryID, + mAuxItem.get(), + gInventoryCallbacks.registerCB(cb)); + } + else + { + std::string buffer = getEncodedAsset(); + LLPointer cb = new LLMaterialEditorCopiedCallback(buffer, getKey(), mHasUnsavedChanges); + copy_inventory_item( + gAgent.getID(), + item->getPermissions().getOwner(), + item->getUUID(), + parent_id, + new_name, + cb); + } mAssetStatus = PREVIEW_ASSET_LOADING; setEnabled(false); @@ -1772,19 +1867,26 @@ void LLMaterialEditor::loadAsset() // TODO: see commented out "editor" references and make them do something appropriate to the UI // request the asset. - const LLInventoryItem* item = getItem(); + const LLInventoryItem* item; + if (mNotecardInventoryID.notNull()) + { + item = mAuxItem.get(); + } + else + { + item = getItem(); + } bool fail = false; if (item) { LLPermissions perm(item->getPermissions()); - BOOL allow_copy = gAgent.allowOperation(PERM_COPY, perm, GP_OBJECT_MANIPULATE); - BOOL allow_modify = canModify(mObjectUUID, item); - BOOL source_library = mObjectUUID.isNull() && gInventory.isObjectDescendentOf(mItemUUID, gInventory.getLibraryRootFolderID()); + bool allow_copy = gAgent.allowOperation(PERM_COPY, perm, GP_OBJECT_MANIPULATE); + bool allow_modify = canModify(mObjectUUID, item); + bool source_library = mObjectUUID.isNull() && gInventory.isObjectDescendentOf(mItemUUID, gInventory.getLibraryRootFolderID()); setCanSaveAs(allow_copy); - setCanSave(allow_modify && !source_library); setMaterialName(item->getName()); { @@ -1801,7 +1903,11 @@ void LLMaterialEditor::loadAsset() LLHost source_sim = LLHost(); LLSD* user_data = new LLSD(); - if (mObjectUUID.notNull()) + if (mNotecardInventoryID.notNull()) + { + user_data->with("objectid", mNotecardObjectID).with("notecardid", mNotecardInventoryID); + } + else if (mObjectUUID.notNull()) { LLViewerObject* objectp = gObjectList.findObject(mObjectUUID); if (objectp && objectp->getRegion()) -- cgit v1.2.3 From 3514ab73bd30c70f8b730ee06e9ca08b48f8d3a2 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 12 Oct 2022 11:50:59 +0300 Subject: SL-18125 Material asset doesn't inherit some "uploads" permissions --- indra/newview/llmaterialeditor.cpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 27b5d508e0..dfb43dfe0d 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -941,7 +941,27 @@ bool LLMaterialEditor::saveIfNeeded() create_inventory_item(gAgent.getID(), gAgent.getSessionID(), parent, tid, mMaterialName, res_desc, LLAssetType::AT_MATERIAL, LLInventoryType::IT_MATERIAL, subtype, next_owner_perm, - new LLBoostFuncInventoryCallback([output = buffer](LLUUID const& inv_item_id) { + new LLBoostFuncInventoryCallback([output = buffer](LLUUID const& inv_item_id) + { + LLViewerInventoryItem* item = gInventory.getItem(inv_item_id); + if (item) + { + // create_inventory_item doesn't allow presetting some permissions, fix it now + LLPermissions perm = item->getPermissions(); + if (perm.getMaskEveryone() != LLFloaterPerms::getEveryonePerms("Uploads") + || perm.getMaskGroup() != LLFloaterPerms::getGroupPerms("Uploads")) + { + perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Uploads")); + perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Uploads")); + + item->setPermissions(perm); + + item->updateServer(FALSE); + gInventory.updateItem(item); + gInventory.notifyObservers(); + } + } + // from reference in LLSettingsVOBase::createInventoryItem()/updateInventoryItem() LLResourceUploadInfo::ptr_t uploadInfo = std::make_shared( @@ -966,7 +986,7 @@ bool LLMaterialEditor::saveIfNeeded() } LLViewerAssetUpload::EnqueueInventoryUpload(agent_url, uploadInfo); } - }) + }) ); // We do not update floater with uploaded asset yet, so just close it. -- cgit v1.2.3 From 3d170fae5d528dfbecacc913fb68c870abbf9ce2 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 13 Oct 2022 21:01:35 +0300 Subject: SL-18125 Separate GLTF permissions from normal uploads --- indra/newview/llmaterialeditor.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index dfb43dfe0d..4a75426265 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -935,7 +935,7 @@ bool LLMaterialEditor::saveIfNeeded() tid.generate(); // timestamp-based randomization + uniquification LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); std::string res_desc = buildMaterialDescription(); - U32 next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Uploads"); + U32 next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Materials"); LLUUID parent = gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_MATERIAL); const U8 subtype = NO_INV_SUBTYPE; // TODO maybe use AT_SETTINGS and LLSettingsType::ST_MATERIAL ? @@ -948,11 +948,11 @@ bool LLMaterialEditor::saveIfNeeded() { // create_inventory_item doesn't allow presetting some permissions, fix it now LLPermissions perm = item->getPermissions(); - if (perm.getMaskEveryone() != LLFloaterPerms::getEveryonePerms("Uploads") - || perm.getMaskGroup() != LLFloaterPerms::getGroupPerms("Uploads")) + if (perm.getMaskEveryone() != LLFloaterPerms::getEveryonePerms("Materials") + || perm.getMaskGroup() != LLFloaterPerms::getGroupPerms("Materials")) { - perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Uploads")); - perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Uploads")); + perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Materials")); + perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Materials")); item->setPermissions(perm); -- cgit v1.2.3 From bda420662710e95de1b3f6ff954459b4bb6c3b01 Mon Sep 17 00:00:00 2001 From: "Brad Kittenbrink (Brad Linden)" Date: Mon, 10 Oct 2022 16:10:10 -0700 Subject: WIP for SL-18103 and SL-17697 live editing of materials using ModifyMaterialParams cap --- indra/newview/llmaterialeditor.cpp | 54 +++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 4a75426265..9738030e97 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -200,6 +200,8 @@ LLMaterialEditor::LLMaterialEditor(const LLSD& key) , mHasUnsavedChanges(false) , mExpectedUploadCost(0) , mUploadingTexturesCount(0) + , mOverrideObjectId(LLUUID::null) + , mOverrideFace(0) { const LLInventoryItem* item = getItem(); if (item) @@ -1832,6 +1834,7 @@ private: void LLMaterialEditor::applyToSelection() { +#if 0 // local preview placeholder hack // Placehodler. Will be removed once override systems gets finished. LLPointer mat = new LLGLTFMaterial(); getGLTFMaterial(mat); @@ -1839,7 +1842,19 @@ void LLMaterialEditor::applyToSelection() gGLTFMaterialList.addMaterial(placeholder, mat); LLRemderMaterialFunctor mat_func(placeholder); LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); - selected_objects->applyToTEs(&mat_func); + //selected_objects->applyToTEs(&mat_func); +#else + std::string url = gAgent.getRegionCapability("ModifyMaterialParams"); + if (!url.empty()) + { + LLSDMap overrides; + LLCoros::instance().launch("modifyMaterialCoro", std::bind(&LLMaterialEditor::modifyMaterialCoro, this, url, overrides)); + } + else + { + LL_WARNS() << "not connected to materials capable region, missing ModifyMaterialParams cap" << LL_ENDL; + } +#endif } void LLMaterialEditor::getGLTFMaterial(LLGLTFMaterial* mat) @@ -2232,3 +2247,40 @@ void LLMaterialEditor::loadDefaults() model_in.materials.resize(1); setFromGltfModel(model_in, 0, true); } + +void LLMaterialEditor::modifyMaterialCoro(std::string cap_url, LLSD overrides) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("modifyMaterialCoro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); + LLCore::HttpHeaders::ptr_t httpHeaders; + + httpOpts->setFollowRedirects(true); + LLSD body = llsd::map( + "local_id", mOverrideObjectId, + "face", mOverrideFace, + "overrides", overrides + ); + + LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, body, httpOpts, httpHeaders); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status) + { + LL_WARNS() << "Failed to modify material." << LL_ENDL; + } + else if (!result["success"].asBoolean()) + { + LL_WARNS() << "Failed to modify material: " << result["message"] << LL_ENDL; + } +} + +void LLMaterialEditor::setOverrideTarget(const LLUUID& object_id, S32 face) +{ + mOverrideObjectId = object_id; + mOverrideFace = face; +} -- cgit v1.2.3 From c6bb0fef90b0c2c6557b933b0bc57cabd66fa572 Mon Sep 17 00:00:00 2001 From: "Brad Kittenbrink (Brad Linden)" Date: Tue, 11 Oct 2022 18:08:15 -0700 Subject: Fix SL-17697 local_id usage --- indra/newview/llmaterialeditor.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 9738030e97..c23f9ec4e7 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -200,7 +200,7 @@ LLMaterialEditor::LLMaterialEditor(const LLSD& key) , mHasUnsavedChanges(false) , mExpectedUploadCost(0) , mUploadingTexturesCount(0) - , mOverrideObjectId(LLUUID::null) + , mOverrideLocalId(0) , mOverrideFace(0) { const LLInventoryItem* item = getItem(); @@ -2259,7 +2259,7 @@ void LLMaterialEditor::modifyMaterialCoro(std::string cap_url, LLSD overrides) httpOpts->setFollowRedirects(true); LLSD body = llsd::map( - "local_id", mOverrideObjectId, + "local_id", S32(mOverrideLocalId), "face", mOverrideFace, "overrides", overrides ); @@ -2279,8 +2279,8 @@ void LLMaterialEditor::modifyMaterialCoro(std::string cap_url, LLSD overrides) } } -void LLMaterialEditor::setOverrideTarget(const LLUUID& object_id, S32 face) +void LLMaterialEditor::setOverrideTarget(U32 local_id, S32 face) { - mOverrideObjectId = object_id; + mOverrideLocalId = local_id; mOverrideFace = face; } -- cgit v1.2.3 From a27e701530e3498f71b828d7639024330cd0ccb7 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 17 Oct 2022 23:33:27 +0300 Subject: SL-18008 Add Save and Edit buttons to right click menu for materials --- indra/newview/llmaterialeditor.cpp | 44 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index c23f9ec4e7..80a0583fd0 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1401,6 +1401,16 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind } } +void LLMaterialEditor::loadLiveMaterial(LLGLTFMaterial * material, bool make_copy) +{ + if (!material) + { + return; + } + LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor"); + me->loadMaterial(material, make_copy); +} + void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std::string &filename_lc, S32 index) { if (model_in.materials.size() <= index) @@ -1505,6 +1515,40 @@ void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std:: applyToSelection(); } +void LLMaterialEditor::loadMaterial(LLGLTFMaterial * material, bool make_copy) +{ + setBaseColorId(material->mBaseColorId); + setMetallicRoughnessId(material->mMetallicRoughnessId); + setEmissiveId(material->mEmissiveId); + setNormalId(material->mNormalId); + + setAlphaMode(material->getAlphaMode()); + setAlphaCutoff(material->mAlphaCutoff); + + setBaseColor(material->mBaseColor); + setEmissiveColor(material->mEmissiveColor); + + setMetalnessFactor(material->mMetallicFactor); + setRoughnessFactor(material->mRoughnessFactor); + + setDoubleSided(material->mDoubleSided); + + if (make_copy) + { + setTitle(LLTrans::getString("New Material")); + } + // else ??? Think of a name for live editing + + // Todo: At the moment it always makes a 'copy' + // Will need a way to expand existing material + // once overrides are done + + setHasUnsavedChanges(make_copy); + + openFloater(); + setFocus(TRUE); +} + bool LLMaterialEditor::setFromGltfModel(const tinygltf::Model& model, S32 index, bool set_textures) { if (model.materials.size() > index) -- cgit v1.2.3 From 77eba62335158db6b0c6c7966a26b956fd796da9 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 17 Oct 2022 23:55:59 +0300 Subject: SL-18008 Placeholder functionality for PBR Edit button --- indra/newview/llmaterialeditor.cpp | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 80a0583fd0..f1b015fc84 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1537,7 +1537,28 @@ void LLMaterialEditor::loadMaterial(LLGLTFMaterial * material, bool make_copy) { setTitle(LLTrans::getString("New Material")); } - // else ??? Think of a name for live editing + else + { + setTitle(getString("material_override_title")); + // TODO: Save whole selection + + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); + LLViewerObject* object = selection->getFirstNode()->getObject(); + if (object) + { + const S32 num_tes = llmin((S32)object->getNumTEs(), (S32)object->getNumFaces()); // avatars have TEs but no faces + for (S32 face = 0; face < num_tes; ++face) + { + LLTextureEntry *te = object->getTE(face); + if (te->isSelected()) + { + // TEMP + setOverrideTarget(object->getLocalID(), face); + break; + } + } + } + } // Todo: At the moment it always makes a 'copy' // Will need a way to expand existing material -- cgit v1.2.3 From 53e5216b2092b98d6973c2b27c5c75713ec99e73 Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink Date: Mon, 17 Oct 2022 15:44:32 -0700 Subject: Continuing work on SL-17697 Live editing with material overrides. * Fixed Selection usage so material editor no longer hardcoded to a single object/face * made local preview hack the fallback for when the ModifyMaterialParams cap is missing --- indra/newview/llmaterialeditor.cpp | 77 ++++++++++++++++++++++++-------------- 1 file changed, 48 insertions(+), 29 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index f1b015fc84..735b4af689 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -200,8 +200,6 @@ LLMaterialEditor::LLMaterialEditor(const LLSD& key) , mHasUnsavedChanges(false) , mExpectedUploadCost(0) , mUploadingTexturesCount(0) - , mOverrideLocalId(0) - , mOverrideFace(0) { const LLInventoryItem* item = getItem(); if (item) @@ -1875,10 +1873,10 @@ void LLMaterialEditor::importMaterial() true); } -class LLRemderMaterialFunctor : public LLSelectedTEFunctor +class LLRenderMaterialFunctor : public LLSelectedTEFunctor { public: - LLRemderMaterialFunctor(const LLUUID &id) + LLRenderMaterialFunctor(const LLUUID &id) : mMatId(id) { } @@ -1897,29 +1895,59 @@ private: LLUUID mMatId; }; +class LLRenderMaterialOverrideFunctor : public LLSelectedTEFunctor +{ +public: + LLRenderMaterialOverrideFunctor(LLMaterialEditor * me, std::string const & url) + : mEditor(me), mCapUrl(url) + { + + } + + bool apply(LLViewerObject* objectp, S32 te) override + { + if (objectp && objectp->permModify() && objectp->getVolume()) + { + //LLVOVolume* vobjp = (LLVOVolume*)objectp; + S32 local_id = objectp->getLocalID(); + + LLSD overrides = llsd::map( + "local_id", local_id, + "side", te, + "overrides", LLSD::emptyMap() + ); + LLCoros::instance().launch("modifyMaterialCoro", std::bind(&LLMaterialEditor::modifyMaterialCoro, mEditor, mCapUrl, overrides)); + } + return true; + } + +private: + LLMaterialEditor * mEditor; + std::string mCapUrl; +}; + void LLMaterialEditor::applyToSelection() { -#if 0 // local preview placeholder hack - // Placehodler. Will be removed once override systems gets finished. - LLPointer mat = new LLGLTFMaterial(); - getGLTFMaterial(mat); - const LLUUID placeholder("984e183e-7811-4b05-a502-d79c6f978a98"); - gGLTFMaterialList.addMaterial(placeholder, mat); - LLRemderMaterialFunctor mat_func(placeholder); - LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); - //selected_objects->applyToTEs(&mat_func); -#else std::string url = gAgent.getRegionCapability("ModifyMaterialParams"); if (!url.empty()) { - LLSDMap overrides; - LLCoros::instance().launch("modifyMaterialCoro", std::bind(&LLMaterialEditor::modifyMaterialCoro, this, url, overrides)); + LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); + LLRenderMaterialOverrideFunctor override_func(this, url); + selected_objects->applyToTEs(&override_func); } else { LL_WARNS() << "not connected to materials capable region, missing ModifyMaterialParams cap" << LL_ENDL; + + // Fallback local preview. Will be removed once override systems is finished and new cap is deployed everywhere. + LLPointer mat = new LLGLTFMaterial(); + getGLTFMaterial(mat); + static const LLUUID placeholder("984e183e-7811-4b05-a502-d79c6f978a98"); + gGLTFMaterialList.addMaterial(placeholder, mat); + LLRenderMaterialFunctor mat_func(placeholder); + LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); + selected_objects->applyToTEs(&mat_func); } -#endif } void LLMaterialEditor::getGLTFMaterial(LLGLTFMaterial* mat) @@ -2323,13 +2351,10 @@ void LLMaterialEditor::modifyMaterialCoro(std::string cap_url, LLSD overrides) LLCore::HttpHeaders::ptr_t httpHeaders; httpOpts->setFollowRedirects(true); - LLSD body = llsd::map( - "local_id", S32(mOverrideLocalId), - "face", mOverrideFace, - "overrides", overrides - ); - LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, body, httpOpts, httpHeaders); + LL_DEBUGS() << "Applying override via ModifyMaterialParams cap: " << overrides << LL_ENDL; + + LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, overrides, httpOpts, httpHeaders); LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); @@ -2343,9 +2368,3 @@ void LLMaterialEditor::modifyMaterialCoro(std::string cap_url, LLSD overrides) LL_WARNS() << "Failed to modify material: " << result["message"] << LL_ENDL; } } - -void LLMaterialEditor::setOverrideTarget(U32 local_id, S32 face) -{ - mOverrideLocalId = local_id; - mOverrideFace = face; -} -- cgit v1.2.3 From f20c47a5968c82b1627139537e07a2ae67f64b24 Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink Date: Mon, 17 Oct 2022 16:49:51 -0700 Subject: More work on SL-17697 LLMaterialEditor now uses new override diffing code when applyToSelection() gets called --- indra/newview/llmaterialeditor.cpp | 55 +++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 22 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 735b4af689..0256ab32da 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1538,24 +1538,6 @@ void LLMaterialEditor::loadMaterial(LLGLTFMaterial * material, bool make_copy) else { setTitle(getString("material_override_title")); - // TODO: Save whole selection - - LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); - LLViewerObject* object = selection->getFirstNode()->getObject(); - if (object) - { - const S32 num_tes = llmin((S32)object->getNumTEs(), (S32)object->getNumFaces()); // avatars have TEs but no faces - for (S32 face = 0; face < num_tes; ++face) - { - LLTextureEntry *te = object->getTE(face); - if (te->isSelected()) - { - // TEMP - setOverrideTarget(object->getLocalID(), face); - break; - } - } - } } // Todo: At the moment it always makes a 'copy' @@ -1898,8 +1880,8 @@ private: class LLRenderMaterialOverrideFunctor : public LLSelectedTEFunctor { public: - LLRenderMaterialOverrideFunctor(LLMaterialEditor * me, std::string const & url) - : mEditor(me), mCapUrl(url) + LLRenderMaterialOverrideFunctor(LLMaterialEditor * me, std::string const & url, LLUUID const & asset_id) + : mEditor(me), mCapUrl(url), mAssetID(asset_id) { } @@ -1911,10 +1893,37 @@ public: //LLVOVolume* vobjp = (LLVOVolume*)objectp; S32 local_id = objectp->getLocalID(); + LLPointer material = new LLGLTFMaterial(); + LLPointer base; + mEditor->getGLTFMaterial(material); + + tinygltf::Model model_out; + + if(mAssetID != LLUUID::null) + { + base = gGLTFMaterialList.getMaterial(mAssetID); + material->writeOverridesToModel(model_out, 0, base); + } + else + { + material->writeToModel(model_out, 0); + } + + std::string overrides_json; + { + tinygltf::TinyGLTF gltf; + std::ostringstream str; + + gltf.WriteGltfSceneToStream(&model_out, str, false, false); + + overrides_json = str.str(); + LL_DEBUGS() << "overrides_json " << overrides_json << LL_ENDL; + } + LLSD overrides = llsd::map( "local_id", local_id, "side", te, - "overrides", LLSD::emptyMap() + "overrides", overrides_json ); LLCoros::instance().launch("modifyMaterialCoro", std::bind(&LLMaterialEditor::modifyMaterialCoro, mEditor, mCapUrl, overrides)); } @@ -1924,6 +1933,7 @@ public: private: LLMaterialEditor * mEditor; std::string mCapUrl; + LLUUID mAssetID; }; void LLMaterialEditor::applyToSelection() @@ -1932,7 +1942,8 @@ void LLMaterialEditor::applyToSelection() if (!url.empty()) { LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); - LLRenderMaterialOverrideFunctor override_func(this, url); + // TODO figure out how to get the right asset id in cases where we don't have a good one + LLRenderMaterialOverrideFunctor override_func(this, url, mAssetID); selected_objects->applyToTEs(&override_func); } else -- cgit v1.2.3 From 7be33594eaab6b9c0da863778bbdacdb8cbe7838 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 18 Oct 2022 20:12:38 +0300 Subject: SL-18008 Updated Save and Edit PBR buttons --- indra/newview/llmaterialeditor.cpp | 72 +++++++++++++++----------------------- 1 file changed, 28 insertions(+), 44 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 0256ab32da..58cebecb23 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -65,6 +65,8 @@ const std::string MATERIAL_NORMAL_DEFAULT_NAME = "Normal"; const std::string MATERIAL_METALLIC_DEFAULT_NAME = "Metallic Roughness"; const std::string MATERIAL_EMISSIVE_DEFAULT_NAME = "Emissive"; +const LLUUID LIVE_MATERIAL_EDITOR_KEY("6cf97162-8b68-49eb-b627-79886c9fd17d"); + LLFloaterComboOptions::LLFloaterComboOptions() : LLFloater(LLSD()) { @@ -1399,14 +1401,24 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind } } -void LLMaterialEditor::loadLiveMaterial(LLGLTFMaterial * material, bool make_copy) +void LLMaterialEditor::loadLiveMaterial(LLUUID &asset_id) +{ + LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", LLSD(LIVE_MATERIAL_EDITOR_KEY)); + me->setTitle(me->getString("material_override_title")); + me->setAssetId(asset_id); + me->setFromGLTFMaterial(gGLTFMaterialList.getMaterial(asset_id)); + me->openFloater(); + me->setFocus(TRUE); +} + +void LLMaterialEditor::loadFromGLTFMaterial(LLUUID &asset_id) { - if (!material) - { - return; - } LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor"); - me->loadMaterial(material, make_copy); + me->setTitle(LLTrans::getString("New Material")); + me->setHasUnsavedChanges(true); + me->setFromGLTFMaterial(gGLTFMaterialList.getMaterial(asset_id)); + me->openFloater(); + me->setFocus(TRUE); } void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std::string &filename_lc, S32 index) @@ -1513,43 +1525,6 @@ void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std:: applyToSelection(); } -void LLMaterialEditor::loadMaterial(LLGLTFMaterial * material, bool make_copy) -{ - setBaseColorId(material->mBaseColorId); - setMetallicRoughnessId(material->mMetallicRoughnessId); - setEmissiveId(material->mEmissiveId); - setNormalId(material->mNormalId); - - setAlphaMode(material->getAlphaMode()); - setAlphaCutoff(material->mAlphaCutoff); - - setBaseColor(material->mBaseColor); - setEmissiveColor(material->mEmissiveColor); - - setMetalnessFactor(material->mMetallicFactor); - setRoughnessFactor(material->mRoughnessFactor); - - setDoubleSided(material->mDoubleSided); - - if (make_copy) - { - setTitle(LLTrans::getString("New Material")); - } - else - { - setTitle(getString("material_override_title")); - } - - // Todo: At the moment it always makes a 'copy' - // Will need a way to expand existing material - // once overrides are done - - setHasUnsavedChanges(make_copy); - - openFloater(); - setFocus(TRUE); -} - bool LLMaterialEditor::setFromGltfModel(const tinygltf::Model& model, S32 index, bool set_textures) { if (model.materials.size() > index) @@ -1863,7 +1838,7 @@ public: { } - virtual bool apply(LLViewerObject* objectp, S32 te) + bool apply(LLViewerObject* objectp, S32 te) override { if (objectp && objectp->permModify() && objectp->getVolume()) { @@ -1938,6 +1913,15 @@ private: void LLMaterialEditor::applyToSelection() { + if (!mKey.isUUID() || mKey.asUUID() != LIVE_MATERIAL_EDITOR_KEY) + { + // Only apply if working with 'live' materials + // Might need a better way to distinguish 'live' mode. + // But only one live edit is supposed to work at a time + // as a pair to tools floater. + return; + } + std::string url = gAgent.getRegionCapability("ModifyMaterialParams"); if (!url.empty()) { -- cgit v1.2.3 From 0b177c27a07344d81cb52806695b2348b6f33b0a Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 18 Oct 2022 22:08:27 +0300 Subject: SL-18008 Mac build fix --- indra/newview/llmaterialeditor.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 58cebecb23..319f98b816 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1406,13 +1406,21 @@ void LLMaterialEditor::loadLiveMaterial(LLUUID &asset_id) LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", LLSD(LIVE_MATERIAL_EDITOR_KEY)); me->setTitle(me->getString("material_override_title")); me->setAssetId(asset_id); - me->setFromGLTFMaterial(gGLTFMaterialList.getMaterial(asset_id)); + if (asset_id.notNull()) + { + me->setFromGLTFMaterial(gGLTFMaterialList.getMaterial(asset_id)); + } me->openFloater(); me->setFocus(TRUE); } void LLMaterialEditor::loadFromGLTFMaterial(LLUUID &asset_id) { + if (asset_id.isNull()) + { + LL_WARNS() << "Trying to open material with null id" << LL_ENDL; + return; + } LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor"); me->setTitle(LLTrans::getString("New Material")); me->setHasUnsavedChanges(true); -- cgit v1.2.3 From 58472180696401155159414c20a307cf97f7df44 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 19 Oct 2022 00:08:27 +0300 Subject: SL-18391 Basic GLTF lifetime management --- indra/newview/llmaterialeditor.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 319f98b816..c5cdb81d67 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1422,7 +1422,8 @@ void LLMaterialEditor::loadFromGLTFMaterial(LLUUID &asset_id) return; } LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor"); - me->setTitle(LLTrans::getString("New Material")); + me->mMaterialName = LLTrans::getString("New Material"); + me->setTitle(me->mMaterialName); me->setHasUnsavedChanges(true); me->setFromGLTFMaterial(gGLTFMaterialList.getMaterial(asset_id)); me->openFloater(); @@ -1943,7 +1944,7 @@ void LLMaterialEditor::applyToSelection() LL_WARNS() << "not connected to materials capable region, missing ModifyMaterialParams cap" << LL_ENDL; // Fallback local preview. Will be removed once override systems is finished and new cap is deployed everywhere. - LLPointer mat = new LLGLTFMaterial(); + LLPointer mat = new LLFetchedGLTFMaterial(); getGLTFMaterial(mat); static const LLUUID placeholder("984e183e-7811-4b05-a502-d79c6f978a98"); gGLTFMaterialList.addMaterial(placeholder, mat); -- cgit v1.2.3 From 61967623baaa8988f4f8b48043f79be29452ca80 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 21 Oct 2022 16:34:14 -0500 Subject: SL-18105 Clean up class1/deferred/materialF.glsl (merge cleanup), make override messaging LLSD where it ought to be and JSON where it ought to be. --- indra/newview/llmaterialeditor.cpp | 40 +++++++++++--------------------------- 1 file changed, 11 insertions(+), 29 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index c5cdb81d67..58894dbd69 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1872,42 +1872,24 @@ public: bool apply(LLViewerObject* objectp, S32 te) override { + // post override from given object and te to the simulator + // requestData should have: + // object_id - UUID of LLViewerObject + // side - S32 index of texture entry + // gltf_json - String of GLTF json for override data + if (objectp && objectp->permModify() && objectp->getVolume()) { - //LLVOVolume* vobjp = (LLVOVolume*)objectp; - S32 local_id = objectp->getLocalID(); - LLPointer material = new LLGLTFMaterial(); - LLPointer base; + mEditor->getGLTFMaterial(material); - tinygltf::Model model_out; - - if(mAssetID != LLUUID::null) - { - base = gGLTFMaterialList.getMaterial(mAssetID); - material->writeOverridesToModel(model_out, 0, base); - } - else - { - material->writeToModel(model_out, 0); - } - - std::string overrides_json; - { - tinygltf::TinyGLTF gltf; - std::ostringstream str; - - gltf.WriteGltfSceneToStream(&model_out, str, false, false); - - overrides_json = str.str(); - LL_DEBUGS() << "overrides_json " << overrides_json << LL_ENDL; - } - + std::string overrides_json = material->asJSON(); + LLSD overrides = llsd::map( - "local_id", local_id, + "object_id", objectp->getID(), "side", te, - "overrides", overrides_json + "gltf_json", overrides_json ); LLCoros::instance().launch("modifyMaterialCoro", std::bind(&LLMaterialEditor::modifyMaterialCoro, mEditor, mCapUrl, overrides)); } -- cgit v1.2.3 From 0cd7c3842119f1801872b4db05e17544b4eb7158 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 21 Oct 2022 18:05:19 -0500 Subject: SL-18105 Hook up live material editor to current selection set and implicitly open build floater when editing a PBR material. --- indra/newview/llmaterialeditor.cpp | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 58894dbd69..86efdfcd06 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1401,15 +1401,14 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind } } -void LLMaterialEditor::loadLiveMaterial(LLUUID &asset_id) +void LLMaterialEditor::loadLiveMaterialEditor() { LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", LLSD(LIVE_MATERIAL_EDITOR_KEY)); + me->mIsOverride = true; me->setTitle(me->getString("material_override_title")); - me->setAssetId(asset_id); - if (asset_id.notNull()) - { - me->setFromGLTFMaterial(gGLTFMaterialList.getMaterial(asset_id)); - } + me->childSetVisible("save", false); + me->childSetVisible("save_as", false); + me->setFromSelection(); me->openFloater(); me->setFocus(TRUE); } @@ -1904,7 +1903,7 @@ private: void LLMaterialEditor::applyToSelection() { - if (!mKey.isUUID() || mKey.asUUID() != LIVE_MATERIAL_EDITOR_KEY) + if (!mIsOverride) { // Only apply if working with 'live' materials // Might need a better way to distinguish 'live' mode. @@ -1974,6 +1973,22 @@ void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat) setAlphaCutoff(mat->mAlphaCutoff); } +void LLMaterialEditor::setFromSelection() +{ + struct LLSelectedTEGetGLTFRenderMaterial : public LLSelectedTEGetFunctor > + { + LLPointer get(LLViewerObject* object, S32 te_index) + { + return object->getTE(te_index)->getGLTFRenderMaterial(); // present user with combined override + asset + } + } func; + + LLPointer mat; + LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&func, mat); + setFromGLTFMaterial(mat); +} + + void LLMaterialEditor::loadAsset() { // derived from LLPreviewNotecard::loadAsset -- cgit v1.2.3 From 7135934e50bf2727c2366687af7427d44483e984 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 22 Oct 2022 11:01:35 -0500 Subject: SL-18105 Fix for crash when attempting to "Edit PBR Material" when there's no PBR material --- indra/newview/llmaterialeditor.cpp | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 86efdfcd06..038f4df863 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1404,13 +1404,16 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind void LLMaterialEditor::loadLiveMaterialEditor() { LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", LLSD(LIVE_MATERIAL_EDITOR_KEY)); - me->mIsOverride = true; - me->setTitle(me->getString("material_override_title")); - me->childSetVisible("save", false); - me->childSetVisible("save_as", false); - me->setFromSelection(); - me->openFloater(); - me->setFocus(TRUE); + if (me->setFromSelection()) + { + me->mIsOverride = true; + me->setTitle(me->getString("material_override_title")); + me->childSetVisible("save", false); + me->childSetVisible("save_as", false); + + me->openFloater(); + me->setFocus(TRUE); + } } void LLMaterialEditor::loadFromGLTFMaterial(LLUUID &asset_id) @@ -1973,7 +1976,7 @@ void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat) setAlphaCutoff(mat->mAlphaCutoff); } -void LLMaterialEditor::setFromSelection() +bool LLMaterialEditor::setFromSelection() { struct LLSelectedTEGetGLTFRenderMaterial : public LLSelectedTEGetFunctor > { @@ -1985,7 +1988,13 @@ void LLMaterialEditor::setFromSelection() LLPointer mat; LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&func, mat); - setFromGLTFMaterial(mat); + if (mat.notNull()) + { + setFromGLTFMaterial(mat); + return true; + } + + return false; } -- cgit v1.2.3 From 88659e9fe793a02fb4edcbf8ef07307c25119604 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 22 Oct 2022 15:25:03 -0500 Subject: SL-18105 When saving an object's material to inventory, save the version that as overrides applied. --- indra/newview/llmaterialeditor.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 038f4df863..8086bcf402 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1401,7 +1401,7 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind } } -void LLMaterialEditor::loadLiveMaterialEditor() +void LLMaterialEditor::loadLive() { LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", LLSD(LIVE_MATERIAL_EDITOR_KEY)); if (me->setFromSelection()) @@ -1416,6 +1416,18 @@ void LLMaterialEditor::loadLiveMaterialEditor() } } +void LLMaterialEditor::loadObjectSave() +{ + LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", LLSD(LIVE_MATERIAL_EDITOR_KEY)); + if (me->setFromSelection()) + { + me->mIsOverride = false; + me->childSetVisible("save", false); + me->openFloater(); + me->setFocus(TRUE); + } +} + void LLMaterialEditor::loadFromGLTFMaterial(LLUUID &asset_id) { if (asset_id.isNull()) -- cgit v1.2.3 From 4a1397c621eec2deb90d4953762fea6187c0a270 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 24 Oct 2022 23:35:28 +0300 Subject: SL-18414 Smarter material editor's cancel for overrides --- indra/newview/llmaterialeditor.cpp | 97 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 93 insertions(+), 4 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 8086bcf402..06705a277b 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -302,10 +302,6 @@ void LLMaterialEditor::onClickCloseBtn(bool app_quitting) void LLMaterialEditor::onClose(bool app_quitting) { - // todo: will only revert whatever was recently selected, - // Later should work based of tools floater - LLSelectMgr::getInstance()->selectionRevertGLTFMaterials(); - LLPreview::onClose(app_quitting); } @@ -1265,6 +1261,73 @@ void LLMaterialEditor::onCancelMsgCallback(const LLSD& notification, const LLSD& S32 option = LLNotificationsUtil::getSelectedOption(notification, response); if (0 == option) { + if (mIsOverride && !mObjectOverridesSavedValues.empty()) + { + // Reapply ids back onto selection. + // TODO: monitor selection changes and resave on selection changes + struct g : public LLSelectedObjectFunctor + { + g(LLMaterialEditor* me) : mEditor(me) {} + virtual bool apply(LLViewerObject* objectp) + { + if (!objectp || !objectp->permModify()) + { + return false; + } + + U32 local_id = objectp->getLocalID(); + if (mEditor->mObjectOverridesSavedValues.find(local_id) == mEditor->mObjectOverridesSavedValues.end()) + { + return false; + } + + S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); + for (U8 te = 0; te < num_tes; te++) + { + if (mEditor->mObjectOverridesSavedValues[local_id].size() > te + && objectp->getTE(te)->isSelected()) + { + objectp->setRenderMaterialID( + te, + mEditor->mObjectOverridesSavedValues[local_id][te], + false /*wait for bulk update*/); + } + } + return true; + } + LLMaterialEditor* mEditor; + } restorefunc(this); + LLSelectMgr::getInstance()->getSelection()->applyToObjects(&restorefunc); + + struct f : public LLSelectedObjectFunctor + { + virtual bool apply(LLViewerObject* object) + { + if (object && !object->permModify()) + { + return false; + } + + LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)object->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL); + if (param_block) + { + if (param_block->isEmpty()) + { + object->setHasRenderMaterialParams(false); + } + else + { + object->parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, true); + } + } + + object->sendTEUpdate(); + return true; + } + } sendfunc; + LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc); + } + closeFloater(); } } @@ -1410,6 +1473,32 @@ void LLMaterialEditor::loadLive() me->setTitle(me->getString("material_override_title")); me->childSetVisible("save", false); me->childSetVisible("save_as", false); + me->mObjectOverridesSavedValues.clear(); + + // Collect ids to be able to revert overrides. + // TODO: monitor selection changes and resave on selection changes + struct g : public LLSelectedObjectFunctor + { + g(LLMaterialEditor* me) : mEditor(me) {} + virtual bool apply(LLViewerObject* objectp) + { + if (!objectp) + { + return false; + } + + U32 local_id = objectp->getLocalID(); + S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); + for (U8 te = 0; te < num_tes; te++) + { + LLUUID mat_id = objectp->getRenderMaterialID(te); + mEditor->mObjectOverridesSavedValues[local_id].push_back(mat_id); + } + return true; + } + LLMaterialEditor* mEditor; + } savefunc(me); + LLSelectMgr::getInstance()->getSelection()->applyToObjects(&savefunc); me->openFloater(); me->setFocus(TRUE); -- cgit v1.2.3 From 89625f92473bd2894acd287caeeb1d20673f8ddb Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 26 Oct 2022 00:41:35 +0300 Subject: SL-18444 Live Material Editor updating with selection --- indra/newview/llmaterialeditor.cpp | 93 ++++++++++++++++++++++++++------------ 1 file changed, 63 insertions(+), 30 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 06705a277b..1e75216079 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -302,6 +302,11 @@ void LLMaterialEditor::onClickCloseBtn(bool app_quitting) void LLMaterialEditor::onClose(bool app_quitting) { + if (mSelectionUpdateSlot.connected()) + { + mSelectionUpdateSlot.disconnect(); + } + LLPreview::onClose(app_quitting); } @@ -1463,42 +1468,61 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind ); } } +void LLMaterialEditor::onSelectionChanged() +{ + mHasUnsavedChanges = false; + clearTextures(); + setFromSelection(); + saveLiveValues(); +} + +void LLMaterialEditor::saveLiveValues() +{ + // Collect ids to be able to revert overrides. + // TODO: monitor selection changes and resave on selection changes + mObjectOverridesSavedValues.clear(); + struct g : public LLSelectedObjectFunctor + { + g(LLMaterialEditor* me) : mEditor(me) {} + virtual bool apply(LLViewerObject* objectp) + { + if (!objectp) + { + return false; + } + + U32 local_id = objectp->getLocalID(); + S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); + for (U8 te = 0; te < num_tes; te++) + { + LLUUID mat_id = objectp->getRenderMaterialID(te); + mEditor->mObjectOverridesSavedValues[local_id].push_back(mat_id); + } + return true; + } + LLMaterialEditor* mEditor; + } savefunc(this); + LLSelectMgr::getInstance()->getSelection()->applyToObjects(&savefunc); +} void LLMaterialEditor::loadLive() { LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", LLSD(LIVE_MATERIAL_EDITOR_KEY)); - if (me->setFromSelection()) + if (me) { + me->setFromSelection(); me->mIsOverride = true; me->setTitle(me->getString("material_override_title")); me->childSetVisible("save", false); me->childSetVisible("save_as", false); - me->mObjectOverridesSavedValues.clear(); - // Collect ids to be able to revert overrides. - // TODO: monitor selection changes and resave on selection changes - struct g : public LLSelectedObjectFunctor + // Set up for selection changes updates + if (!me->mSelectionUpdateSlot.connected()) { - g(LLMaterialEditor* me) : mEditor(me) {} - virtual bool apply(LLViewerObject* objectp) - { - if (!objectp) - { - return false; - } - - U32 local_id = objectp->getLocalID(); - S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); - for (U8 te = 0; te < num_tes; te++) - { - LLUUID mat_id = objectp->getRenderMaterialID(te); - mEditor->mObjectOverridesSavedValues[local_id].push_back(mat_id); - } - return true; - } - LLMaterialEditor* mEditor; - } savefunc(me); - LLSelectMgr::getInstance()->getSelection()->applyToObjects(&savefunc); + me->mSelectionUpdateSlot = LLSelectMgr::instance().mUpdateSignal.connect(boost::bind(&LLMaterialEditor::onSelectionChanged, me)); + } + // Collect ids to be able to revert overrides on cancel. + me->saveLiveValues(); me->openFloater(); me->setFocus(TRUE); @@ -2095,6 +2119,10 @@ bool LLMaterialEditor::setFromSelection() return true; } + // pick defaults from a blank material; + LLGLTFMaterial blank_mat; + setFromGLTFMaterial(&blank_mat); + return false; } @@ -2424,6 +2452,16 @@ S32 LLMaterialEditor::saveTextures() } // discard upload buffers once textures have been saved + clearTextures(); + + // asset storage can callback immediately, causing a decrease + // of mUploadingTexturesCount, report amount of work scheduled + // not amount of work remaining + return work_count; +} + +void LLMaterialEditor::clearTextures() +{ mBaseColorJ2C = nullptr; mNormalJ2C = nullptr; mEmissiveJ2C = nullptr; @@ -2438,11 +2476,6 @@ S32 LLMaterialEditor::saveTextures() mNormalTextureUploadId.setNull(); mMetallicTextureUploadId.setNull(); mEmissiveTextureUploadId.setNull(); - - // asset storage can callback immediately, causing a decrease - // of mUploadingTexturesCount, report amount of work scheduled - // not amount of work remaining - return work_count; } void LLMaterialEditor::loadDefaults() -- cgit v1.2.3 From d69c814db94c907a1a772e4e63a8b82a293985d2 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 26 Oct 2022 20:18:33 +0300 Subject: SL-18446 Terse-update selection set from live material editor #1 --- indra/newview/llmaterialeditor.cpp | 169 +++++++++++++++++++++++++++---------- 1 file changed, 126 insertions(+), 43 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 1e75216079..58804a901f 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -67,6 +67,24 @@ const std::string MATERIAL_EMISSIVE_DEFAULT_NAME = "Emissive"; const LLUUID LIVE_MATERIAL_EDITOR_KEY("6cf97162-8b68-49eb-b627-79886c9fd17d"); +// Dirty flags +static const U32 MATERIAL_BASE_COLOR_DIRTY = 0x1 << 0; +static const U32 MATERIAL_BASE_TRANSPARENCY_DIRTY = 0x1 << 1; +static const U32 MATERIAL_BASE_COLOR_TEX_DIRTY = 0x1 << 2; + +static const U32 MATERIAL_NORMAL_TEX_DIRTY = 0x1 << 3; + +static const U32 MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY = 0x1 << 4; +static const U32 MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY = 0x1 << 5; +static const U32 MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY = 0x1 << 6; + +static const U32 MATERIAL_EMISIVE_COLOR_DIRTY = 0x1 << 7; +static const U32 MATERIAL_EMISIVE_TEX_DIRTY = 0x1 << 8; + +static const U32 MATERIAL_DOUBLE_SIDED_DIRTY = 0x1 << 9; +static const U32 MATERIAL_ALPHA_MODE_DIRTY = 0x1 << 10; +static const U32 MATERIAL_ALPHA_CUTOFF_DIRTY = 0x1 << 11; + LLFloaterComboOptions::LLFloaterComboOptions() : LLFloater(LLSD()) { @@ -199,7 +217,7 @@ private: // Default constructor LLMaterialEditor::LLMaterialEditor(const LLSD& key) : LLPreview(key) - , mHasUnsavedChanges(false) + , mUnsavedChanges(0) , mExpectedUploadCost(0) , mUploadingTexturesCount(0) { @@ -251,33 +269,30 @@ BOOL LLMaterialEditor::postBuild() getChild("emissive_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); getChild("normal_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); - boost::function changes_callback = [this](LLUICtrl * ctrl, void*) + boost::function changes_callback = [this](LLUICtrl * ctrl, void* userData) { - setHasUnsavedChanges(true); + const U32 *flag = (const U32*)userData; + markChangesUnsaved(*flag); // Apply changes to object live applyToSelection(); }; - childSetCommitCallback("double sided", changes_callback, NULL); + childSetCommitCallback("double sided", changes_callback, (void*)&MATERIAL_DOUBLE_SIDED_DIRTY); // BaseColor - childSetCommitCallback("base color", changes_callback, NULL); - childSetCommitCallback("transparency", changes_callback, NULL); - childSetCommitCallback("alpha mode", changes_callback, NULL); - childSetCommitCallback("alpha cutoff", changes_callback, NULL); + childSetCommitCallback("base color", changes_callback, (void*)&MATERIAL_BASE_COLOR_DIRTY); + childSetCommitCallback("transparency", changes_callback, (void*)&MATERIAL_BASE_TRANSPARENCY_DIRTY); + childSetCommitCallback("alpha mode", changes_callback, (void*)&MATERIAL_ALPHA_MODE_DIRTY); + childSetCommitCallback("alpha cutoff", changes_callback, (void*)&MATERIAL_ALPHA_CUTOFF_DIRTY); // Metallic-Roughness - childSetCommitCallback("metalness factor", changes_callback, NULL); - childSetCommitCallback("roughness factor", changes_callback, NULL); - - // Metallic-Roughness - childSetCommitCallback("metalness factor", changes_callback, NULL); - childSetCommitCallback("roughness factor", changes_callback, NULL); + childSetCommitCallback("metalness factor", changes_callback, (void*)&MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY); + childSetCommitCallback("roughness factor", changes_callback, (void*)&MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY); // Emissive - childSetCommitCallback("emissive color", changes_callback, NULL); + childSetCommitCallback("emissive color", changes_callback, (void*)&MATERIAL_EMISIVE_COLOR_DIRTY); - childSetVisible("unsaved_changes", mHasUnsavedChanges); + childSetVisible("unsaved_changes", mUnsavedChanges); getChild("total_upload_fee")->setTextArg("[FEE]", llformat("%d", 0)); @@ -333,7 +348,7 @@ void LLMaterialEditor::setBaseColorUploadId(const LLUUID& id) // Only set if we will need to upload this texture mBaseColorTextureUploadId = id; } - setHasUnsavedChanges(true); + markChangesUnsaved(MATERIAL_BASE_COLOR_TEX_DIRTY); } LLColor4 LLMaterialEditor::getBaseColor() @@ -405,7 +420,7 @@ void LLMaterialEditor::setMetallicRoughnessUploadId(const LLUUID& id) childSetValue("metallic_upload_fee", getString("upload_fee_string")); mMetallicTextureUploadId = id; } - setHasUnsavedChanges(true); + markChangesUnsaved(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY); } F32 LLMaterialEditor::getMetalnessFactor() @@ -448,7 +463,7 @@ void LLMaterialEditor::setEmissiveUploadId(const LLUUID& id) childSetValue("emissive_upload_fee", getString("upload_fee_string")); mEmissiveTextureUploadId = id; } - setHasUnsavedChanges(true); + markChangesUnsaved(MATERIAL_EMISIVE_TEX_DIRTY); } LLColor4 LLMaterialEditor::getEmissiveColor() @@ -481,7 +496,7 @@ void LLMaterialEditor::setNormalUploadId(const LLUUID& id) childSetValue("normal_upload_fee", getString("upload_fee_string")); mNormalTextureUploadId = id; } - setHasUnsavedChanges(true); + markChangesUnsaved(MATERIAL_NORMAL_TEX_DIRTY); } bool LLMaterialEditor::getDoubleSided() @@ -494,12 +509,22 @@ void LLMaterialEditor::setDoubleSided(bool double_sided) childSetValue("double sided", double_sided); } -void LLMaterialEditor::setHasUnsavedChanges(bool value) +void LLMaterialEditor::resetUnsavedChanges() +{ + mUnsavedChanges = 0; + childSetVisible("unsaved_changes", false); + setCanSave(false); + + mExpectedUploadCost = 0; + getChild("total_upload_fee")->setTextArg("[FEE]", llformat("%d", mExpectedUploadCost)); +} + +void LLMaterialEditor::markChangesUnsaved(U32 dirty_flag) { - mHasUnsavedChanges = value; - childSetVisible("unsaved_changes", value); + mUnsavedChanges |= dirty_flag; + childSetVisible("unsaved_changes", mUnsavedChanges); - if (mHasUnsavedChanges) + if (mUnsavedChanges) { const LLInventoryItem* item = getItem(); if (item) @@ -594,7 +619,7 @@ void LLMaterialEditor::onCommitBaseColorTexture(LLUICtrl * ctrl, const LLSD & da // the texture that is not in use childSetValue("base_color_upload_fee", getString("no_upload_fee_string")); } - setHasUnsavedChanges(true); + markChangesUnsaved(MATERIAL_BASE_COLOR_TEX_DIRTY); applyToSelection(); } @@ -609,7 +634,7 @@ void LLMaterialEditor::onCommitMetallicTexture(LLUICtrl * ctrl, const LLSD & dat { childSetValue("metallic_upload_fee", getString("no_upload_fee_string")); } - setHasUnsavedChanges(true); + markChangesUnsaved(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY); applyToSelection(); } @@ -624,7 +649,7 @@ void LLMaterialEditor::onCommitEmissiveTexture(LLUICtrl * ctrl, const LLSD & dat { childSetValue("emissive_upload_fee", getString("no_upload_fee_string")); } - setHasUnsavedChanges(true); + markChangesUnsaved(MATERIAL_EMISIVE_TEX_DIRTY); applyToSelection(); } @@ -639,7 +664,7 @@ void LLMaterialEditor::onCommitNormalTexture(LLUICtrl * ctrl, const LLSD & data) { childSetValue("normal_upload_fee", getString("no_upload_fee_string")); } - setHasUnsavedChanges(true); + markChangesUnsaved(MATERIAL_NORMAL_TEX_DIRTY); applyToSelection(); } @@ -1223,7 +1248,7 @@ void LLMaterialEditor::onSaveAsMsgCallback(const LLSD& notification, const LLSD& else { std::string buffer = getEncodedAsset(); - LLPointer cb = new LLMaterialEditorCopiedCallback(buffer, getKey(), mHasUnsavedChanges); + LLPointer cb = new LLMaterialEditorCopiedCallback(buffer, getKey(), mUnsavedChanges); copy_inventory_item( gAgent.getID(), item->getPermissions().getOwner(), @@ -1251,7 +1276,7 @@ void LLMaterialEditor::onSaveAsMsgCallback(const LLSD& notification, const LLSD& void LLMaterialEditor::onClickCancel() { - if (mHasUnsavedChanges) + if (mUnsavedChanges) { LLNotificationsUtil::add("UsavedMaterialChanges", LLSD(), LLSD(), boost::bind(&LLMaterialEditor::onCancelMsgCallback, this, _1, _2)); } @@ -1470,7 +1495,7 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind } void LLMaterialEditor::onSelectionChanged() { - mHasUnsavedChanges = false; + mUnsavedChanges = 0; clearTextures(); setFromSelection(); saveLiveValues(); @@ -1551,7 +1576,6 @@ void LLMaterialEditor::loadFromGLTFMaterial(LLUUID &asset_id) LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor"); me->mMaterialName = LLTrans::getString("New Material"); me->setTitle(me->mMaterialName); - me->setHasUnsavedChanges(true); me->setFromGLTFMaterial(gGLTFMaterialList.getMaterial(asset_id)); me->openFloater(); me->setFocus(TRUE); @@ -1653,7 +1677,7 @@ void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std:: setFromGltfMetaData(filename_lc, model_in, index); - setHasUnsavedChanges(true); + markChangesUnsaved(U32_MAX); openFloater(); setFocus(TRUE); @@ -1991,8 +2015,8 @@ private: class LLRenderMaterialOverrideFunctor : public LLSelectedTEFunctor { public: - LLRenderMaterialOverrideFunctor(LLMaterialEditor * me, std::string const & url, LLUUID const & asset_id) - : mEditor(me), mCapUrl(url), mAssetID(asset_id) + LLRenderMaterialOverrideFunctor(LLMaterialEditor * me, std::string const & url) + : mEditor(me), mCapUrl(url) { } @@ -2007,9 +2031,69 @@ public: if (objectp && objectp->permModify() && objectp->getVolume()) { - LLPointer material = new LLGLTFMaterial(); - - mEditor->getGLTFMaterial(material); + // Get material from object + // Selection can cover multiple objects, and live editor is + // supposed to overwrite changed values only + LLTextureEntry* tep = objectp->getTE(te); + LLPointer material = tep->getGLTFMaterial(); + if (material.isNull()) + { + material = new LLGLTFMaterial(); + } + + // Override object's values with values from editor where appropriate + if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_COLOR_DIRTY) + { + material->mBaseColor = mEditor->getBaseColor(); + } + if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_TRANSPARENCY_DIRTY) + { + material->mBaseColor.mV[3] = mEditor->getTransparency(); + } + if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_COLOR_TEX_DIRTY) + { + material->mBaseColorId = mEditor->getBaseColorId(); + } + + if (mEditor->getUnsavedChangesFlags() & MATERIAL_NORMAL_TEX_DIRTY) + { + material->mNormalId = mEditor->getNormalId(); + } + + if (mEditor->getUnsavedChangesFlags() & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) + { + material->mMetallicRoughnessId = mEditor->getMetallicRoughnessId(); + } + if (mEditor->getUnsavedChangesFlags() & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY) + { + material->mMetallicFactor = mEditor->getMetalnessFactor(); + } + if (mEditor->getUnsavedChangesFlags() & MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY) + { + material->mRoughnessFactor = mEditor->getRoughnessFactor(); + } + + if (mEditor->getUnsavedChangesFlags() & MATERIAL_EMISIVE_COLOR_DIRTY) + { + material->mEmissiveColor = mEditor->getEmissiveColor(); + } + if (mEditor->getUnsavedChangesFlags() & MATERIAL_EMISIVE_TEX_DIRTY) + { + material->mEmissiveId = mEditor->getEmissiveId(); + } + + if (mEditor->getUnsavedChangesFlags() & MATERIAL_DOUBLE_SIDED_DIRTY) + { + material->mDoubleSided = mEditor->getDoubleSided(); + } + if (mEditor->getUnsavedChangesFlags() & MATERIAL_ALPHA_MODE_DIRTY) + { + material->setAlphaMode(mEditor->getAlphaMode()); + } + if (mEditor->getUnsavedChangesFlags() & MATERIAL_ALPHA_CUTOFF_DIRTY) + { + material->mAlphaCutoff = mEditor->getAlphaCutoff(); + } std::string overrides_json = material->asJSON(); @@ -2026,7 +2110,6 @@ public: private: LLMaterialEditor * mEditor; std::string mCapUrl; - LLUUID mAssetID; }; void LLMaterialEditor::applyToSelection() @@ -2045,7 +2128,7 @@ void LLMaterialEditor::applyToSelection() { LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); // TODO figure out how to get the right asset id in cases where we don't have a good one - LLRenderMaterialOverrideFunctor override_func(this, url, mAssetID); + LLRenderMaterialOverrideFunctor override_func(this, url); selected_objects->applyToTEs(&override_func); } else @@ -2162,7 +2245,7 @@ void LLMaterialEditor::loadAsset() { mAssetStatus = PREVIEW_ASSET_LOADED; loadDefaults(); - setHasUnsavedChanges(false); + resetUnsavedChanges(); setEnableEditing(allow_modify && !source_library); } else @@ -2187,7 +2270,7 @@ void LLMaterialEditor::loadAsset() LL_WARNS() << "Can't find object " << mObjectUUID << " associated with notecard." << LL_ENDL; mAssetID.setNull(); mAssetStatus = PREVIEW_ASSET_LOADED; - setHasUnsavedChanges(false); + resetUnsavedChanges(); setEnableEditing(allow_modify && !source_library); return; } @@ -2274,7 +2357,7 @@ void LLMaterialEditor::onLoadComplete(const LLUUID& asset_uuid, BOOL allow_modify = editor->canModify(editor->mObjectUUID, editor->getItem()); BOOL source_library = editor->mObjectUUID.isNull() && gInventory.isObjectDescendentOf(editor->mItemUUID, gInventory.getLibraryRootFolderID()); editor->setEnableEditing(allow_modify && !source_library); - editor->setHasUnsavedChanges(false); + editor->resetUnsavedChanges(); editor->mAssetStatus = PREVIEW_ASSET_LOADED; editor->setEnabled(true); // ready for use } -- cgit v1.2.3 From 5ee774f4ecda6ab312239b0d2ab1d7849ff535b0 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 26 Oct 2022 22:40:16 +0300 Subject: SL-18446 Support "multiple textures" in Live material overrides --- indra/newview/llmaterialeditor.cpp | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 58804a901f..a6d2729dfa 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -334,6 +334,7 @@ void LLMaterialEditor::setBaseColorId(const LLUUID& id) { mBaseColorTextureCtrl->setValue(id); mBaseColorTextureCtrl->setDefaultImageAssetID(id); + mBaseColorTextureCtrl->setTentative(FALSE); } void LLMaterialEditor::setBaseColorUploadId(const LLUUID& id) @@ -409,6 +410,7 @@ void LLMaterialEditor::setMetallicRoughnessId(const LLUUID& id) { mMetallicTextureCtrl->setValue(id); mMetallicTextureCtrl->setDefaultImageAssetID(id); + mMetallicTextureCtrl->setTentative(FALSE); } void LLMaterialEditor::setMetallicRoughnessUploadId(const LLUUID& id) @@ -452,6 +454,7 @@ void LLMaterialEditor::setEmissiveId(const LLUUID& id) { mEmissiveTextureCtrl->setValue(id); mEmissiveTextureCtrl->setDefaultImageAssetID(id); + mEmissiveTextureCtrl->setTentative(FALSE); } void LLMaterialEditor::setEmissiveUploadId(const LLUUID& id) @@ -485,6 +488,7 @@ void LLMaterialEditor::setNormalId(const LLUUID& id) { mNormalTextureCtrl->setValue(id); mNormalTextureCtrl->setDefaultImageAssetID(id); + mNormalTextureCtrl->setTentative(FALSE); } void LLMaterialEditor::setNormalUploadId(const LLUUID& id) @@ -2188,25 +2192,40 @@ bool LLMaterialEditor::setFromSelection() { struct LLSelectedTEGetGLTFRenderMaterial : public LLSelectedTEGetFunctor > { - LLPointer get(LLViewerObject* object, S32 te_index) + LLPointer get(LLViewerObject* objectp, S32 te_index) { - return object->getTE(te_index)->getGLTFRenderMaterial(); // present user with combined override + asset + if (!objectp) + { + return nullptr; + } + LLTextureEntry *tep = objectp->getTE(te_index); + if (!tep) + { + return nullptr; + } + return tep->getGLTFRenderMaterial(); // present user with combined override + asset } } func; LLPointer mat; - LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&func, mat); + bool identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&func, mat); if (mat.notNull()) { setFromGLTFMaterial(mat); - return true; + } + else + { + // pick defaults from a blank material; + LLGLTFMaterial blank_mat; + setFromGLTFMaterial(&blank_mat); } - // pick defaults from a blank material; - LLGLTFMaterial blank_mat; - setFromGLTFMaterial(&blank_mat); + mBaseColorTextureCtrl->setTentative(!identical); + mMetallicTextureCtrl->setTentative(!identical); + mEmissiveTextureCtrl->setTentative(!identical); + mNormalTextureCtrl->setTentative(!identical); - return false; + return mat.notNull(); } -- cgit v1.2.3 From 8f47657d646c06dbba8d44497c0f81fd00730cc8 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 26 Oct 2022 16:08:28 -0500 Subject: SL-18443 Allow nulling out of override data and implement new override message protocol. --- indra/newview/llmaterialeditor.cpp | 29 +---------------------------- 1 file changed, 1 insertion(+), 28 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 06705a277b..5ae16db1f6 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1994,7 +1994,7 @@ public: "side", te, "gltf_json", overrides_json ); - LLCoros::instance().launch("modifyMaterialCoro", std::bind(&LLMaterialEditor::modifyMaterialCoro, mEditor, mCapUrl, overrides)); + LLCoros::instance().launch("modifyMaterialCoro", std::bind(&LLGLTFMaterialList::modifyMaterialCoro, mCapUrl, overrides)); } return true; } @@ -2452,30 +2452,3 @@ void LLMaterialEditor::loadDefaults() setFromGltfModel(model_in, 0, true); } -void LLMaterialEditor::modifyMaterialCoro(std::string cap_url, LLSD overrides) -{ - LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); - LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t - httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("modifyMaterialCoro", httpPolicy)); - LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); - LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); - LLCore::HttpHeaders::ptr_t httpHeaders; - - httpOpts->setFollowRedirects(true); - - LL_DEBUGS() << "Applying override via ModifyMaterialParams cap: " << overrides << LL_ENDL; - - LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, overrides, httpOpts, httpHeaders); - - LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; - LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); - - if (!status) - { - LL_WARNS() << "Failed to modify material." << LL_ENDL; - } - else if (!result["success"].asBoolean()) - { - LL_WARNS() << "Failed to modify material: " << result["message"] << LL_ENDL; - } -} -- cgit v1.2.3 From 0c0b66388fddb70c4e9ac7660ba5dd709bc4cfc9 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 27 Oct 2022 01:42:45 +0300 Subject: SL-18465 Crash opening Material Editor --- indra/newview/llmaterialeditor.cpp | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 7cd9b9198f..7ffa767e37 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -65,7 +65,9 @@ const std::string MATERIAL_NORMAL_DEFAULT_NAME = "Normal"; const std::string MATERIAL_METALLIC_DEFAULT_NAME = "Metallic Roughness"; const std::string MATERIAL_EMISSIVE_DEFAULT_NAME = "Emissive"; -const LLUUID LIVE_MATERIAL_EDITOR_KEY("6cf97162-8b68-49eb-b627-79886c9fd17d"); +// Don't use ids here, LLPreview will attempt to use it as an inventory item +static const std::string LIVE_MATERIAL_EDITOR_KEY = "Live Editor"; +static const std::string SAVE_LIVE_MATERIAL_KEY = "Save Material Editor"; // Dirty flags static const U32 MATERIAL_BASE_COLOR_DIRTY = 0x1 << 0; @@ -1169,6 +1171,12 @@ void LLMaterialEditor::finishSaveAs( void LLMaterialEditor::refreshFromInventory(const LLUUID& new_item_id) { + if (mIsOverride) + { + // refreshFromInventory shouldn't be called for overrides, + // but just in case. + return; + } if (new_item_id.notNull()) { mItemUUID = new_item_id; @@ -1536,11 +1544,12 @@ void LLMaterialEditor::saveLiveValues() void LLMaterialEditor::loadLive() { - LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", LLSD(LIVE_MATERIAL_EDITOR_KEY)); + const LLSD floater_key(LIVE_MATERIAL_EDITOR_KEY); + LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", floater_key); if (me) { - me->setFromSelection(); me->mIsOverride = true; + me->setFromSelection(); me->setTitle(me->getString("material_override_title")); me->childSetVisible("save", false); me->childSetVisible("save_as", false); @@ -1553,19 +1562,20 @@ void LLMaterialEditor::loadLive() // Collect ids to be able to revert overrides on cancel. me->saveLiveValues(); - me->openFloater(); + me->openFloater(floater_key); me->setFocus(TRUE); } } void LLMaterialEditor::loadObjectSave() { - LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", LLSD(LIVE_MATERIAL_EDITOR_KEY)); - if (me->setFromSelection()) + const LLSD floater_key(SAVE_LIVE_MATERIAL_KEY); + LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", floater_key); + if (me && me->setFromSelection()) { me->mIsOverride = false; me->childSetVisible("save", false); - me->openFloater(); + me->openFloater(floater_key); me->setFocus(TRUE); } } @@ -2226,10 +2236,13 @@ bool LLMaterialEditor::setFromSelection() setFromGLTFMaterial(&blank_mat); } - mBaseColorTextureCtrl->setTentative(!identical); - mMetallicTextureCtrl->setTentative(!identical); - mEmissiveTextureCtrl->setTentative(!identical); - mNormalTextureCtrl->setTentative(!identical); + if (mIsOverride) + { + mBaseColorTextureCtrl->setTentative(!identical); + mMetallicTextureCtrl->setTentative(!identical); + mEmissiveTextureCtrl->setTentative(!identical); + mNormalTextureCtrl->setTentative(!identical); + } return mat.notNull(); } -- cgit v1.2.3 From e70cf8edfee32d62392008fcba8ea5e7c0dd112f Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 27 Oct 2022 22:45:24 +0300 Subject: SL-18446 Live editing material should not override objects without pbr Objects without pbr have no base to override --- indra/newview/llmaterialeditor.cpp | 132 +++++++++++++++++++++++++++++-------- 1 file changed, 104 insertions(+), 28 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 7ffa767e37..6fee65201d 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -67,7 +67,6 @@ const std::string MATERIAL_EMISSIVE_DEFAULT_NAME = "Emissive"; // Don't use ids here, LLPreview will attempt to use it as an inventory item static const std::string LIVE_MATERIAL_EDITOR_KEY = "Live Editor"; -static const std::string SAVE_LIVE_MATERIAL_KEY = "Save Material Editor"; // Dirty flags static const U32 MATERIAL_BASE_COLOR_DIRTY = 0x1 << 0; @@ -1507,10 +1506,12 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind } void LLMaterialEditor::onSelectionChanged() { + // This won't get deletion or deselectAll() + // Might need to handle that separately mUnsavedChanges = 0; clearTextures(); setFromSelection(); - saveLiveValues(); + // saveLiveValues(); todo } void LLMaterialEditor::saveLiveValues() @@ -1532,6 +1533,8 @@ void LLMaterialEditor::saveLiveValues() S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); for (U8 te = 0; te < num_tes; te++) { + // Todo: fix this, overrides don't care about ids, + // we will have to save actual values or materials LLUUID mat_id = objectp->getRenderMaterialID(te); mEditor->mObjectOverridesSavedValues[local_id].push_back(mat_id); } @@ -1544,6 +1547,7 @@ void LLMaterialEditor::saveLiveValues() void LLMaterialEditor::loadLive() { + // Allow only one 'live' instance const LLSD floater_key(LIVE_MATERIAL_EDITOR_KEY); LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", floater_key); if (me) @@ -1569,13 +1573,14 @@ void LLMaterialEditor::loadLive() void LLMaterialEditor::loadObjectSave() { - const LLSD floater_key(SAVE_LIVE_MATERIAL_KEY); - LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", floater_key); + LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor"); if (me && me->setFromSelection()) { me->mIsOverride = false; me->childSetVisible("save", false); - me->openFloater(floater_key); + me->mMaterialName = LLTrans::getString("New Material"); + me->setTitle(me->mMaterialName); + me->openFloater(); me->setFocus(TRUE); } } @@ -2053,13 +2058,15 @@ public: if (material.isNull()) { - material = new LLGLTFMaterial(); - } - else - { - material = new LLGLTFMaterial(*material); + // overrides are not supposed to work or apply if + // there is no base material to work from + return false; } + // make a copy to not invalidate existing + // material for multiple objects + material = new LLGLTFMaterial(*material); + // Override object's values with values from editor where appropriate if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_COLOR_DIRTY) { @@ -2206,45 +2213,114 @@ void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat) bool LLMaterialEditor::setFromSelection() { - struct LLSelectedTEGetGLTFRenderMaterial : public LLSelectedTEGetFunctor > + struct LLSelectedTEGetmatIdAndPermissions : public LLSelectedTEFunctor { - LLPointer get(LLViewerObject* objectp, S32 te_index) + LLSelectedTEGetmatIdAndPermissions(bool for_override) + : mIsOverride(for_override) + , mIdenticalTexColor(true) + , mIdenticalTexMetal(true) + , mIdenticalTexEmissive(true) + , mIdenticalTexNormal(true) + , mFirst(true) + {} + + bool apply(LLViewerObject* objectp, S32 te_index) { if (!objectp) { - return nullptr; + return false; } + LLUUID mat_id = objectp->getRenderMaterialID(te_index); + bool can_use = mIsOverride ? objectp->permModify() : objectp->permCopy(); LLTextureEntry *tep = objectp->getTE(te_index); - if (!tep) + // We might want to disable this entirely if at least + // something in selection is no-copy or no modify + // or has no base material + if (can_use && tep && mat_id.notNull()) { - return nullptr; + LLPointer mat = tep->getGLTFRenderMaterial(); + LLUUID tex_color_id; + LLUUID tex_metal_id; + LLUUID tex_emissive_id; + LLUUID tex_normal_id; + llassert(mat.notNull()); // by this point shouldn't be null + if (mat.notNull()) + { + tex_color_id = mat->mBaseColorId; + tex_metal_id = mat->mMetallicRoughnessId; + tex_emissive_id = mat->mEmissiveId; + tex_normal_id = mat->mNormalId; + } + if (mFirst) + { + mMaterial = mat; + mTexColorId = tex_color_id; + mTexMetalId = tex_metal_id; + mTexEmissiveId = tex_emissive_id; + mTexNormalId = tex_normal_id; + mFirst = false; + } + else + { + if (mTexColorId != tex_color_id) + { + mIdenticalTexColor = false; + } + if (mTexMetalId != tex_metal_id) + { + mIdenticalTexMetal = false; + } + if (mTexEmissiveId != tex_emissive_id) + { + mIdenticalTexEmissive = false; + } + if (mTexNormalId != tex_normal_id) + { + mIdenticalTexNormal = false; + } + } } - return tep->getGLTFRenderMaterial(); // present user with combined override + asset + return true; } - } func; - - LLPointer mat; - bool identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&func, mat); - if (mat.notNull()) - { - setFromGLTFMaterial(mat); + bool mIsOverride; + bool mIdenticalTexColor; + bool mIdenticalTexMetal; + bool mIdenticalTexEmissive; + bool mIdenticalTexNormal; + bool mFirst; + LLUUID mTexColorId; + LLUUID mTexMetalId; + LLUUID mTexEmissiveId; + LLUUID mTexNormalId; + LLPointer mMaterial; + } func(mIsOverride); + + LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func); + if (func.mMaterial.notNull()) + { + setFromGLTFMaterial(func.mMaterial); + setEnableEditing(true); } else { // pick defaults from a blank material; LLGLTFMaterial blank_mat; setFromGLTFMaterial(&blank_mat); + if (mIsOverride) + { + setEnableEditing(false); + } } if (mIsOverride) { - mBaseColorTextureCtrl->setTentative(!identical); - mMetallicTextureCtrl->setTentative(!identical); - mEmissiveTextureCtrl->setTentative(!identical); - mNormalTextureCtrl->setTentative(!identical); + mBaseColorTextureCtrl->setTentative(!func.mIdenticalTexColor); + mMetallicTextureCtrl->setTentative(!func.mIdenticalTexMetal); + mEmissiveTextureCtrl->setTentative(!func.mIdenticalTexEmissive); + mNormalTextureCtrl->setTentative(!func.mIdenticalTexNormal); } - return mat.notNull(); + return func.mMaterial.notNull(); } -- cgit v1.2.3 From 29062fd90763d6865db514cfc6c012c08f9621e5 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 27 Oct 2022 23:06:12 +0300 Subject: SL-18441 "Override" UI cleanup --- indra/newview/llmaterialeditor.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 6fee65201d..a8b0fdb3c9 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -227,6 +227,8 @@ LLMaterialEditor::LLMaterialEditor(const LLSD& key) { mAssetID = item->getAssetUUID(); } + // if this is a 'live editor' instance, it uses live overrides + mIsOverride = key.asString() == LIVE_MATERIAL_EDITOR_KEY; } void LLMaterialEditor::setObjectID(const LLUUID& object_id) @@ -293,7 +295,7 @@ BOOL LLMaterialEditor::postBuild() // Emissive childSetCommitCallback("emissive color", changes_callback, (void*)&MATERIAL_EMISIVE_COLOR_DIRTY); - childSetVisible("unsaved_changes", mUnsavedChanges); + childSetVisible("unsaved_changes", mUnsavedChanges && !mIsOverride); getChild("total_upload_fee")->setTextArg("[FEE]", llformat("%d", 0)); @@ -527,7 +529,8 @@ void LLMaterialEditor::resetUnsavedChanges() void LLMaterialEditor::markChangesUnsaved(U32 dirty_flag) { mUnsavedChanges |= dirty_flag; - childSetVisible("unsaved_changes", mUnsavedChanges); + // at the moment live editing (mIsOverride) applies everything 'live' + childSetVisible("unsaved_changes", mUnsavedChanges && !mIsOverride); if (mUnsavedChanges) { @@ -1552,7 +1555,6 @@ void LLMaterialEditor::loadLive() LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", floater_key); if (me) { - me->mIsOverride = true; me->setFromSelection(); me->setTitle(me->getString("material_override_title")); me->childSetVisible("save", false); @@ -1576,7 +1578,6 @@ void LLMaterialEditor::loadObjectSave() LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor"); if (me && me->setFromSelection()) { - me->mIsOverride = false; me->childSetVisible("save", false); me->mMaterialName = LLTrans::getString("New Material"); me->setTitle(me->mMaterialName); -- cgit v1.2.3 From 467c9f627c22dd88d9e9d058583b8279a2c5564e Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 28 Oct 2022 18:45:36 +0300 Subject: SL-18441 Fix logging to be more informative and logcontrol compatible. --- indra/newview/llmaterialeditor.cpp | 49 +++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 17 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index a8b0fdb3c9..1213deec64 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -854,17 +854,21 @@ bool LLMaterialEditor::decodeAsset(const std::vector& buffer) } else { - LL_WARNS() << "Failed to decode material asset: " << LL_ENDL; - LL_WARNS() << warn_msg << LL_ENDL; - LL_WARNS() << error_msg << LL_ENDL; + LL_WARNS("MaterialEditor") << "Floater " << getKey() << " Failed to decode material asset: " << LL_NEWLINE + << warn_msg << LL_NEWLINE + << error_msg << LL_ENDL; } } } } + else + { + LL_WARNS("MaterialEditor") << "Invalid LLSD content "<< asset << " for flaoter " << getKey() << LL_ENDL; + } } else { - LL_WARNS() << "Failed to deserialize material LLSD" << LL_ENDL; + LL_WARNS("MaterialEditor") << "Failed to deserialize material LLSD for flaoter " << getKey() << LL_ENDL; } return false; @@ -1018,7 +1022,7 @@ bool LLMaterialEditor::saveIfNeeded() std::string agent_url(region->getCapability("UpdateMaterialAgentInventory")); if (agent_url.empty()) { - LL_ERRS() << "missing required agent inventory cap url" << LL_ENDL; + LL_ERRS("MaterialEditor") << "missing required agent inventory cap url" << LL_ENDL; } LLViewerAssetUpload::EnqueueInventoryUpload(agent_url, uploadInfo); } @@ -1039,7 +1043,7 @@ bool LLMaterialEditor::saveToInventoryItem(const std::string &buffer, const LLUU const LLViewerRegion* region = gAgent.getRegion(); if (!region) { - LL_WARNS() << "Not connected to a region, cannot save material." << LL_ENDL; + LL_WARNS("MaterialEditor") << "Not connected to a region, cannot save material." << LL_ENDL; return false; } std::string agent_url = region->getCapability("UpdateMaterialAgentInventory"); @@ -1080,7 +1084,7 @@ bool LLMaterialEditor::saveToInventoryItem(const std::string &buffer, const LLUU } else // !gAssetStorage { - LL_WARNS() << "Not connected to an materials capable region." << LL_ENDL; + LL_WARNS("MaterialEditor") << "Not connected to an materials capable region." << LL_ENDL; return false; } @@ -1167,7 +1171,7 @@ void LLMaterialEditor::finishSaveAs( else if (me) { me->setEnabled(true); - LL_WARNS() << "Item does not exist" << LL_ENDL; + LL_WARNS("MaterialEditor") << "Item does not exist, floater " << me->getKey() << LL_ENDL; } } @@ -1177,8 +1181,10 @@ void LLMaterialEditor::refreshFromInventory(const LLUUID& new_item_id) { // refreshFromInventory shouldn't be called for overrides, // but just in case. + LL_WARNS("MaterialEditor") << "Tried to refresh from inventory for live editor" << LL_ENDL; return; } + LLSD old_key = getKey(); if (new_item_id.notNull()) { mItemUUID = new_item_id; @@ -1201,7 +1207,7 @@ void LLMaterialEditor::refreshFromInventory(const LLUUID& new_item_id) setKey(LLSD(new_item_id)); } } - LL_DEBUGS() << "LLPreviewNotecard::refreshFromInventory()" << LL_ENDL; + LL_DEBUGS("MaterialEditor") << "New floater key: " << getKey() << " Old key: " << old_key << LL_ENDL; loadAsset(); } @@ -1392,7 +1398,7 @@ static void pack_textures( if (base_color_img) { base_color_j2c = LLViewerTextureList::convertToUploadFile(base_color_img); - LL_INFOS() << "BaseColor: " << base_color_j2c->getDataSize() << LL_ENDL; + LL_DEBUGS("MaterialEditor") << "BaseColor: " << base_color_j2c->getDataSize() << LL_ENDL; } if (normal_img) @@ -1405,7 +1411,7 @@ static void pack_textures( S32 lossy_bytes = normal_j2c->getDataSize(); S32 lossless_bytes = test->getDataSize(); - LL_INFOS() << llformat("Lossless vs Lossy: (%d/%d) = %.2f", lossless_bytes, lossy_bytes, (F32)lossless_bytes / lossy_bytes) << LL_ENDL; + LL_DEBUGS("MaterialEditor") << llformat("Lossless vs Lossy: (%d/%d) = %.2f", lossless_bytes, lossy_bytes, (F32)lossless_bytes / lossy_bytes) << LL_ENDL; normal_j2c = test; } @@ -1413,13 +1419,13 @@ static void pack_textures( if (mr_img) { mr_j2c = LLViewerTextureList::convertToUploadFile(mr_img); - LL_INFOS() << "Metallic/Roughness: " << mr_j2c->getDataSize() << LL_ENDL; + LL_DEBUGS("MaterialEditor") << "Metallic/Roughness: " << mr_j2c->getDataSize() << LL_ENDL; } if (emissive_img) { emissive_j2c = LLViewerTextureList::convertToUploadFile(emissive_img); - LL_INFOS() << "Emissive: " << emissive_j2c->getDataSize() << LL_ENDL; + LL_DEBUGS("MaterialEditor") << "Emissive: " << emissive_j2c->getDataSize() << LL_ENDL; } } @@ -1590,7 +1596,7 @@ void LLMaterialEditor::loadFromGLTFMaterial(LLUUID &asset_id) { if (asset_id.isNull()) { - LL_WARNS() << "Trying to open material with null id" << LL_ENDL; + LL_WARNS("MaterialEditor") << "Trying to open material with null id" << LL_ENDL; return; } LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor"); @@ -2161,7 +2167,7 @@ void LLMaterialEditor::applyToSelection() } else { - LL_WARNS() << "not connected to materials capable region, missing ModifyMaterialParams cap" << LL_ENDL; + LL_WARNS("MaterialEditor") << "Not connected to materials capable region, missing ModifyMaterialParams cap" << LL_ENDL; // Fallback local preview. Will be removed once override systems is finished and new cap is deployed everywhere. LLPointer mat = new LLFetchedGLTFMaterial(); @@ -2356,6 +2362,7 @@ void LLMaterialEditor::loadAsset() { mAssetID = item->getAssetUUID(); + if (mAssetID.isNull()) { mAssetStatus = PREVIEW_ASSET_LOADED; @@ -2382,7 +2389,7 @@ void LLMaterialEditor::loadAsset() else { // The object that we're trying to look at disappeared, bail. - LL_WARNS() << "Can't find object " << mObjectUUID << " associated with notecard." << LL_ENDL; + LL_WARNS("MaterialEditor") << "Can't find object " << mObjectUUID << " associated with material." << LL_ENDL; mAssetID.setNull(); mAssetStatus = PREVIEW_ASSET_LOADED; resetUnsavedChanges(); @@ -2453,11 +2460,15 @@ void LLMaterialEditor::onLoadComplete(const LLUUID& asset_uuid, LLAssetType::EType type, void* user_data, S32 status, LLExtStat ext_status) { - LL_INFOS() << "LLMaterialEditor::onLoadComplete()" << LL_ENDL; LLSD* floater_key = (LLSD*)user_data; + LL_DEBUGS("MaterialEditor") << "loading " << asset_uuid << " for " << *floater_key << LL_ENDL; LLMaterialEditor* editor = LLFloaterReg::findTypedInstance("material_editor", *floater_key); if (editor) { + if (asset_uuid != editor->mAssetID) + { + LL_WARNS() << "Asset id mismatch, expected: " << editor->mAssetID << " got: " << asset_uuid << LL_ENDL; + } if (0 == status) { LLFileSystem file(asset_uuid, type, LLFileSystem::READ); @@ -2497,6 +2508,10 @@ void LLMaterialEditor::onLoadComplete(const LLUUID& asset_uuid, editor->mAssetStatus = PREVIEW_ASSET_ERROR; } } + else + { + LL_DEBUGS("MaterialEditor") << "Floater " << *floater_key << " does not exist." << LL_ENDL; + } delete floater_key; } -- cgit v1.2.3 From 6d0fcc0e616ff58f4a83bc3730374c5509ee959a Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 28 Oct 2022 19:58:27 +0300 Subject: SL-17699 Blank material Id for material picker --- indra/newview/llmaterialeditor.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 1213deec64..533f882d39 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -2333,11 +2333,6 @@ bool LLMaterialEditor::setFromSelection() void LLMaterialEditor::loadAsset() { - // derived from LLPreviewNotecard::loadAsset - - // TODO: see commented out "editor" references and make them do something appropriate to the UI - - // request the asset. const LLInventoryItem* item; if (mNotecardInventoryID.notNull()) { @@ -2405,6 +2400,7 @@ void LLMaterialEditor::loadAsset() setEnableEditing(false); // wait for it to load + // request the asset. gAssetStorage->getInvItemAsset(source_sim, gAgent.getID(), gAgent.getSessionID(), -- cgit v1.2.3 From 35d4124b5eb3d412643124993b4fa8c09f3f747c Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Sat, 29 Oct 2022 03:16:16 +0300 Subject: SL-18446 Material override arrival for selected objects should update material editor --- indra/newview/llmaterialeditor.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 533f882d39..c10625a45a 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1513,13 +1513,14 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind ); } } + void LLMaterialEditor::onSelectionChanged() { // This won't get deletion or deselectAll() // Might need to handle that separately - mUnsavedChanges = 0; clearTextures(); setFromSelection(); + // At the moment all cahges are 'live' so don't reset dirty flags // saveLiveValues(); todo } @@ -1554,6 +1555,21 @@ void LLMaterialEditor::saveLiveValues() LLSelectMgr::getInstance()->getSelection()->applyToObjects(&savefunc); } +void LLMaterialEditor::updateLive() +{ + const LLSD floater_key(LIVE_MATERIAL_EDITOR_KEY); + LLFloater* instance = LLFloaterReg::findInstance("material_editor", floater_key); + if (instance && LLFloater::isVisible(instance)) + { + LLMaterialEditor* me = (LLMaterialEditor*)instance; + if (me) + { + me->clearTextures(); + me->setFromSelection(); + } + } +} + void LLMaterialEditor::loadLive() { // Allow only one 'live' instance @@ -2164,6 +2180,9 @@ void LLMaterialEditor::applyToSelection() // TODO figure out how to get the right asset id in cases where we don't have a good one LLRenderMaterialOverrideFunctor override_func(this, url); selected_objects->applyToTEs(&override_func); + + // we posted all changes + mUnsavedChanges = 0; } else { -- cgit v1.2.3 From 094a8876d6e030b5dc618ea28250e15022030c78 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 31 Oct 2022 20:12:53 +0200 Subject: SL-18446 Material override arrival filtering --- indra/newview/llmaterialeditor.cpp | 66 +++++++++++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 4 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index c10625a45a..70ba77e18b 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -86,6 +86,9 @@ static const U32 MATERIAL_DOUBLE_SIDED_DIRTY = 0x1 << 9; static const U32 MATERIAL_ALPHA_MODE_DIRTY = 0x1 << 10; static const U32 MATERIAL_ALPHA_CUTOFF_DIRTY = 0x1 << 11; +LLUUID LLMaterialEditor::mOverrideObjectId; +S32 LLMaterialEditor::mOverrideObjectTE = -1; + LLFloaterComboOptions::LLFloaterComboOptions() : LLFloater(LLSD()) { @@ -1518,8 +1521,16 @@ void LLMaterialEditor::onSelectionChanged() { // This won't get deletion or deselectAll() // Might need to handle that separately - clearTextures(); - setFromSelection(); + + // Drop selection updates if we are waiting for + // overrides to finish aplying to not reset values + // (might need a timeout) + if (!mOverrideInProgress) + { + clearTextures(); + setFromSelection(); + } + // At the moment all cahges are 'live' so don't reset dirty flags // saveLiveValues(); todo } @@ -1564,6 +1575,29 @@ void LLMaterialEditor::updateLive() LLMaterialEditor* me = (LLMaterialEditor*)instance; if (me) { + me->mOverrideInProgress = false; + me->clearTextures(); + me->setFromSelection(); + } + } +} + +void LLMaterialEditor::updateLive(const LLUUID &object_id, S32 te) +{ + if (mOverrideObjectId != object_id + || mOverrideObjectTE != te) + { + // Not an update we are waiting for + return; + } + const LLSD floater_key(LIVE_MATERIAL_EDITOR_KEY); + LLFloater* instance = LLFloaterReg::findInstance("material_editor", floater_key); + if (instance && LLFloater::isVisible(instance)) + { + LLMaterialEditor* me = (LLMaterialEditor*)instance; + if (me) + { + me->mOverrideInProgress = false; me->clearTextures(); me->setFromSelection(); } @@ -1577,6 +1611,7 @@ void LLMaterialEditor::loadLive() LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", floater_key); if (me) { + me->mOverrideInProgress = false; me->setFromSelection(); me->setTitle(me->getString("material_override_title")); me->childSetVisible("save", false); @@ -2152,11 +2187,21 @@ public: "side", te, "gltf_json", overrides_json ); - LLCoros::instance().launch("modifyMaterialCoro", std::bind(&LLGLTFMaterialList::modifyMaterialCoro, mCapUrl, overrides)); + LLCoros::instance().launch("modifyMaterialCoro", std::bind(&LLGLTFMaterialList::modifyMaterialCoro, mCapUrl, overrides, modifyCallback)); } return true; } + static void modifyCallback(bool success) + { + if (!success) + { + // something went wrong update selection + LLMaterialEditor::updateLive(); + } + // else we will get updateLive(obj, id) from aplied overrides + } + private: LLMaterialEditor * mEditor; std::string mCapUrl; @@ -2176,10 +2221,14 @@ void LLMaterialEditor::applyToSelection() std::string url = gAgent.getRegionCapability("ModifyMaterialParams"); if (!url.empty()) { + mOverrideInProgress = true; LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); // TODO figure out how to get the right asset id in cases where we don't have a good one LLRenderMaterialOverrideFunctor override_func(this, url); - selected_objects->applyToTEs(&override_func); + if (!selected_objects->applyToTEs(&override_func)) + { + mOverrideInProgress = false; + } // we posted all changes mUnsavedChanges = 0; @@ -2247,6 +2296,7 @@ bool LLMaterialEditor::setFromSelection() , mIdenticalTexMetal(true) , mIdenticalTexEmissive(true) , mIdenticalTexNormal(true) + , mObjectTE(-1) , mFirst(true) {} @@ -2284,6 +2334,8 @@ bool LLMaterialEditor::setFromSelection() mTexMetalId = tex_metal_id; mTexEmissiveId = tex_emissive_id; mTexNormalId = tex_normal_id; + mObjectTE = te_index; + mObjectId = objectp->getID(); mFirst = false; } else @@ -2318,6 +2370,8 @@ bool LLMaterialEditor::setFromSelection() LLUUID mTexMetalId; LLUUID mTexEmissiveId; LLUUID mTexNormalId; + LLUUID mObjectId; + S32 mObjectTE; LLPointer mMaterial; } func(mIsOverride); @@ -2344,6 +2398,10 @@ bool LLMaterialEditor::setFromSelection() mMetallicTextureCtrl->setTentative(!func.mIdenticalTexMetal); mEmissiveTextureCtrl->setTentative(!func.mIdenticalTexEmissive); mNormalTextureCtrl->setTentative(!func.mIdenticalTexNormal); + + // Memorize selection data for filtering further updates + mOverrideObjectId = func.mObjectId; + mOverrideObjectTE = func.mObjectTE; } return func.mMaterial.notNull(); -- cgit v1.2.3 From 4cb5439e425dbfd354a27cbfbfe071904d068d5d Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 31 Oct 2022 21:24:41 +0200 Subject: SL-18446 Don't cause excessive udpates --- indra/newview/llmaterialeditor.cpp | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 70ba77e18b..20fee6686c 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -2221,17 +2221,22 @@ void LLMaterialEditor::applyToSelection() std::string url = gAgent.getRegionCapability("ModifyMaterialParams"); if (!url.empty()) { - mOverrideInProgress = true; - LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); - // TODO figure out how to get the right asset id in cases where we don't have a good one - LLRenderMaterialOverrideFunctor override_func(this, url); - if (!selected_objects->applyToTEs(&override_func)) + // Don't send data if there is nothing to send. + // Some UI elements will cause multiple commits, + // like spin ctrls on click and on down + if (mUnsavedChanges != 0) { - mOverrideInProgress = false; - } + mOverrideInProgress = true; + LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); + LLRenderMaterialOverrideFunctor override_func(this, url); + if (!selected_objects->applyToTEs(&override_func)) + { + mOverrideInProgress = false; + } - // we posted all changes - mUnsavedChanges = 0; + // we posted all changes + mUnsavedChanges = 0; + } } else { -- cgit v1.2.3 From e73c5e4ee38dee244d56f3b58e9595d7d976834a Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 31 Oct 2022 23:15:10 +0200 Subject: SL-18448 Do not show editor when saving material inworld, only a name prompt --- indra/newview/llmaterialeditor.cpp | 367 +++++++++++++++++++++---------------- 1 file changed, 209 insertions(+), 158 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 20fee6686c..44a1991094 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -214,6 +214,103 @@ private: bool mHasUnsavedChanges; }; +///---------------------------------------------------------------------------- +/// Class LLSelectedTEGetMatData +/// For finding selected applicable inworld material +///---------------------------------------------------------------------------- + +struct LLSelectedTEGetMatData : public LLSelectedTEFunctor +{ + LLSelectedTEGetMatData(bool for_override); + + bool apply(LLViewerObject* objectp, S32 te_index); + + bool mIsOverride; + bool mIdenticalTexColor; + bool mIdenticalTexMetal; + bool mIdenticalTexEmissive; + bool mIdenticalTexNormal; + bool mFirst; + LLUUID mTexColorId; + LLUUID mTexMetalId; + LLUUID mTexEmissiveId; + LLUUID mTexNormalId; + LLUUID mObjectId; + S32 mObjectTE; + LLPointer mMaterial; +}; + +LLSelectedTEGetMatData::LLSelectedTEGetMatData(bool for_override) + : mIsOverride(for_override) + , mIdenticalTexColor(true) + , mIdenticalTexMetal(true) + , mIdenticalTexEmissive(true) + , mIdenticalTexNormal(true) + , mObjectTE(-1) + , mFirst(true) +{} + +bool LLSelectedTEGetMatData::apply(LLViewerObject* objectp, S32 te_index) +{ + if (!objectp) + { + return false; + } + LLUUID mat_id = objectp->getRenderMaterialID(te_index); + bool can_use = mIsOverride ? objectp->permModify() : objectp->permCopy(); + LLTextureEntry *tep = objectp->getTE(te_index); + // We might want to disable this entirely if at least + // something in selection is no-copy or no modify + // or has no base material + if (can_use && tep && mat_id.notNull()) + { + LLPointer mat = tep->getGLTFRenderMaterial(); + LLUUID tex_color_id; + LLUUID tex_metal_id; + LLUUID tex_emissive_id; + LLUUID tex_normal_id; + llassert(mat.notNull()); // by this point shouldn't be null + if (mat.notNull()) + { + tex_color_id = mat->mBaseColorId; + tex_metal_id = mat->mMetallicRoughnessId; + tex_emissive_id = mat->mEmissiveId; + tex_normal_id = mat->mNormalId; + } + if (mFirst) + { + mMaterial = mat; + mTexColorId = tex_color_id; + mTexMetalId = tex_metal_id; + mTexEmissiveId = tex_emissive_id; + mTexNormalId = tex_normal_id; + mObjectTE = te_index; + mObjectId = objectp->getID(); + mFirst = false; + } + else + { + if (mTexColorId != tex_color_id) + { + mIdenticalTexColor = false; + } + if (mTexMetalId != tex_metal_id) + { + mIdenticalTexMetal = false; + } + if (mTexEmissiveId != tex_emissive_id) + { + mIdenticalTexEmissive = false; + } + if (mTexNormalId != tex_normal_id) + { + mIdenticalTexNormal = false; + } + } + } + return true; +} + ///---------------------------------------------------------------------------- /// Class LLMaterialEditor ///---------------------------------------------------------------------------- @@ -955,7 +1052,7 @@ bool LLMaterialEditor::saveIfNeeded() // save it out to database if (item) { - if (!saveToInventoryItem(buffer, mItemUUID, mObjectUUID)) + if (!updateInventoryItem(buffer, mItemUUID, mObjectUUID)) { return false; } @@ -971,77 +1068,20 @@ bool LLMaterialEditor::saveIfNeeded() } } else - { //make a new inventory item -#if 1 - // gen a new uuid for this asset - LLTransactionID tid; - tid.generate(); // timestamp-based randomization + uniquification - LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); + { + //make a new inventory item std::string res_desc = buildMaterialDescription(); - U32 next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Materials"); - LLUUID parent = gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_MATERIAL); - const U8 subtype = NO_INV_SUBTYPE; // TODO maybe use AT_SETTINGS and LLSettingsType::ST_MATERIAL ? - - create_inventory_item(gAgent.getID(), gAgent.getSessionID(), parent, tid, mMaterialName, res_desc, - LLAssetType::AT_MATERIAL, LLInventoryType::IT_MATERIAL, subtype, next_owner_perm, - new LLBoostFuncInventoryCallback([output = buffer](LLUUID const& inv_item_id) - { - LLViewerInventoryItem* item = gInventory.getItem(inv_item_id); - if (item) - { - // create_inventory_item doesn't allow presetting some permissions, fix it now - LLPermissions perm = item->getPermissions(); - if (perm.getMaskEveryone() != LLFloaterPerms::getEveryonePerms("Materials") - || perm.getMaskGroup() != LLFloaterPerms::getGroupPerms("Materials")) - { - perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Materials")); - perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Materials")); - - item->setPermissions(perm); - - item->updateServer(FALSE); - gInventory.updateItem(item); - gInventory.notifyObservers(); - } - } - - // from reference in LLSettingsVOBase::createInventoryItem()/updateInventoryItem() - LLResourceUploadInfo::ptr_t uploadInfo = - std::make_shared( - inv_item_id, - LLAssetType::AT_MATERIAL, - output, - [](LLUUID item_id, LLUUID new_asset_id, LLUUID new_item_id, LLSD response) { - LL_INFOS("Material") << "inventory item uploaded. item: " << item_id << " asset: " << new_asset_id << " new_item_id: " << new_item_id << " response: " << response << LL_ENDL; - LLSD params = llsd::map("ASSET_ID", new_asset_id); - LLNotificationsUtil::add("MaterialCreated", params); - }); - - // todo: apply permissions from textures here if server doesn't - // if any texture is 'no transfer', material should be 'no transfer' as well - const LLViewerRegion* region = gAgent.getRegion(); - if (region) - { - std::string agent_url(region->getCapability("UpdateMaterialAgentInventory")); - if (agent_url.empty()) - { - LL_ERRS("MaterialEditor") << "missing required agent inventory cap url" << LL_ENDL; - } - LLViewerAssetUpload::EnqueueInventoryUpload(agent_url, uploadInfo); - } - }) - ); + createInventoryItem(buffer, mMaterialName, res_desc); // We do not update floater with uploaded asset yet, so just close it. closeFloater(); -#endif } return true; } // static -bool LLMaterialEditor::saveToInventoryItem(const std::string &buffer, const LLUUID &item_id, const LLUUID &task_id) +bool LLMaterialEditor::updateInventoryItem(const std::string &buffer, const LLUUID &item_id, const LLUUID &task_id) { const LLViewerRegion* region = gAgent.getRegion(); if (!region) @@ -1097,6 +1137,67 @@ bool LLMaterialEditor::saveToInventoryItem(const std::string &buffer, const LLUU return true; } +void LLMaterialEditor::createInventoryItem(const std::string &buffer, const std::string &name, const std::string &desc) +{ + // gen a new uuid for this asset + LLTransactionID tid; + tid.generate(); // timestamp-based randomization + uniquification + LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); + U32 next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Materials"); + LLUUID parent = gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_MATERIAL); + const U8 subtype = NO_INV_SUBTYPE; // TODO maybe use AT_SETTINGS and LLSettingsType::ST_MATERIAL ? + + create_inventory_item(gAgent.getID(), gAgent.getSessionID(), parent, tid, name, desc, + LLAssetType::AT_MATERIAL, LLInventoryType::IT_MATERIAL, subtype, next_owner_perm, + new LLBoostFuncInventoryCallback([output = buffer](LLUUID const& inv_item_id) + { + LLViewerInventoryItem* item = gInventory.getItem(inv_item_id); + if (item) + { + // create_inventory_item doesn't allow presetting some permissions, fix it now + LLPermissions perm = item->getPermissions(); + if (perm.getMaskEveryone() != LLFloaterPerms::getEveryonePerms("Materials") + || perm.getMaskGroup() != LLFloaterPerms::getGroupPerms("Materials")) + { + perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Materials")); + perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Materials")); + + item->setPermissions(perm); + + item->updateServer(FALSE); + gInventory.updateItem(item); + gInventory.notifyObservers(); + } + } + + // from reference in LLSettingsVOBase::createInventoryItem()/updateInventoryItem() + LLResourceUploadInfo::ptr_t uploadInfo = + std::make_shared( + inv_item_id, + LLAssetType::AT_MATERIAL, + output, + [](LLUUID item_id, LLUUID new_asset_id, LLUUID new_item_id, LLSD response) { + LL_INFOS("Material") << "inventory item uploaded. item: " << item_id << " asset: " << new_asset_id << " new_item_id: " << new_item_id << " response: " << response << LL_ENDL; + LLSD params = llsd::map("ASSET_ID", new_asset_id); + LLNotificationsUtil::add("MaterialCreated", params); + }); + + // todo: apply permissions from textures here if server doesn't + // if any texture is 'no transfer', material should be 'no transfer' as well + const LLViewerRegion* region = gAgent.getRegion(); + if (region) + { + std::string agent_url(region->getCapability("UpdateMaterialAgentInventory")); + if (agent_url.empty()) + { + LL_ERRS("MaterialEditor") << "missing required agent inventory cap url" << LL_ENDL; + } + LLViewerAssetUpload::EnqueueInventoryUpload(agent_url, uploadInfo); + } + }) + ); +} + void LLMaterialEditor::finishInventoryUpload(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId) { // Update the UI with the new asset. @@ -1155,7 +1256,7 @@ void LLMaterialEditor::finishSaveAs( me->setMaterialName(item->getName()); if (has_unsaved_changes) { - if (!saveToInventoryItem(buffer, newItemId, LLUUID::null)) + if (!updateInventoryItem(buffer, newItemId, LLUUID::null)) { me->setEnabled(true); } @@ -1168,7 +1269,7 @@ void LLMaterialEditor::finishSaveAs( } else if(has_unsaved_changes) { - saveToInventoryItem(buffer, newItemId, LLUUID::null); + updateInventoryItem(buffer, newItemId, LLUUID::null); } } else if (me) @@ -1630,16 +1731,51 @@ void LLMaterialEditor::loadLive() } } -void LLMaterialEditor::loadObjectSave() +void LLMaterialEditor::saveObjectsMaterialAs() { - LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor"); - if (me && me->setFromSelection()) + LLSD args; + args["DESC"] = LLTrans::getString("New Material"); + + LLSD payload; + + // Find an applicable material. + // Do this before showing message, because + // message is going to drop selection. + LLSelectedTEGetMatData func(false); + LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func); + + if (func.mMaterial.notNull()) { - me->childSetVisible("save", false); - me->mMaterialName = LLTrans::getString("New Material"); - me->setTitle(me->mMaterialName); - me->openFloater(); - me->setFocus(TRUE); + func.mMaterial; + payload["data"] = func.mMaterial->asJSON(); + } + else + { + // Menu shouldn't allow this, but as a fallback + // pick defaults from a blank material + LLGLTFMaterial blank_mat; + payload["data"] = blank_mat.asJSON(); + LL_WARNS() << "Got no material when trying to save material" << LL_ENDL; + } + + LLNotificationsUtil::add("SaveMaterialAs", args, payload, boost::bind(&LLMaterialEditor::onSaveObjectsMaterialAsMsgCallback, _1, _2)); +} + +void LLMaterialEditor::onSaveObjectsMaterialAsMsgCallback(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (0 == option) + { + LLSD asset; + asset["version"] = "1.0"; + asset["type"] = "GLTF 2.0"; + asset["data"] = notification["payload"]["data"]; + + std::ostringstream str; + LLSDSerialize::serialize(asset, str, LLSDSerialize::LLSD_BINARY); + + std::string new_name = response["message"].asString(); + createInventoryItem(str.str(), new_name, std::string()); } } @@ -2293,92 +2429,7 @@ void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat) bool LLMaterialEditor::setFromSelection() { - struct LLSelectedTEGetmatIdAndPermissions : public LLSelectedTEFunctor - { - LLSelectedTEGetmatIdAndPermissions(bool for_override) - : mIsOverride(for_override) - , mIdenticalTexColor(true) - , mIdenticalTexMetal(true) - , mIdenticalTexEmissive(true) - , mIdenticalTexNormal(true) - , mObjectTE(-1) - , mFirst(true) - {} - - bool apply(LLViewerObject* objectp, S32 te_index) - { - if (!objectp) - { - return false; - } - LLUUID mat_id = objectp->getRenderMaterialID(te_index); - bool can_use = mIsOverride ? objectp->permModify() : objectp->permCopy(); - LLTextureEntry *tep = objectp->getTE(te_index); - // We might want to disable this entirely if at least - // something in selection is no-copy or no modify - // or has no base material - if (can_use && tep && mat_id.notNull()) - { - LLPointer mat = tep->getGLTFRenderMaterial(); - LLUUID tex_color_id; - LLUUID tex_metal_id; - LLUUID tex_emissive_id; - LLUUID tex_normal_id; - llassert(mat.notNull()); // by this point shouldn't be null - if (mat.notNull()) - { - tex_color_id = mat->mBaseColorId; - tex_metal_id = mat->mMetallicRoughnessId; - tex_emissive_id = mat->mEmissiveId; - tex_normal_id = mat->mNormalId; - } - if (mFirst) - { - mMaterial = mat; - mTexColorId = tex_color_id; - mTexMetalId = tex_metal_id; - mTexEmissiveId = tex_emissive_id; - mTexNormalId = tex_normal_id; - mObjectTE = te_index; - mObjectId = objectp->getID(); - mFirst = false; - } - else - { - if (mTexColorId != tex_color_id) - { - mIdenticalTexColor = false; - } - if (mTexMetalId != tex_metal_id) - { - mIdenticalTexMetal = false; - } - if (mTexEmissiveId != tex_emissive_id) - { - mIdenticalTexEmissive = false; - } - if (mTexNormalId != tex_normal_id) - { - mIdenticalTexNormal = false; - } - } - } - return true; - } - bool mIsOverride; - bool mIdenticalTexColor; - bool mIdenticalTexMetal; - bool mIdenticalTexEmissive; - bool mIdenticalTexNormal; - bool mFirst; - LLUUID mTexColorId; - LLUUID mTexMetalId; - LLUUID mTexEmissiveId; - LLUUID mTexNormalId; - LLUUID mObjectId; - S32 mObjectTE; - LLPointer mMaterial; - } func(mIsOverride); + LLSelectedTEGetMatData func(mIsOverride); LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func); if (func.mMaterial.notNull()) -- cgit v1.2.3 From 8faa5a3305a3dad31ee3584aa5404d0ee80923ed Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 31 Oct 2022 17:39:56 -0500 Subject: SL-18448 Fix for mac build. --- indra/newview/llmaterialeditor.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 44a1991094..c99e7307ed 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1746,7 +1746,6 @@ void LLMaterialEditor::saveObjectsMaterialAs() if (func.mMaterial.notNull()) { - func.mMaterial; payload["data"] = func.mMaterial->asJSON(); } else -- cgit v1.2.3 From a4ad75e93c20f140d9503c119201128b0f9e4d0e Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 1 Nov 2022 15:17:22 -0500 Subject: SL-18520 WIP - Use off-by-epsilon and special UUID identifier hacks to allow overriding to default values. --- indra/newview/llmaterialeditor.cpp | 50 ++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 27 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index c99e7307ed..0ae8dcbcf7 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -70,21 +70,20 @@ static const std::string LIVE_MATERIAL_EDITOR_KEY = "Live Editor"; // Dirty flags static const U32 MATERIAL_BASE_COLOR_DIRTY = 0x1 << 0; -static const U32 MATERIAL_BASE_TRANSPARENCY_DIRTY = 0x1 << 1; -static const U32 MATERIAL_BASE_COLOR_TEX_DIRTY = 0x1 << 2; +static const U32 MATERIAL_BASE_COLOR_TEX_DIRTY = 0x1 << 1; -static const U32 MATERIAL_NORMAL_TEX_DIRTY = 0x1 << 3; +static const U32 MATERIAL_NORMAL_TEX_DIRTY = 0x1 << 2; -static const U32 MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY = 0x1 << 4; -static const U32 MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY = 0x1 << 5; -static const U32 MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY = 0x1 << 6; +static const U32 MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY = 0x1 << 3; +static const U32 MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY = 0x1 << 4; +static const U32 MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY = 0x1 << 5; -static const U32 MATERIAL_EMISIVE_COLOR_DIRTY = 0x1 << 7; -static const U32 MATERIAL_EMISIVE_TEX_DIRTY = 0x1 << 8; +static const U32 MATERIAL_EMISIVE_COLOR_DIRTY = 0x1 << 6; +static const U32 MATERIAL_EMISIVE_TEX_DIRTY = 0x1 << 7; -static const U32 MATERIAL_DOUBLE_SIDED_DIRTY = 0x1 << 9; -static const U32 MATERIAL_ALPHA_MODE_DIRTY = 0x1 << 10; -static const U32 MATERIAL_ALPHA_CUTOFF_DIRTY = 0x1 << 11; +static const U32 MATERIAL_DOUBLE_SIDED_DIRTY = 0x1 << 8; +static const U32 MATERIAL_ALPHA_MODE_DIRTY = 0x1 << 9; +static const U32 MATERIAL_ALPHA_CUTOFF_DIRTY = 0x1 << 10; LLUUID LLMaterialEditor::mOverrideObjectId; S32 LLMaterialEditor::mOverrideObjectTE = -1; @@ -384,7 +383,7 @@ BOOL LLMaterialEditor::postBuild() // BaseColor childSetCommitCallback("base color", changes_callback, (void*)&MATERIAL_BASE_COLOR_DIRTY); - childSetCommitCallback("transparency", changes_callback, (void*)&MATERIAL_BASE_TRANSPARENCY_DIRTY); + childSetCommitCallback("transparency", changes_callback, (void*)&MATERIAL_BASE_COLOR_DIRTY); childSetCommitCallback("alpha mode", changes_callback, (void*)&MATERIAL_ALPHA_MODE_DIRTY); childSetCommitCallback("alpha cutoff", changes_callback, (void*)&MATERIAL_ALPHA_CUTOFF_DIRTY); @@ -2263,55 +2262,52 @@ public: // Override object's values with values from editor where appropriate if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_COLOR_DIRTY) { - material->mBaseColor = mEditor->getBaseColor(); - } - if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_TRANSPARENCY_DIRTY) - { - material->mBaseColor.mV[3] = mEditor->getTransparency(); + LLColor4 baseColor = mEditor->getBaseColor(); + material->setBaseColorFactor(mEditor->getBaseColor(), true); } if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_COLOR_TEX_DIRTY) { - material->mBaseColorId = mEditor->getBaseColorId(); + material->setBaseColorId(mEditor->getBaseColorId(), true); } if (mEditor->getUnsavedChangesFlags() & MATERIAL_NORMAL_TEX_DIRTY) { - material->mNormalId = mEditor->getNormalId(); + material->setNormalId(mEditor->getNormalId(), true); } if (mEditor->getUnsavedChangesFlags() & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) { - material->mMetallicRoughnessId = mEditor->getMetallicRoughnessId(); + material->setMetallicRoughnessId(mEditor->getMetallicRoughnessId(), true); } if (mEditor->getUnsavedChangesFlags() & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY) { - material->mMetallicFactor = mEditor->getMetalnessFactor(); + material->setMetallicFactor(mEditor->getMetalnessFactor(), true); } if (mEditor->getUnsavedChangesFlags() & MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY) { - material->mRoughnessFactor = mEditor->getRoughnessFactor(); + material->setRoughnessFactor(mEditor->getRoughnessFactor(), true); } if (mEditor->getUnsavedChangesFlags() & MATERIAL_EMISIVE_COLOR_DIRTY) { - material->mEmissiveColor = mEditor->getEmissiveColor(); + material->setEmissiveColorFactor(LLColor3(mEditor->getEmissiveColor()), true); } if (mEditor->getUnsavedChangesFlags() & MATERIAL_EMISIVE_TEX_DIRTY) { - material->mEmissiveId = mEditor->getEmissiveId(); + material->setEmissiveId(mEditor->getEmissiveId(), true); } if (mEditor->getUnsavedChangesFlags() & MATERIAL_DOUBLE_SIDED_DIRTY) { - material->mDoubleSided = mEditor->getDoubleSided(); + material->setDoubleSided(mEditor->getDoubleSided(), true); } if (mEditor->getUnsavedChangesFlags() & MATERIAL_ALPHA_MODE_DIRTY) { - material->setAlphaMode(mEditor->getAlphaMode()); + material->setAlphaMode(mEditor->getAlphaMode(), true); } if (mEditor->getUnsavedChangesFlags() & MATERIAL_ALPHA_CUTOFF_DIRTY) { - material->mAlphaCutoff = mEditor->getAlphaCutoff(); + material->setAlphaCutoff(mEditor->getAlphaCutoff(), true); } std::string overrides_json = material->asJSON(); -- cgit v1.2.3 From 8c5c07d30749f2abeb475c37b81f9cf089721a1e Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 1 Nov 2022 22:01:45 +0200 Subject: SL-18448 Modified Material Editor to match overrides better --- indra/newview/llmaterialeditor.cpp | 319 ++++++++++++++++--------------------- 1 file changed, 138 insertions(+), 181 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 0ae8dcbcf7..71499ae97b 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -65,9 +65,6 @@ const std::string MATERIAL_NORMAL_DEFAULT_NAME = "Normal"; const std::string MATERIAL_METALLIC_DEFAULT_NAME = "Metallic Roughness"; const std::string MATERIAL_EMISSIVE_DEFAULT_NAME = "Emissive"; -// Don't use ids here, LLPreview will attempt to use it as an inventory item -static const std::string LIVE_MATERIAL_EDITOR_KEY = "Live Editor"; - // Dirty flags static const U32 MATERIAL_BASE_COLOR_DIRTY = 0x1 << 0; static const U32 MATERIAL_BASE_COLOR_TEX_DIRTY = 0x1 << 1; @@ -326,8 +323,6 @@ LLMaterialEditor::LLMaterialEditor(const LLSD& key) { mAssetID = item->getAssetUUID(); } - // if this is a 'live editor' instance, it uses live overrides - mIsOverride = key.asString() == LIVE_MATERIAL_EDITOR_KEY; } void LLMaterialEditor::setObjectID(const LLUUID& object_id) @@ -351,6 +346,10 @@ void LLMaterialEditor::setAuxItem(const LLInventoryItem* item) BOOL LLMaterialEditor::postBuild() { + // if this is a 'live editor' instance, it is also + // single instacne and uses live overrides + mIsOverride = getIsSingleInstance(); + mBaseColorTextureCtrl = getChild("base_color_texture"); mMetallicTextureCtrl = getChild("metallic_roughness_texture"); mEmissiveTextureCtrl = getChild("emissive_texture"); @@ -361,15 +360,28 @@ BOOL LLMaterialEditor::postBuild() mEmissiveTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitEmissiveTexture, this, _1, _2)); mNormalTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitNormalTexture, this, _1, _2)); - childSetAction("save", boost::bind(&LLMaterialEditor::onClickSave, this)); - childSetAction("save_as", boost::bind(&LLMaterialEditor::onClickSaveAs, this)); - childSetAction("cancel", boost::bind(&LLMaterialEditor::onClickCancel, this)); + if (!mIsOverride) + { + childSetAction("save", boost::bind(&LLMaterialEditor::onClickSave, this)); + childSetAction("save_as", boost::bind(&LLMaterialEditor::onClickSaveAs, this)); + childSetAction("cancel", boost::bind(&LLMaterialEditor::onClickCancel, this)); + } - S32 upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(); - getChild("base_color_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); - getChild("metallic_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); - getChild("emissive_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); - getChild("normal_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); + if (mIsOverride) + { + childSetVisible("base_color_upload_fee", FALSE); + childSetVisible("metallic_upload_fee", FALSE); + childSetVisible("emissive_upload_fee", FALSE); + childSetVisible("normal_upload_fee", FALSE); + } + else + { + S32 upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(); + getChild("base_color_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); + getChild("metallic_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); + getChild("emissive_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); + getChild("normal_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); + } boost::function changes_callback = [this](LLUICtrl * ctrl, void* userData) { @@ -394,9 +406,14 @@ BOOL LLMaterialEditor::postBuild() // Emissive childSetCommitCallback("emissive color", changes_callback, (void*)&MATERIAL_EMISIVE_COLOR_DIRTY); - childSetVisible("unsaved_changes", mUnsavedChanges && !mIsOverride); + if (!mIsOverride) + { + // "unsaved_changes" doesn't exist in live editor + childSetVisible("unsaved_changes", mUnsavedChanges); - getChild("total_upload_fee")->setTextArg("[FEE]", llformat("%d", 0)); + // Doesn't exist in live editor + getChild("total_upload_fee")->setTextArg("[FEE]", llformat("%d", 0)); + } // Todo: // Disable/enable setCanApplyImmediately() based on @@ -411,7 +428,7 @@ void LLMaterialEditor::onClickCloseBtn(bool app_quitting) { closeFloater(app_quitting); } - else + else if (!mIsOverride) { onClickCancel(); } @@ -618,18 +635,27 @@ void LLMaterialEditor::setDoubleSided(bool double_sided) void LLMaterialEditor::resetUnsavedChanges() { mUnsavedChanges = 0; - childSetVisible("unsaved_changes", false); - setCanSave(false); + if (!mIsOverride) + { + childSetVisible("unsaved_changes", false); + setCanSave(false); - mExpectedUploadCost = 0; - getChild("total_upload_fee")->setTextArg("[FEE]", llformat("%d", mExpectedUploadCost)); + mExpectedUploadCost = 0; + getChild("total_upload_fee")->setTextArg("[FEE]", llformat("%d", mExpectedUploadCost)); + } } void LLMaterialEditor::markChangesUnsaved(U32 dirty_flag) { mUnsavedChanges |= dirty_flag; - // at the moment live editing (mIsOverride) applies everything 'live' - childSetVisible("unsaved_changes", mUnsavedChanges && !mIsOverride); + if (!mIsOverride) + { + // at the moment live editing (mIsOverride) applies everything 'live' + // and "unsaved_changes", save/cancel buttons don't exist there + return; + } + + childSetVisible("unsaved_changes", mUnsavedChanges); if (mUnsavedChanges) { @@ -673,12 +699,18 @@ void LLMaterialEditor::markChangesUnsaved(U32 dirty_flag) void LLMaterialEditor::setCanSaveAs(bool value) { - childSetEnabled("save_as", value); + if (!mIsOverride) + { + childSetEnabled("save_as", value); + } } void LLMaterialEditor::setCanSave(bool value) { - childSetEnabled("save", value); + if (!mIsOverride) + { + childSetEnabled("save", value); + } } void LLMaterialEditor::setEnableEditing(bool can_modify) @@ -710,21 +742,24 @@ void LLMaterialEditor::setEnableEditing(bool can_modify) void LLMaterialEditor::onCommitBaseColorTexture(LLUICtrl * ctrl, const LLSD & data) { - // might be better to use arrays, to have a single callback - // and not to repeat the same thing for each tecture control - LLUUID new_val = mBaseColorTextureCtrl->getValue().asUUID(); - if (new_val == mBaseColorTextureUploadId && mBaseColorTextureUploadId.notNull()) - { - childSetValue("base_color_upload_fee", getString("upload_fee_string")); - } - else + if (!mIsOverride) { - // Texture picker has 'apply now' with 'cancel' support. - // Keep mBaseColorJ2C and mBaseColorFetched, it's our storage in - // case user decides to cancel changes. - // Without mBaseColorFetched, viewer will eventually cleanup - // the texture that is not in use - childSetValue("base_color_upload_fee", getString("no_upload_fee_string")); + // might be better to use arrays, to have a single callback + // and not to repeat the same thing for each tecture control + LLUUID new_val = mBaseColorTextureCtrl->getValue().asUUID(); + if (new_val == mBaseColorTextureUploadId && mBaseColorTextureUploadId.notNull()) + { + childSetValue("base_color_upload_fee", getString("upload_fee_string")); + } + else + { + // Texture picker has 'apply now' with 'cancel' support. + // Keep mBaseColorJ2C and mBaseColorFetched, it's our storage in + // case user decides to cancel changes. + // Without mBaseColorFetched, viewer will eventually cleanup + // the texture that is not in use + childSetValue("base_color_upload_fee", getString("no_upload_fee_string")); + } } markChangesUnsaved(MATERIAL_BASE_COLOR_TEX_DIRTY); applyToSelection(); @@ -732,14 +767,17 @@ void LLMaterialEditor::onCommitBaseColorTexture(LLUICtrl * ctrl, const LLSD & da void LLMaterialEditor::onCommitMetallicTexture(LLUICtrl * ctrl, const LLSD & data) { - LLUUID new_val = mMetallicTextureCtrl->getValue().asUUID(); - if (new_val == mMetallicTextureUploadId && mMetallicTextureUploadId.notNull()) - { - childSetValue("metallic_upload_fee", getString("upload_fee_string")); - } - else + if (!mIsOverride) { - childSetValue("metallic_upload_fee", getString("no_upload_fee_string")); + LLUUID new_val = mMetallicTextureCtrl->getValue().asUUID(); + if (new_val == mMetallicTextureUploadId && mMetallicTextureUploadId.notNull()) + { + childSetValue("metallic_upload_fee", getString("upload_fee_string")); + } + else + { + childSetValue("metallic_upload_fee", getString("no_upload_fee_string")); + } } markChangesUnsaved(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY); applyToSelection(); @@ -747,14 +785,17 @@ void LLMaterialEditor::onCommitMetallicTexture(LLUICtrl * ctrl, const LLSD & dat void LLMaterialEditor::onCommitEmissiveTexture(LLUICtrl * ctrl, const LLSD & data) { - LLUUID new_val = mEmissiveTextureCtrl->getValue().asUUID(); - if (new_val == mEmissiveTextureUploadId && mEmissiveTextureUploadId.notNull()) - { - childSetValue("emissive_upload_fee", getString("upload_fee_string")); - } - else + if (!mIsOverride) { - childSetValue("emissive_upload_fee", getString("no_upload_fee_string")); + LLUUID new_val = mEmissiveTextureCtrl->getValue().asUUID(); + if (new_val == mEmissiveTextureUploadId && mEmissiveTextureUploadId.notNull()) + { + childSetValue("emissive_upload_fee", getString("upload_fee_string")); + } + else + { + childSetValue("emissive_upload_fee", getString("no_upload_fee_string")); + } } markChangesUnsaved(MATERIAL_EMISIVE_TEX_DIRTY); applyToSelection(); @@ -762,14 +803,17 @@ void LLMaterialEditor::onCommitEmissiveTexture(LLUICtrl * ctrl, const LLSD & dat void LLMaterialEditor::onCommitNormalTexture(LLUICtrl * ctrl, const LLSD & data) { - LLUUID new_val = mNormalTextureCtrl->getValue().asUUID(); - if (new_val == mNormalTextureUploadId && mNormalTextureUploadId.notNull()) - { - childSetValue("normal_upload_fee", getString("upload_fee_string")); - } - else + if (!mIsOverride) { - childSetValue("normal_upload_fee", getString("no_upload_fee_string")); + LLUUID new_val = mNormalTextureCtrl->getValue().asUUID(); + if (new_val == mNormalTextureUploadId && mNormalTextureUploadId.notNull()) + { + childSetValue("normal_upload_fee", getString("upload_fee_string")); + } + else + { + childSetValue("normal_upload_fee", getString("no_upload_fee_string")); + } } markChangesUnsaved(MATERIAL_NORMAL_TEX_DIRTY); applyToSelection(); @@ -1414,73 +1458,6 @@ void LLMaterialEditor::onCancelMsgCallback(const LLSD& notification, const LLSD& S32 option = LLNotificationsUtil::getSelectedOption(notification, response); if (0 == option) { - if (mIsOverride && !mObjectOverridesSavedValues.empty()) - { - // Reapply ids back onto selection. - // TODO: monitor selection changes and resave on selection changes - struct g : public LLSelectedObjectFunctor - { - g(LLMaterialEditor* me) : mEditor(me) {} - virtual bool apply(LLViewerObject* objectp) - { - if (!objectp || !objectp->permModify()) - { - return false; - } - - U32 local_id = objectp->getLocalID(); - if (mEditor->mObjectOverridesSavedValues.find(local_id) == mEditor->mObjectOverridesSavedValues.end()) - { - return false; - } - - S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); - for (U8 te = 0; te < num_tes; te++) - { - if (mEditor->mObjectOverridesSavedValues[local_id].size() > te - && objectp->getTE(te)->isSelected()) - { - objectp->setRenderMaterialID( - te, - mEditor->mObjectOverridesSavedValues[local_id][te], - false /*wait for bulk update*/); - } - } - return true; - } - LLMaterialEditor* mEditor; - } restorefunc(this); - LLSelectMgr::getInstance()->getSelection()->applyToObjects(&restorefunc); - - struct f : public LLSelectedObjectFunctor - { - virtual bool apply(LLViewerObject* object) - { - if (object && !object->permModify()) - { - return false; - } - - LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)object->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL); - if (param_block) - { - if (param_block->isEmpty()) - { - object->setHasRenderMaterialParams(false); - } - else - { - object->parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, true); - } - } - - object->sendTEUpdate(); - return true; - } - } sendfunc; - LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc); - } - closeFloater(); } } @@ -1630,46 +1607,11 @@ void LLMaterialEditor::onSelectionChanged() clearTextures(); setFromSelection(); } - - // At the moment all cahges are 'live' so don't reset dirty flags - // saveLiveValues(); todo -} - -void LLMaterialEditor::saveLiveValues() -{ - // Collect ids to be able to revert overrides. - // TODO: monitor selection changes and resave on selection changes - mObjectOverridesSavedValues.clear(); - struct g : public LLSelectedObjectFunctor - { - g(LLMaterialEditor* me) : mEditor(me) {} - virtual bool apply(LLViewerObject* objectp) - { - if (!objectp) - { - return false; - } - - U32 local_id = objectp->getLocalID(); - S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); - for (U8 te = 0; te < num_tes; te++) - { - // Todo: fix this, overrides don't care about ids, - // we will have to save actual values or materials - LLUUID mat_id = objectp->getRenderMaterialID(te); - mEditor->mObjectOverridesSavedValues[local_id].push_back(mat_id); - } - return true; - } - LLMaterialEditor* mEditor; - } savefunc(this); - LLSelectMgr::getInstance()->getSelection()->applyToObjects(&savefunc); } void LLMaterialEditor::updateLive() { - const LLSD floater_key(LIVE_MATERIAL_EDITOR_KEY); - LLFloater* instance = LLFloaterReg::findInstance("material_editor", floater_key); + LLFloater* instance = LLFloaterReg::findInstance("live_material_editor"); if (instance && LLFloater::isVisible(instance)) { LLMaterialEditor* me = (LLMaterialEditor*)instance; @@ -1690,8 +1632,7 @@ void LLMaterialEditor::updateLive(const LLUUID &object_id, S32 te) // Not an update we are waiting for return; } - const LLSD floater_key(LIVE_MATERIAL_EDITOR_KEY); - LLFloater* instance = LLFloaterReg::findInstance("material_editor", floater_key); + LLFloater* instance = LLFloaterReg::findInstance("live_material_editor"); if (instance && LLFloater::isVisible(instance)) { LLMaterialEditor* me = (LLMaterialEditor*)instance; @@ -1706,26 +1647,19 @@ void LLMaterialEditor::updateLive(const LLUUID &object_id, S32 te) void LLMaterialEditor::loadLive() { - // Allow only one 'live' instance - const LLSD floater_key(LIVE_MATERIAL_EDITOR_KEY); - LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", floater_key); + LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("live_material_editor"); if (me) { me->mOverrideInProgress = false; me->setFromSelection(); - me->setTitle(me->getString("material_override_title")); - me->childSetVisible("save", false); - me->childSetVisible("save_as", false); // Set up for selection changes updates if (!me->mSelectionUpdateSlot.connected()) { me->mSelectionUpdateSlot = LLSelectMgr::instance().mUpdateSignal.connect(boost::bind(&LLMaterialEditor::onSelectionChanged, me)); } - // Collect ids to be able to revert overrides on cancel. - me->saveLiveValues(); - me->openFloater(floater_key); + me->openFloater(); me->setFocus(TRUE); } } @@ -2226,10 +2160,17 @@ private: class LLRenderMaterialOverrideFunctor : public LLSelectedTEFunctor { public: - LLRenderMaterialOverrideFunctor(LLMaterialEditor * me, std::string const & url) - : mEditor(me), mCapUrl(url) + LLRenderMaterialOverrideFunctor( + LLMaterialEditor * me, + std::string const & url, + const LLUUID &report_on_object_id, + S32 report_on_te) + : mEditor(me) + , mCapUrl(url) + , mSuccess(false) + , mObjectId(report_on_object_id) + , mObjectTE(report_on_te) { - } bool apply(LLViewerObject* objectp, S32 te) override @@ -2312,13 +2253,22 @@ public: std::string overrides_json = material->asJSON(); - LLSD overrides = llsd::map( "object_id", objectp->getID(), "side", te, "gltf_json", overrides_json ); - LLCoros::instance().launch("modifyMaterialCoro", std::bind(&LLGLTFMaterialList::modifyMaterialCoro, mCapUrl, overrides, modifyCallback)); + + void(*done_callback)(bool) = nullptr; + if (mObjectTE == te + && mObjectId == objectp->getID()) + { + mSuccess = true; + // We only want callback for face we are displayig material from + // even if we are setting all of them + done_callback = modifyCallback; + } + LLCoros::instance().launch("modifyMaterialCoro", std::bind(&LLGLTFMaterialList::modifyMaterialCoro, mCapUrl, overrides, done_callback)); } return true; } @@ -2330,12 +2280,17 @@ public: // something went wrong update selection LLMaterialEditor::updateLive(); } - // else we will get updateLive(obj, id) from aplied overrides + // else we will get updateLive(obj, id) from applied overrides } + bool getResult() { return mSuccess; } + private: LLMaterialEditor * mEditor; std::string mCapUrl; + LLUUID mObjectId; + S32 mObjectTE; + bool mSuccess; }; void LLMaterialEditor::applyToSelection() @@ -2359,9 +2314,11 @@ void LLMaterialEditor::applyToSelection() { mOverrideInProgress = true; LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); - LLRenderMaterialOverrideFunctor override_func(this, url); - if (!selected_objects->applyToTEs(&override_func)) + LLRenderMaterialOverrideFunctor override_func(this, url, mOverrideObjectId, mOverrideObjectTE); + selected_objects->applyToTEs(&override_func); + if (!override_func.getResult()) { + // OverrideFunctor didn't find expected object or face mOverrideInProgress = false; } -- cgit v1.2.3 From d228a12f4574e649e302b96c415d4fac40c6e7c3 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 1 Nov 2022 22:01:45 +0200 Subject: SL-18448 Fixed exit condition --- indra/newview/llmaterialeditor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 71499ae97b..9b1c06d313 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -424,11 +424,11 @@ BOOL LLMaterialEditor::postBuild() void LLMaterialEditor::onClickCloseBtn(bool app_quitting) { - if (app_quitting) + if (app_quitting || mIsOverride) { closeFloater(app_quitting); } - else if (!mIsOverride) + else { onClickCancel(); } -- cgit v1.2.3 From 613f3738b2effe121ffb15166b4fb7227b0e84ea Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 1 Nov 2022 23:05:03 +0200 Subject: D559 MacOS build fix --- indra/newview/llmaterialeditor.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 9b1c06d313..cb28607903 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -2203,7 +2203,6 @@ public: // Override object's values with values from editor where appropriate if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_COLOR_DIRTY) { - LLColor4 baseColor = mEditor->getBaseColor(); material->setBaseColorFactor(mEditor->getBaseColor(), true); } if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_COLOR_TEX_DIRTY) -- cgit v1.2.3 From c3f94ab9a1da2c0c5304ff624b54fad6a43506ae Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 2 Nov 2022 12:14:56 -0500 Subject: SL-18520 Use GLTF material.extras to pass flags for enabling overriding alpha mode and double sided to default --- indra/newview/llmaterialeditor.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 0ae8dcbcf7..004d61a2ec 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -2312,7 +2312,13 @@ public: std::string overrides_json = material->asJSON(); - +#if 1 + // debug + std::string err, warn; + LLGLTFMaterial debug; + debug.fromJSON(overrides_json, warn, err); +#endif + LLSD overrides = llsd::map( "object_id", objectp->getID(), "side", te, -- cgit v1.2.3 From d042ad67ed4db72bf0265804e26610e565f15cf2 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 2 Nov 2022 19:46:13 +0200 Subject: SL-18448 Make material editor's scroll smarter --- indra/newview/llmaterialeditor.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 792a916e6b..cf627cf992 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -443,6 +443,20 @@ void LLMaterialEditor::onClose(bool app_quitting) LLPreview::onClose(app_quitting); } +void LLMaterialEditor::handleReshape(const LLRect& new_rect, bool by_user) +{ + if (by_user) + { + const LLRect old_rect = getRect(); + LLRect clamp_rect(new_rect); + clamp_rect.mRight = clamp_rect.mLeft + old_rect.getWidth(); + LLPreview::handleReshape(clamp_rect, by_user); + } + else + { + LLPreview::handleReshape(new_rect, by_user); + } +} LLUUID LLMaterialEditor::getBaseColorId() { @@ -648,7 +662,7 @@ void LLMaterialEditor::resetUnsavedChanges() void LLMaterialEditor::markChangesUnsaved(U32 dirty_flag) { mUnsavedChanges |= dirty_flag; - if (!mIsOverride) + if (mIsOverride) { // at the moment live editing (mIsOverride) applies everything 'live' // and "unsaved_changes", save/cancel buttons don't exist there -- cgit v1.2.3 From 0f20cf17fd31abb051efd5bd14399ed6329112cf Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 3 Nov 2022 00:16:20 +0200 Subject: SL-18446 Don't cause excessive udpates #2 --- indra/newview/llmaterialeditor.cpp | 70 ++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 30 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index cf627cf992..00105c1e8f 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -84,6 +84,8 @@ static const U32 MATERIAL_ALPHA_CUTOFF_DIRTY = 0x1 << 10; LLUUID LLMaterialEditor::mOverrideObjectId; S32 LLMaterialEditor::mOverrideObjectTE = -1; +bool LLMaterialEditor::mOverrideInProgress = false; +bool LLMaterialEditor::mSelectionNeedsUpdate = true; LLFloaterComboOptions::LLFloaterComboOptions() : LLFloater(LLSD()) @@ -443,6 +445,27 @@ void LLMaterialEditor::onClose(bool app_quitting) LLPreview::onClose(app_quitting); } + +void LLMaterialEditor::draw() +{ + if (mIsOverride) + { + bool selection_empty = LLSelectMgr::getInstance()->getSelection()->isEmpty(); + if (selection_empty && mHasSelection) + { + mSelectionNeedsUpdate = true; + } + + if (mSelectionNeedsUpdate) + { + mSelectionNeedsUpdate = false; + clearTextures(); + setFromSelection(); + } + } + LLPreview::draw(); +} + void LLMaterialEditor::handleReshape(const LLRect& new_rect, bool by_user) { if (by_user) @@ -1610,32 +1633,20 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind void LLMaterialEditor::onSelectionChanged() { - // This won't get deletion or deselectAll() - // Might need to handle that separately - // Drop selection updates if we are waiting for - // overrides to finish aplying to not reset values + // overrides to finish applying to not reset values // (might need a timeout) if (!mOverrideInProgress) { - clearTextures(); - setFromSelection(); + // mUpdateSignal triggers a lot per frame, breakwater + mSelectionNeedsUpdate = true; } } void LLMaterialEditor::updateLive() { - LLFloater* instance = LLFloaterReg::findInstance("live_material_editor"); - if (instance && LLFloater::isVisible(instance)) - { - LLMaterialEditor* me = (LLMaterialEditor*)instance; - if (me) - { - me->mOverrideInProgress = false; - me->clearTextures(); - me->setFromSelection(); - } - } + mSelectionNeedsUpdate = true; + mOverrideInProgress = false; } void LLMaterialEditor::updateLive(const LLUUID &object_id, S32 te) @@ -1643,20 +1654,15 @@ void LLMaterialEditor::updateLive(const LLUUID &object_id, S32 te) if (mOverrideObjectId != object_id || mOverrideObjectTE != te) { - // Not an update we are waiting for + // Ignore if waiting for override, + // if not waiting, mark selection dirty + mSelectionNeedsUpdate |= !mOverrideInProgress; return; } - LLFloater* instance = LLFloaterReg::findInstance("live_material_editor"); - if (instance && LLFloater::isVisible(instance)) - { - LLMaterialEditor* me = (LLMaterialEditor*)instance; - if (me) - { - me->mOverrideInProgress = false; - me->clearTextures(); - me->setFromSelection(); - } - } + + // update for currently displayed object and face + mSelectionNeedsUpdate = true; + mOverrideInProgress = false; } void LLMaterialEditor::loadLive() @@ -2401,9 +2407,13 @@ void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat) bool LLMaterialEditor::setFromSelection() { + LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); LLSelectedTEGetMatData func(mIsOverride); - LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func); + selected_objects->applyToTEs(&func); + mHasSelection = !selected_objects->isEmpty(); + mSelectionNeedsUpdate = false; + if (func.mMaterial.notNull()) { setFromGLTFMaterial(func.mMaterial); -- cgit v1.2.3 From a0c7a7ecdc7b9fb53fa1175babf0d8497a3e9112 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Thu, 3 Nov 2022 13:18:14 +0200 Subject: SL-18548 fix for crash when trying to Save material without caps --- indra/newview/llmaterialeditor.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 00105c1e8f..397a302069 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -883,6 +883,11 @@ static U32 write_texture(const LLUUID& id, tinygltf::Model& model) void LLMaterialEditor::onClickSave() { + if (!capabilitiesAvalaible()) + { + LLNotificationsUtil::add("MissingMaterialCaps"); + return; + } if (!can_afford_transaction(mExpectedUploadCost)) { LLSD args; @@ -2809,3 +2814,17 @@ void LLMaterialEditor::loadDefaults() setFromGltfModel(model_in, 0, true); } +bool LLMaterialEditor::capabilitiesAvalaible() +{ + const LLViewerRegion* region = gAgent.getRegion(); + if (!region) + { + LL_WARNS("MaterialEditor") << "Not connected to a region, cannot save material." << LL_ENDL; + return false; + } + std::string agent_url = region->getCapability("UpdateMaterialAgentInventory"); + std::string task_url = region->getCapability("UpdateMaterialTaskInventory"); + + return (!agent_url.empty() && !task_url.empty()); +} + -- cgit v1.2.3 From 11c87378be68d9102d7dcf94d714b3c5c1923952 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 4 Nov 2022 18:57:48 +0200 Subject: SL-18560 Make local materials save correctly from right-click menu --- indra/newview/llmaterialeditor.cpp | 150 +++++++++++++++++++++++++++---------- 1 file changed, 111 insertions(+), 39 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 397a302069..9173981c01 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -36,6 +36,7 @@ #include "llfilesystem.h" #include "llgltfmateriallist.h" #include "llinventorymodel.h" +#include "lllocalgltfmaterials.h" #include "llnotificationsutil.h" #include "lltexturectrl.h" #include "lltrans.h" @@ -236,6 +237,7 @@ struct LLSelectedTEGetMatData : public LLSelectedTEFunctor LLUUID mObjectId; S32 mObjectTE; LLPointer mMaterial; + LLPointer mLocalMaterial; }; LLSelectedTEGetMatData::LLSelectedTEGetMatData(bool for_override) @@ -262,48 +264,63 @@ bool LLSelectedTEGetMatData::apply(LLViewerObject* objectp, S32 te_index) // or has no base material if (can_use && tep && mat_id.notNull()) { - LLPointer mat = tep->getGLTFRenderMaterial(); - LLUUID tex_color_id; - LLUUID tex_metal_id; - LLUUID tex_emissive_id; - LLUUID tex_normal_id; - llassert(mat.notNull()); // by this point shouldn't be null - if (mat.notNull()) - { - tex_color_id = mat->mBaseColorId; - tex_metal_id = mat->mMetallicRoughnessId; - tex_emissive_id = mat->mEmissiveId; - tex_normal_id = mat->mNormalId; - } - if (mFirst) - { - mMaterial = mat; - mTexColorId = tex_color_id; - mTexMetalId = tex_metal_id; - mTexEmissiveId = tex_emissive_id; - mTexNormalId = tex_normal_id; - mObjectTE = te_index; - mObjectId = objectp->getID(); - mFirst = false; - } - else + if (mIsOverride) { - if (mTexColorId != tex_color_id) + LLPointer mat = tep->getGLTFRenderMaterial(); + + LLUUID tex_color_id; + LLUUID tex_metal_id; + LLUUID tex_emissive_id; + LLUUID tex_normal_id; + llassert(mat.notNull()); // by this point shouldn't be null + if (mat.notNull()) { - mIdenticalTexColor = false; + tex_color_id = mat->mBaseColorId; + tex_metal_id = mat->mMetallicRoughnessId; + tex_emissive_id = mat->mEmissiveId; + tex_normal_id = mat->mNormalId; } - if (mTexMetalId != tex_metal_id) + if (mFirst) { - mIdenticalTexMetal = false; + mMaterial = mat; + mTexColorId = tex_color_id; + mTexMetalId = tex_metal_id; + mTexEmissiveId = tex_emissive_id; + mTexNormalId = tex_normal_id; + mObjectTE = te_index; + mObjectId = objectp->getID(); + mFirst = false; } - if (mTexEmissiveId != tex_emissive_id) + else { - mIdenticalTexEmissive = false; + if (mTexColorId != tex_color_id) + { + mIdenticalTexColor = false; + } + if (mTexMetalId != tex_metal_id) + { + mIdenticalTexMetal = false; + } + if (mTexEmissiveId != tex_emissive_id) + { + mIdenticalTexEmissive = false; + } + if (mTexNormalId != tex_normal_id) + { + mIdenticalTexNormal = false; + } } - if (mTexNormalId != tex_normal_id) + } + else + { + LLGLTFMaterial *mat = tep->getGLTFMaterial(); + LLLocalGLTFMaterial *local_mat = dynamic_cast(mat); + + if (local_mat) { - mIdenticalTexNormal = false; + mLocalMaterial = local_mat; } + mMaterial = tep->getGLTFRenderMaterial(); } } return true; @@ -349,7 +366,7 @@ void LLMaterialEditor::setAuxItem(const LLInventoryItem* item) BOOL LLMaterialEditor::postBuild() { // if this is a 'live editor' instance, it is also - // single instacne and uses live overrides + // single instance and uses live overrides mIsOverride = getIsSingleInstance(); mBaseColorTextureCtrl = getChild("base_color_texture"); @@ -1691,17 +1708,69 @@ void LLMaterialEditor::loadLive() void LLMaterialEditor::saveObjectsMaterialAs() { - LLSD args; - args["DESC"] = LLTrans::getString("New Material"); - - LLSD payload; // Find an applicable material. // Do this before showing message, because // message is going to drop selection. LLSelectedTEGetMatData func(false); - LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func); + LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func, true /*first applicable*/); + if (func.mLocalMaterial.notNull()) + { + // This is a local material, reload it from file + // so that user won't end up with grey textures + // on next login. + LLMaterialEditor::loadMaterialFromFile(func.mLocalMaterial->getFilename(), func.mLocalMaterial->getIndexInFile()); + + LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor"); + if (me) + { + // apply differences on top + LLGLTFMaterial* local_mat = func.mLocalMaterial.get(); + // don't use override mat here, it has 'hacked ids' + // and values, use end result. + LLGLTFMaterial* cmp_mat = func.mMaterial.get(); + + me->setBaseColor(cmp_mat->mBaseColor); + me->setMetalnessFactor(cmp_mat->mMetallicFactor); + me->setRoughnessFactor(cmp_mat->mRoughnessFactor); + me->setEmissiveColor(cmp_mat->mEmissiveColor); + me->setDoubleSided(cmp_mat->mDoubleSided); + me->setAlphaMode(cmp_mat->getAlphaMode()); + me->setAlphaCutoff(cmp_mat->mAlphaCutoff); + + // most things like colors we can apply without verifying + // but texture ids are going to be different from both, base and override + // so only apply override id if there is actually a difference + if (local_mat->mBaseColorId != cmp_mat->mBaseColorId) + { + me->setBaseColorId(cmp_mat->mBaseColorId); + me->childSetValue("base_color_upload_fee", me->getString("no_upload_fee_string")); + } + if (local_mat->mNormalId != cmp_mat->mNormalId) + { + me->setNormalId(cmp_mat->mNormalId); + me->childSetValue("normal_upload_fee", me->getString("no_upload_fee_string")); + } + if (local_mat->mMetallicRoughnessId != cmp_mat->mMetallicRoughnessId) + { + me->setMetallicRoughnessId(cmp_mat->mMetallicRoughnessId); + me->childSetValue("metallic_upload_fee", me->getString("no_upload_fee_string")); + } + if (local_mat->mEmissiveId != cmp_mat->mEmissiveId) + { + me->setEmissiveId(cmp_mat->mEmissiveId); + me->childSetValue("emissive_upload_fee", me->getString("no_upload_fee_string")); + } + + // recalculate upload prices + me->markChangesUnsaved(0); + } + + return; + } + + LLSD payload; if (func.mMaterial.notNull()) { payload["data"] = func.mMaterial->asJSON(); @@ -1715,6 +1784,9 @@ void LLMaterialEditor::saveObjectsMaterialAs() LL_WARNS() << "Got no material when trying to save material" << LL_ENDL; } + LLSD args; + args["DESC"] = LLTrans::getString("New Material"); + LLNotificationsUtil::add("SaveMaterialAs", args, payload, boost::bind(&LLMaterialEditor::onSaveObjectsMaterialAsMsgCallback, _1, _2)); } -- cgit v1.2.3 From 080421decbac73c85d878b7e734ad4e2cfb0f251 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 8 Nov 2022 01:22:08 +0200 Subject: SL-18583 Make Live Material editor restore changes when canceling in texture or color pickers --- indra/newview/llmaterialeditor.cpp | 311 ++++++++++++++++++++++++++++--------- 1 file changed, 234 insertions(+), 77 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 9173981c01..7a23d8da37 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -31,6 +31,7 @@ #include "llagent.h" #include "llagentbenefits.h" #include "llappviewer.h" +#include "llcolorswatch.h" #include "llcombobox.h" #include "llfloaterreg.h" #include "llfilesystem.h" @@ -334,6 +335,7 @@ bool LLSelectedTEGetMatData::apply(LLViewerObject* objectp, S32 te_index) LLMaterialEditor::LLMaterialEditor(const LLSD& key) : LLPreview(key) , mUnsavedChanges(0) + , mRevertedChanges(0) , mExpectedUploadCost(0) , mUploadingTexturesCount(0) { @@ -373,11 +375,28 @@ BOOL LLMaterialEditor::postBuild() mMetallicTextureCtrl = getChild("metallic_roughness_texture"); mEmissiveTextureCtrl = getChild("emissive_texture"); mNormalTextureCtrl = getChild("normal_texture"); + mBaseColorCtrl = getChild("base color"); + mEmissiveColorCtrl = getChild("emissive color"); - mBaseColorTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitBaseColorTexture, this, _1, _2)); - mMetallicTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitMetallicTexture, this, _1, _2)); - mEmissiveTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitEmissiveTexture, this, _1, _2)); - mNormalTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitNormalTexture, this, _1, _2)); + mBaseColorTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitTexture, this, _1, _2, MATERIAL_BASE_COLOR_TEX_DIRTY)); + mMetallicTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitTexture, this, _1, _2, MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY)); + mEmissiveTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitTexture, this, _1, _2, MATERIAL_EMISIVE_TEX_DIRTY)); + mNormalTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitTexture, this, _1, _2, MATERIAL_NORMAL_TEX_DIRTY)); + + if (mIsOverride) + { + // Live editing needs a recovery mechanism on cancel + mBaseColorTextureCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_BASE_COLOR_TEX_DIRTY)); + mMetallicTextureCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY)); + mEmissiveTextureCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_EMISIVE_TEX_DIRTY)); + mNormalTextureCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_NORMAL_TEX_DIRTY)); + + // Save applied changes on 'OK' to our recovery mechanism. + mBaseColorTextureCtrl->setOnSelectCallback(boost::bind(&LLMaterialEditor::onSelectCtrl, this, _1, _2, MATERIAL_BASE_COLOR_TEX_DIRTY)); + mMetallicTextureCtrl->setOnSelectCallback(boost::bind(&LLMaterialEditor::onSelectCtrl, this, _1, _2, MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY)); + mEmissiveTextureCtrl->setOnSelectCallback(boost::bind(&LLMaterialEditor::onSelectCtrl, this, _1, _2, MATERIAL_EMISIVE_TEX_DIRTY)); + mNormalTextureCtrl->setOnSelectCallback(boost::bind(&LLMaterialEditor::onSelectCtrl, this, _1, _2, MATERIAL_NORMAL_TEX_DIRTY)); + } if (!mIsOverride) { @@ -413,7 +432,13 @@ BOOL LLMaterialEditor::postBuild() childSetCommitCallback("double sided", changes_callback, (void*)&MATERIAL_DOUBLE_SIDED_DIRTY); // BaseColor - childSetCommitCallback("base color", changes_callback, (void*)&MATERIAL_BASE_COLOR_DIRTY); + mBaseColorCtrl->setCommitCallback(changes_callback, (void*)&MATERIAL_BASE_COLOR_DIRTY); + if (mIsOverride) + { + mBaseColorCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_BASE_COLOR_DIRTY)); + mBaseColorCtrl->setOnSelectCallback(boost::bind(&LLMaterialEditor::onSelectCtrl, this, _1, _2, MATERIAL_BASE_COLOR_DIRTY)); + } + // transparency is a part of base color childSetCommitCallback("transparency", changes_callback, (void*)&MATERIAL_BASE_COLOR_DIRTY); childSetCommitCallback("alpha mode", changes_callback, (void*)&MATERIAL_ALPHA_MODE_DIRTY); childSetCommitCallback("alpha cutoff", changes_callback, (void*)&MATERIAL_ALPHA_CUTOFF_DIRTY); @@ -423,7 +448,12 @@ BOOL LLMaterialEditor::postBuild() childSetCommitCallback("roughness factor", changes_callback, (void*)&MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY); // Emissive - childSetCommitCallback("emissive color", changes_callback, (void*)&MATERIAL_EMISIVE_COLOR_DIRTY); + mEmissiveColorCtrl->setCommitCallback(changes_callback, (void*)&MATERIAL_EMISIVE_COLOR_DIRTY); + if (mIsOverride) + { + mEmissiveColorCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_EMISIVE_COLOR_DIRTY)); + mEmissiveColorCtrl->setOnSelectCallback(boost::bind(&LLMaterialEditor::onSelectCtrl, this, _1, _2, MATERIAL_EMISIVE_COLOR_DIRTY)); + } if (!mIsOverride) { @@ -527,14 +557,14 @@ void LLMaterialEditor::setBaseColorUploadId(const LLUUID& id) LLColor4 LLMaterialEditor::getBaseColor() { - LLColor4 ret = linearColor4(LLColor4(childGetValue("base color"))); + LLColor4 ret = linearColor4(LLColor4(mBaseColorCtrl->getValue())); ret.mV[3] = getTransparency(); return ret; } void LLMaterialEditor::setBaseColor(const LLColor4& color) { - childSetValue("base color", srgbColor4(color).getValue()); + mBaseColorCtrl->setValue(srgbColor4(color).getValue()); setTransparency(color.mV[3]); } @@ -644,12 +674,12 @@ void LLMaterialEditor::setEmissiveUploadId(const LLUUID& id) LLColor4 LLMaterialEditor::getEmissiveColor() { - return linearColor4(LLColor4(childGetValue("emissive color"))); + return linearColor4(LLColor4(mEmissiveColorCtrl->getValue())); } void LLMaterialEditor::setEmissiveColor(const LLColor4& color) { - childSetValue("emissive color", srgbColor4(color).getValue()); + mEmissiveColorCtrl->setValue(srgbColor4(color).getValue()); } LLUUID LLMaterialEditor::getNormalId() @@ -689,6 +719,7 @@ void LLMaterialEditor::setDoubleSided(bool double_sided) void LLMaterialEditor::resetUnsavedChanges() { mUnsavedChanges = 0; + mRevertedChanges = 0; if (!mIsOverride) { childSetVisible("unsaved_changes", false); @@ -794,85 +825,142 @@ void LLMaterialEditor::setEnableEditing(bool can_modify) mNormalTextureCtrl->setEnabled(can_modify); } -void LLMaterialEditor::onCommitBaseColorTexture(LLUICtrl * ctrl, const LLSD & data) +void LLMaterialEditor::onCommitTexture(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag) { if (!mIsOverride) { - // might be better to use arrays, to have a single callback - // and not to repeat the same thing for each tecture control - LLUUID new_val = mBaseColorTextureCtrl->getValue().asUUID(); - if (new_val == mBaseColorTextureUploadId && mBaseColorTextureUploadId.notNull()) + std::string upload_fee_ctrl_name; + LLUUID old_uuid; + + switch (dirty_flag) + { + case MATERIAL_BASE_COLOR_TEX_DIRTY: + { + upload_fee_ctrl_name = "base_color_upload_fee"; + old_uuid = mBaseColorTextureUploadId; + break; + } + case MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY: { - childSetValue("base_color_upload_fee", getString("upload_fee_string")); + upload_fee_ctrl_name = "metallic_upload_fee"; + old_uuid = mMetallicTextureUploadId; + break; + } + case MATERIAL_EMISIVE_TEX_DIRTY: + { + upload_fee_ctrl_name = "emissive_upload_fee"; + old_uuid = mEmissiveTextureUploadId; + break; + } + case MATERIAL_NORMAL_TEX_DIRTY: + { + upload_fee_ctrl_name = "normal_upload_fee"; + old_uuid = mNormalTextureUploadId; + break; + } + default: + break; + } + LLUUID new_val = ctrl->getValue().asUUID(); + if (new_val == old_uuid && old_uuid.notNull()) + { + childSetValue(upload_fee_ctrl_name, getString("upload_fee_string")); } else { // Texture picker has 'apply now' with 'cancel' support. - // Keep mBaseColorJ2C and mBaseColorFetched, it's our storage in - // case user decides to cancel changes. + // Don't clean mBaseColorJ2C and mBaseColorFetched, it's our + // storage in case user decides to cancel changes. // Without mBaseColorFetched, viewer will eventually cleanup // the texture that is not in use - childSetValue("base_color_upload_fee", getString("no_upload_fee_string")); + childSetValue(upload_fee_ctrl_name, getString("no_upload_fee_string")); } } - markChangesUnsaved(MATERIAL_BASE_COLOR_TEX_DIRTY); + + markChangesUnsaved(dirty_flag); applyToSelection(); } -void LLMaterialEditor::onCommitMetallicTexture(LLUICtrl * ctrl, const LLSD & data) +void LLMaterialEditor::onCancelCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag) { - if (!mIsOverride) - { - LLUUID new_val = mMetallicTextureCtrl->getValue().asUUID(); - if (new_val == mMetallicTextureUploadId && mMetallicTextureUploadId.notNull()) - { - childSetValue("metallic_upload_fee", getString("upload_fee_string")); - } - else - { - childSetValue("metallic_upload_fee", getString("no_upload_fee_string")); - } - } - markChangesUnsaved(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY); + mRevertedChanges |= dirty_flag; applyToSelection(); } -void LLMaterialEditor::onCommitEmissiveTexture(LLUICtrl * ctrl, const LLSD & data) +void LLMaterialEditor::onSelectCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag) { - if (!mIsOverride) - { - LLUUID new_val = mEmissiveTextureCtrl->getValue().asUUID(); - if (new_val == mEmissiveTextureUploadId && mEmissiveTextureUploadId.notNull()) - { - childSetValue("emissive_upload_fee", getString("upload_fee_string")); - } - else - { - childSetValue("emissive_upload_fee", getString("no_upload_fee_string")); - } - } - markChangesUnsaved(MATERIAL_EMISIVE_TEX_DIRTY); + mUnsavedChanges |= dirty_flag; applyToSelection(); -} -void LLMaterialEditor::onCommitNormalTexture(LLUICtrl * ctrl, const LLSD & data) -{ - if (!mIsOverride) + struct f : public LLSelectedNodeFunctor { - LLUUID new_val = mNormalTextureCtrl->getValue().asUUID(); - if (new_val == mNormalTextureUploadId && mNormalTextureUploadId.notNull()) + f(LLUICtrl* ctrl, S32 dirty_flag) : mCtrl(ctrl), mDirtyFlag(dirty_flag) { - childSetValue("normal_upload_fee", getString("upload_fee_string")); } - else + + virtual bool apply(LLSelectNode* nodep) { - childSetValue("normal_upload_fee", getString("no_upload_fee_string")); + LLViewerObject* objectp = nodep->getObject(); + if (!objectp) + { + return false; + } + S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); // avatars have TEs but no faces + for (S32 te = 0; te < num_tes; ++te) + { + if (nodep->isTESelected(te) && nodep->mSavedGLTFRenderMaterials.size() > te) + { + switch (mDirtyFlag) + { + //Textures + case MATERIAL_BASE_COLOR_TEX_DIRTY: + { + nodep->mSavedGLTFRenderMaterials[te]->mBaseColorId = mCtrl->getValue().asUUID(); + break; + } + case MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY: + { + nodep->mSavedGLTFRenderMaterials[te]->mMetallicRoughnessId = mCtrl->getValue().asUUID(); + break; + } + case MATERIAL_EMISIVE_TEX_DIRTY: + { + nodep->mSavedGLTFRenderMaterials[te]->mEmissiveId = mCtrl->getValue().asUUID(); + break; + } + case MATERIAL_NORMAL_TEX_DIRTY: + { + nodep->mSavedGLTFRenderMaterials[te]->mNormalId = mCtrl->getValue().asUUID(); + break; + } + // Colors + case MATERIAL_BASE_COLOR_DIRTY: + { + LLColor4 ret = linearColor4(LLColor4(mCtrl->getValue())); + // except transparency + ret.mV[3] = nodep->mSavedGLTFRenderMaterials[te]->mBaseColor.mV[3]; + nodep->mSavedGLTFRenderMaterials[te]->mBaseColor = ret; + break; + } + case MATERIAL_EMISIVE_COLOR_DIRTY: + { + nodep->mSavedGLTFRenderMaterials[te]->mEmissiveColor = LLColor4(mCtrl->getValue()); + break; + } + default: + break; + } + } + } + return true; } - } - markChangesUnsaved(MATERIAL_NORMAL_TEX_DIRTY); - applyToSelection(); -} + LLUICtrl* mCtrl; + S32 mDirtyFlag; + } func(ctrl, dirty_flag); + + LLSelectMgr::getInstance()->getSelection()->applyToNodes(&func); +} static void write_color(const LLColor4& color, std::vector& c) { @@ -2254,7 +2342,7 @@ private: LLUUID mMatId; }; -class LLRenderMaterialOverrideFunctor : public LLSelectedTEFunctor +class LLRenderMaterialOverrideFunctor : public LLSelectedNodeFunctor { public: LLRenderMaterialOverrideFunctor( @@ -2270,16 +2358,29 @@ public: { } - bool apply(LLViewerObject* objectp, S32 te) override + virtual bool apply(LLSelectNode* nodep) override { + LLViewerObject* objectp = nodep->getObject(); + if (!objectp || !objectp->permModify() || !objectp->getVolume()) + { + return false; + } + S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); // avatars have TEs but no faces + // post override from given object and te to the simulator // requestData should have: // object_id - UUID of LLViewerObject // side - S32 index of texture entry // gltf_json - String of GLTF json for override data - if (objectp && objectp->permModify() && objectp->getVolume()) + for (S32 te = 0; te < num_tes; ++te) { + if (!nodep->isTESelected(te)) + { + continue; + } + + // Get material from object // Selection can cover multiple objects, and live editor is // supposed to overwrite changed values only @@ -2293,59 +2394,114 @@ public: return false; } + // make a copy to not invalidate existing // material for multiple objects material = new LLGLTFMaterial(*material); + U32 changed_flags = mEditor->getUnsavedChangesFlags(); + U32 reverted_flags = mEditor->getRevertedChangesFlags(); + bool can_revert = nodep->mSavedGLTFRenderMaterials.size() > te; + // Override object's values with values from editor where appropriate - if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_COLOR_DIRTY) + if (changed_flags & MATERIAL_BASE_COLOR_DIRTY) { material->setBaseColorFactor(mEditor->getBaseColor(), true); } - if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_COLOR_TEX_DIRTY) + else if ((reverted_flags & MATERIAL_BASE_COLOR_DIRTY) && can_revert) + { + material->setBaseColorFactor(nodep->mSavedGLTFRenderMaterials[te]->mBaseColor, true); + } + + if (changed_flags & MATERIAL_BASE_COLOR_TEX_DIRTY) { material->setBaseColorId(mEditor->getBaseColorId(), true); } + else if ((reverted_flags & MATERIAL_BASE_COLOR_TEX_DIRTY) && can_revert) + { + material->setBaseColorId(nodep->mSavedGLTFRenderMaterials[te]->mBaseColorId, true); + } - if (mEditor->getUnsavedChangesFlags() & MATERIAL_NORMAL_TEX_DIRTY) + if (changed_flags & MATERIAL_NORMAL_TEX_DIRTY) { material->setNormalId(mEditor->getNormalId(), true); } + else if ((reverted_flags & MATERIAL_NORMAL_TEX_DIRTY) && can_revert) + { + material->setNormalId(nodep->mSavedGLTFRenderMaterials[te]->mNormalId, true); + } - if (mEditor->getUnsavedChangesFlags() & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) + if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) { material->setMetallicRoughnessId(mEditor->getMetallicRoughnessId(), true); } - if (mEditor->getUnsavedChangesFlags() & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY) + else if ((reverted_flags & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) && can_revert) + { + material->setMetallicRoughnessId(nodep->mSavedGLTFRenderMaterials[te]->mMetallicRoughnessId, true); + } + + if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY) { material->setMetallicFactor(mEditor->getMetalnessFactor(), true); } - if (mEditor->getUnsavedChangesFlags() & MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY) + else if ((reverted_flags & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY) && can_revert) + { + material->setMetallicFactor(nodep->mSavedGLTFRenderMaterials[te]->mMetallicFactor, true); + } + + if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY) { material->setRoughnessFactor(mEditor->getRoughnessFactor(), true); } + else if ((reverted_flags & MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY) && can_revert) + { + material->setRoughnessFactor(nodep->mSavedGLTFRenderMaterials[te]->mRoughnessFactor, true); + } - if (mEditor->getUnsavedChangesFlags() & MATERIAL_EMISIVE_COLOR_DIRTY) + if (changed_flags & MATERIAL_EMISIVE_COLOR_DIRTY) { material->setEmissiveColorFactor(LLColor3(mEditor->getEmissiveColor()), true); } - if (mEditor->getUnsavedChangesFlags() & MATERIAL_EMISIVE_TEX_DIRTY) + else if ((reverted_flags & MATERIAL_EMISIVE_COLOR_DIRTY) && can_revert) + { + material->setEmissiveColorFactor(nodep->mSavedGLTFRenderMaterials[te]->mEmissiveColor, true); + } + + if (changed_flags & MATERIAL_EMISIVE_TEX_DIRTY) { material->setEmissiveId(mEditor->getEmissiveId(), true); } + else if ((reverted_flags & MATERIAL_EMISIVE_TEX_DIRTY) && can_revert) + { + material->setEmissiveId(nodep->mSavedGLTFRenderMaterials[te]->mEmissiveId, true); + } - if (mEditor->getUnsavedChangesFlags() & MATERIAL_DOUBLE_SIDED_DIRTY) + if (changed_flags & MATERIAL_DOUBLE_SIDED_DIRTY) { material->setDoubleSided(mEditor->getDoubleSided(), true); } - if (mEditor->getUnsavedChangesFlags() & MATERIAL_ALPHA_MODE_DIRTY) + else if ((reverted_flags & MATERIAL_DOUBLE_SIDED_DIRTY) && can_revert) + { + material->setDoubleSided(nodep->mSavedGLTFRenderMaterials[te]->mDoubleSided, true); + } + + if (changed_flags & MATERIAL_ALPHA_MODE_DIRTY) { material->setAlphaMode(mEditor->getAlphaMode(), true); } - if (mEditor->getUnsavedChangesFlags() & MATERIAL_ALPHA_CUTOFF_DIRTY) + else if ((reverted_flags & MATERIAL_ALPHA_MODE_DIRTY) && can_revert) + { + material->setAlphaMode(nodep->mSavedGLTFRenderMaterials[te]->mAlphaMode, true); + } + + if (changed_flags & MATERIAL_ALPHA_CUTOFF_DIRTY) { material->setAlphaCutoff(mEditor->getAlphaCutoff(), true); } + else if ((reverted_flags & MATERIAL_ALPHA_CUTOFF_DIRTY) && can_revert) + { + material->setAlphaCutoff(nodep->mSavedGLTFRenderMaterials[te]->mAlphaCutoff, true); + } std::string overrides_json = material->asJSON(); @@ -2413,12 +2569,12 @@ void LLMaterialEditor::applyToSelection() // Don't send data if there is nothing to send. // Some UI elements will cause multiple commits, // like spin ctrls on click and on down - if (mUnsavedChanges != 0) + if (mUnsavedChanges != 0 || mRevertedChanges != 0) { mOverrideInProgress = true; LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); LLRenderMaterialOverrideFunctor override_func(this, url, mOverrideObjectId, mOverrideObjectTE); - selected_objects->applyToTEs(&override_func); + selected_objects->applyToNodes(&override_func); if (!override_func.getResult()) { // OverrideFunctor didn't find expected object or face @@ -2427,6 +2583,7 @@ void LLMaterialEditor::applyToSelection() // we posted all changes mUnsavedChanges = 0; + mRevertedChanges = 0; } } else -- cgit v1.2.3 From 40d01ba39388c5400e2582145e77295c51f33fc3 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 8 Nov 2022 12:20:59 -0600 Subject: SL-18585 Batch updates to ModifyMaterialParams capability. --- indra/newview/llmaterialeditor.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 397a302069..749b5a4c1b 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -2275,14 +2275,16 @@ public: material->setAlphaCutoff(mEditor->getAlphaCutoff(), true); } - std::string overrides_json = material->asJSON(); - #if 1 - // debug - std::string err, warn; - LLGLTFMaterial debug; - debug.fromJSON(overrides_json, warn, err); -#endif + if (mObjectTE == te + && mObjectId == objectp->getID()) + { + mSuccess = true; + } + LLGLTFMaterialList::queueModifyMaterial(objectp->getID(), te, *material); +#else + + std::string overrides_json = material->asJSON(); LLSD overrides = llsd::map( "object_id", objectp->getID(), @@ -2300,6 +2302,7 @@ public: done_callback = modifyCallback; } LLCoros::instance().launch("modifyMaterialCoro", std::bind(&LLGLTFMaterialList::modifyMaterialCoro, mCapUrl, overrides, done_callback)); +#endif } return true; } @@ -2347,6 +2350,11 @@ void LLMaterialEditor::applyToSelection() LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); LLRenderMaterialOverrideFunctor override_func(this, url, mOverrideObjectId, mOverrideObjectTE); selected_objects->applyToTEs(&override_func); + + void(*done_callback)(bool) = LLRenderMaterialOverrideFunctor::modifyCallback; + + LLGLTFMaterialList::flushModifyMaterialQueue(done_callback); + if (!override_func.getResult()) { // OverrideFunctor didn't find expected object or face -- cgit v1.2.3 From cba87c62cc3c31d48c680bf92aa7ae2b9555ba69 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 8 Nov 2022 10:53:24 -0800 Subject: SL-18523: When editing an object's material override, use the object's material override as a base, rather than its render material --- indra/newview/llmaterialeditor.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index a0cb4e1c8f..70b165460a 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -2385,19 +2385,26 @@ public: // Selection can cover multiple objects, and live editor is // supposed to overwrite changed values only LLTextureEntry* tep = objectp->getTE(te); - LLPointer material = tep->getGLTFRenderMaterial(); - if (material.isNull()) + if (tep->getGLTFMaterial().isNull()) { // overrides are not supposed to work or apply if // there is no base material to work from return false; } - + LLPointer material = tep->getGLTFMaterialOverride(); // make a copy to not invalidate existing // material for multiple objects - material = new LLGLTFMaterial(*material); + if (material.isNull()) + { + // Start with a material override which does not make any changes + material = new LLGLTFMaterial(LLGLTFMaterial::sOverrideDefault); + } + else + { + material = new LLGLTFMaterial(*material); + } U32 changed_flags = mEditor->getUnsavedChangesFlags(); U32 reverted_flags = mEditor->getRevertedChangesFlags(); -- cgit v1.2.3 From 4aaa48419594c993c6c1b0bd2f5585c6492b6a31 Mon Sep 17 00:00:00 2001 From: Sabrina Shanman Date: Wed, 9 Nov 2022 00:16:41 +0000 Subject: Revert "SL-18523: When editing an object's material override, use the object's material override as a base, rather than its render material (pull request #1190)" --- indra/newview/llmaterialeditor.cpp | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 70b165460a..a0cb4e1c8f 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -2385,26 +2385,19 @@ public: // Selection can cover multiple objects, and live editor is // supposed to overwrite changed values only LLTextureEntry* tep = objectp->getTE(te); + LLPointer material = tep->getGLTFRenderMaterial(); - if (tep->getGLTFMaterial().isNull()) + if (material.isNull()) { // overrides are not supposed to work or apply if // there is no base material to work from return false; } - LLPointer material = tep->getGLTFMaterialOverride(); + // make a copy to not invalidate existing // material for multiple objects - if (material.isNull()) - { - // Start with a material override which does not make any changes - material = new LLGLTFMaterial(LLGLTFMaterial::sOverrideDefault); - } - else - { - material = new LLGLTFMaterial(*material); - } + material = new LLGLTFMaterial(*material); U32 changed_flags = mEditor->getUnsavedChangesFlags(); U32 reverted_flags = mEditor->getRevertedChangesFlags(); -- cgit v1.2.3 From 14d901f25fdc10df871a60294eefcf4b9fb00931 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 9 Nov 2022 03:11:50 +0200 Subject: SL-18583 Use gltf overrides as a base for live editing to send only minimal changes --- indra/newview/llmaterialeditor.cpp | 67 ++++++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 25 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index a0cb4e1c8f..675ca610ce 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -908,29 +908,35 @@ void LLMaterialEditor::onSelectCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_ S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); // avatars have TEs but no faces for (S32 te = 0; te < num_tes; ++te) { - if (nodep->isTESelected(te) && nodep->mSavedGLTFRenderMaterials.size() > te) + if (nodep->isTESelected(te) && nodep->mSavedGLTFOverrideMaterials.size() > te) { + if (nodep->mSavedGLTFOverrideMaterials[te].isNull()) + { + // populate with default values, default values basically mean 'not in use' + nodep->mSavedGLTFOverrideMaterials[te] = new LLGLTFMaterial(); + } + switch (mDirtyFlag) { //Textures case MATERIAL_BASE_COLOR_TEX_DIRTY: { - nodep->mSavedGLTFRenderMaterials[te]->mBaseColorId = mCtrl->getValue().asUUID(); + nodep->mSavedGLTFOverrideMaterials[te]->mBaseColorId = mCtrl->getValue().asUUID(); break; } case MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY: { - nodep->mSavedGLTFRenderMaterials[te]->mMetallicRoughnessId = mCtrl->getValue().asUUID(); + nodep->mSavedGLTFOverrideMaterials[te]->mMetallicRoughnessId = mCtrl->getValue().asUUID(); break; } case MATERIAL_EMISIVE_TEX_DIRTY: { - nodep->mSavedGLTFRenderMaterials[te]->mEmissiveId = mCtrl->getValue().asUUID(); + nodep->mSavedGLTFOverrideMaterials[te]->mEmissiveId = mCtrl->getValue().asUUID(); break; } case MATERIAL_NORMAL_TEX_DIRTY: { - nodep->mSavedGLTFRenderMaterials[te]->mNormalId = mCtrl->getValue().asUUID(); + nodep->mSavedGLTFOverrideMaterials[te]->mNormalId = mCtrl->getValue().asUUID(); break; } // Colors @@ -938,13 +944,13 @@ void LLMaterialEditor::onSelectCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_ { LLColor4 ret = linearColor4(LLColor4(mCtrl->getValue())); // except transparency - ret.mV[3] = nodep->mSavedGLTFRenderMaterials[te]->mBaseColor.mV[3]; - nodep->mSavedGLTFRenderMaterials[te]->mBaseColor = ret; + ret.mV[3] = nodep->mSavedGLTFOverrideMaterials[te]->mBaseColor.mV[3]; + nodep->mSavedGLTFOverrideMaterials[te]->mBaseColor = ret; break; } case MATERIAL_EMISIVE_COLOR_DIRTY: { - nodep->mSavedGLTFRenderMaterials[te]->mEmissiveColor = LLColor4(mCtrl->getValue()); + nodep->mSavedGLTFOverrideMaterials[te]->mEmissiveColor = LLColor4(mCtrl->getValue()); break; } default: @@ -2379,29 +2385,40 @@ public: { continue; } - // Get material from object // Selection can cover multiple objects, and live editor is // supposed to overwrite changed values only LLTextureEntry* tep = objectp->getTE(te); - LLPointer material = tep->getGLTFRenderMaterial(); - if (material.isNull()) + if (tep->getGLTFMaterial() == nullptr) { // overrides are not supposed to work or apply if // there is no base material to work from return false; } - + LLPointer material = tep->getGLTFMaterialOverride(); // make a copy to not invalidate existing // material for multiple objects - material = new LLGLTFMaterial(*material); + if (material.isNull()) + { + // Start with a material override which does not make any changes + material = new LLGLTFMaterial(); + } + else + { + material = new LLGLTFMaterial(*material); + } U32 changed_flags = mEditor->getUnsavedChangesFlags(); U32 reverted_flags = mEditor->getRevertedChangesFlags(); - bool can_revert = nodep->mSavedGLTFRenderMaterials.size() > te; + + LLPointer revert_mat; + // mSavedGLTFOverrideMaterials[te] being null + // means we need to use a default value + bool can_revert = (nodep->mSavedGLTFOverrideMaterials.size() > te) + && nodep->mSavedGLTFOverrideMaterials[te].notNull(); // Override object's values with values from editor where appropriate if (changed_flags & MATERIAL_BASE_COLOR_DIRTY) @@ -2410,7 +2427,7 @@ public: } else if ((reverted_flags & MATERIAL_BASE_COLOR_DIRTY) && can_revert) { - material->setBaseColorFactor(nodep->mSavedGLTFRenderMaterials[te]->mBaseColor, true); + material->setBaseColorFactor(nodep->mSavedGLTFOverrideMaterials[te]->mBaseColor, true); } if (changed_flags & MATERIAL_BASE_COLOR_TEX_DIRTY) @@ -2419,7 +2436,7 @@ public: } else if ((reverted_flags & MATERIAL_BASE_COLOR_TEX_DIRTY) && can_revert) { - material->setBaseColorId(nodep->mSavedGLTFRenderMaterials[te]->mBaseColorId, true); + material->setBaseColorId(nodep->mSavedGLTFOverrideMaterials[te]->mBaseColorId, true); } if (changed_flags & MATERIAL_NORMAL_TEX_DIRTY) @@ -2428,7 +2445,7 @@ public: } else if ((reverted_flags & MATERIAL_NORMAL_TEX_DIRTY) && can_revert) { - material->setNormalId(nodep->mSavedGLTFRenderMaterials[te]->mNormalId, true); + material->setNormalId(nodep->mSavedGLTFOverrideMaterials[te]->mNormalId, true); } if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) @@ -2437,7 +2454,7 @@ public: } else if ((reverted_flags & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) && can_revert) { - material->setMetallicRoughnessId(nodep->mSavedGLTFRenderMaterials[te]->mMetallicRoughnessId, true); + material->setMetallicRoughnessId(nodep->mSavedGLTFOverrideMaterials[te]->mMetallicRoughnessId, true); } if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY) @@ -2446,7 +2463,7 @@ public: } else if ((reverted_flags & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY) && can_revert) { - material->setMetallicFactor(nodep->mSavedGLTFRenderMaterials[te]->mMetallicFactor, true); + material->setMetallicFactor(nodep->mSavedGLTFOverrideMaterials[te]->mMetallicFactor, true); } if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY) @@ -2455,7 +2472,7 @@ public: } else if ((reverted_flags & MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY) && can_revert) { - material->setRoughnessFactor(nodep->mSavedGLTFRenderMaterials[te]->mRoughnessFactor, true); + material->setRoughnessFactor(nodep->mSavedGLTFOverrideMaterials[te]->mRoughnessFactor, true); } if (changed_flags & MATERIAL_EMISIVE_COLOR_DIRTY) @@ -2464,7 +2481,7 @@ public: } else if ((reverted_flags & MATERIAL_EMISIVE_COLOR_DIRTY) && can_revert) { - material->setEmissiveColorFactor(nodep->mSavedGLTFRenderMaterials[te]->mEmissiveColor, true); + material->setEmissiveColorFactor(nodep->mSavedGLTFOverrideMaterials[te]->mEmissiveColor, true); } if (changed_flags & MATERIAL_EMISIVE_TEX_DIRTY) @@ -2473,7 +2490,7 @@ public: } else if ((reverted_flags & MATERIAL_EMISIVE_TEX_DIRTY) && can_revert) { - material->setEmissiveId(nodep->mSavedGLTFRenderMaterials[te]->mEmissiveId, true); + material->setEmissiveId(nodep->mSavedGLTFOverrideMaterials[te]->mEmissiveId, true); } if (changed_flags & MATERIAL_DOUBLE_SIDED_DIRTY) @@ -2482,7 +2499,7 @@ public: } else if ((reverted_flags & MATERIAL_DOUBLE_SIDED_DIRTY) && can_revert) { - material->setDoubleSided(nodep->mSavedGLTFRenderMaterials[te]->mDoubleSided, true); + material->setDoubleSided(nodep->mSavedGLTFOverrideMaterials[te]->mDoubleSided, true); } if (changed_flags & MATERIAL_ALPHA_MODE_DIRTY) @@ -2491,7 +2508,7 @@ public: } else if ((reverted_flags & MATERIAL_ALPHA_MODE_DIRTY) && can_revert) { - material->setAlphaMode(nodep->mSavedGLTFRenderMaterials[te]->mAlphaMode, true); + material->setAlphaMode(nodep->mSavedGLTFOverrideMaterials[te]->mAlphaMode, true); } if (changed_flags & MATERIAL_ALPHA_CUTOFF_DIRTY) @@ -2500,7 +2517,7 @@ public: } else if ((reverted_flags & MATERIAL_ALPHA_CUTOFF_DIRTY) && can_revert) { - material->setAlphaCutoff(nodep->mSavedGLTFRenderMaterials[te]->mAlphaCutoff, true); + material->setAlphaCutoff(nodep->mSavedGLTFOverrideMaterials[te]->mAlphaCutoff, true); } #if 1 -- cgit v1.2.3 From 1ed8f7cd0ca41ab655aaeeaf141eb4ef20f16bd0 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 9 Nov 2022 17:10:31 -0600 Subject: SL-18602 Fix for applying material asset not removing overrides on drag-and-drop --- indra/newview/llmaterialeditor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 675ca610ce..17da7e8853 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -2526,7 +2526,7 @@ public: { mSuccess = true; } - LLGLTFMaterialList::queueModifyMaterial(objectp->getID(), te, *material); + LLGLTFMaterialList::queueModifyMaterial(objectp->getID(), te, material); #else std::string overrides_json = material->asJSON(); @@ -2598,7 +2598,7 @@ void LLMaterialEditor::applyToSelection() void(*done_callback)(bool) = LLRenderMaterialOverrideFunctor::modifyCallback; - LLGLTFMaterialList::flushModifyMaterialQueue(done_callback); + LLGLTFMaterialList::flushUpdates(done_callback); if (!override_func.getResult()) { -- cgit v1.2.3 From d68f379786ed54dbce9dcf921ded4cccd0c5c61e Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 10 Nov 2022 17:28:09 +0200 Subject: SL-18583 Fixed incorrect values being applied when returning to a case without override --- indra/newview/llmaterialeditor.cpp | 74 +++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 32 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 17da7e8853..cd3f122101 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -921,22 +921,22 @@ void LLMaterialEditor::onSelectCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_ //Textures case MATERIAL_BASE_COLOR_TEX_DIRTY: { - nodep->mSavedGLTFOverrideMaterials[te]->mBaseColorId = mCtrl->getValue().asUUID(); + nodep->mSavedGLTFOverrideMaterials[te]->setBaseColorId(mCtrl->getValue().asUUID(), true); break; } case MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY: { - nodep->mSavedGLTFOverrideMaterials[te]->mMetallicRoughnessId = mCtrl->getValue().asUUID(); + nodep->mSavedGLTFOverrideMaterials[te]->setMetallicRoughnessId(mCtrl->getValue().asUUID(), true); break; } case MATERIAL_EMISIVE_TEX_DIRTY: { - nodep->mSavedGLTFOverrideMaterials[te]->mEmissiveId = mCtrl->getValue().asUUID(); + nodep->mSavedGLTFOverrideMaterials[te]->setEmissiveId(mCtrl->getValue().asUUID(), true); break; } case MATERIAL_NORMAL_TEX_DIRTY: { - nodep->mSavedGLTFOverrideMaterials[te]->mNormalId = mCtrl->getValue().asUUID(); + nodep->mSavedGLTFOverrideMaterials[te]->setNormalId(mCtrl->getValue().asUUID(), true); break; } // Colors @@ -945,12 +945,12 @@ void LLMaterialEditor::onSelectCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_ LLColor4 ret = linearColor4(LLColor4(mCtrl->getValue())); // except transparency ret.mV[3] = nodep->mSavedGLTFOverrideMaterials[te]->mBaseColor.mV[3]; - nodep->mSavedGLTFOverrideMaterials[te]->mBaseColor = ret; + nodep->mSavedGLTFOverrideMaterials[te]->setBaseColorFactor(ret, true); break; } case MATERIAL_EMISIVE_COLOR_DIRTY: { - nodep->mSavedGLTFOverrideMaterials[te]->mEmissiveColor = LLColor4(mCtrl->getValue()); + nodep->mSavedGLTFOverrideMaterials[te]->setEmissiveColorFactor(LLColor3(mCtrl->getValue()), true); break; } default: @@ -2415,109 +2415,119 @@ public: U32 reverted_flags = mEditor->getRevertedChangesFlags(); LLPointer revert_mat; - // mSavedGLTFOverrideMaterials[te] being null - // means we need to use a default value - bool can_revert = (nodep->mSavedGLTFOverrideMaterials.size() > te) - && nodep->mSavedGLTFOverrideMaterials[te].notNull(); + if (nodep->mSavedGLTFOverrideMaterials.size() > te) + { + if (nodep->mSavedGLTFOverrideMaterials[te].notNull()) + { + revert_mat = nodep->mSavedGLTFOverrideMaterials[te]; + } + else + { + // mSavedGLTFOverrideMaterials[te] being present but null + // means we need to use a default value + revert_mat = new LLGLTFMaterial(); + } + } + // else can not revert at all // Override object's values with values from editor where appropriate if (changed_flags & MATERIAL_BASE_COLOR_DIRTY) { material->setBaseColorFactor(mEditor->getBaseColor(), true); } - else if ((reverted_flags & MATERIAL_BASE_COLOR_DIRTY) && can_revert) + else if ((reverted_flags & MATERIAL_BASE_COLOR_DIRTY) && revert_mat.notNull()) { - material->setBaseColorFactor(nodep->mSavedGLTFOverrideMaterials[te]->mBaseColor, true); + material->setBaseColorFactor(revert_mat->mBaseColor, false); } if (changed_flags & MATERIAL_BASE_COLOR_TEX_DIRTY) { material->setBaseColorId(mEditor->getBaseColorId(), true); } - else if ((reverted_flags & MATERIAL_BASE_COLOR_TEX_DIRTY) && can_revert) + else if ((reverted_flags & MATERIAL_BASE_COLOR_TEX_DIRTY) && revert_mat.notNull()) { - material->setBaseColorId(nodep->mSavedGLTFOverrideMaterials[te]->mBaseColorId, true); + material->setBaseColorId(revert_mat->mBaseColorId, false); } if (changed_flags & MATERIAL_NORMAL_TEX_DIRTY) { material->setNormalId(mEditor->getNormalId(), true); } - else if ((reverted_flags & MATERIAL_NORMAL_TEX_DIRTY) && can_revert) + else if ((reverted_flags & MATERIAL_NORMAL_TEX_DIRTY) && revert_mat.notNull()) { - material->setNormalId(nodep->mSavedGLTFOverrideMaterials[te]->mNormalId, true); + material->setNormalId(revert_mat->mNormalId, false); } if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) { material->setMetallicRoughnessId(mEditor->getMetallicRoughnessId(), true); } - else if ((reverted_flags & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) && can_revert) + else if ((reverted_flags & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) && revert_mat.notNull()) { - material->setMetallicRoughnessId(nodep->mSavedGLTFOverrideMaterials[te]->mMetallicRoughnessId, true); + material->setMetallicRoughnessId(revert_mat->mMetallicRoughnessId, false); } if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY) { material->setMetallicFactor(mEditor->getMetalnessFactor(), true); } - else if ((reverted_flags & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY) && can_revert) + else if ((reverted_flags & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY) && revert_mat.notNull()) { - material->setMetallicFactor(nodep->mSavedGLTFOverrideMaterials[te]->mMetallicFactor, true); + material->setMetallicFactor(revert_mat->mMetallicFactor, false); } if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY) { material->setRoughnessFactor(mEditor->getRoughnessFactor(), true); } - else if ((reverted_flags & MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY) && can_revert) + else if ((reverted_flags & MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY) && revert_mat.notNull()) { - material->setRoughnessFactor(nodep->mSavedGLTFOverrideMaterials[te]->mRoughnessFactor, true); + material->setRoughnessFactor(revert_mat->mRoughnessFactor, false); } if (changed_flags & MATERIAL_EMISIVE_COLOR_DIRTY) { material->setEmissiveColorFactor(LLColor3(mEditor->getEmissiveColor()), true); } - else if ((reverted_flags & MATERIAL_EMISIVE_COLOR_DIRTY) && can_revert) + else if ((reverted_flags & MATERIAL_EMISIVE_COLOR_DIRTY) && revert_mat.notNull()) { - material->setEmissiveColorFactor(nodep->mSavedGLTFOverrideMaterials[te]->mEmissiveColor, true); + material->setEmissiveColorFactor(revert_mat->mEmissiveColor, false); } if (changed_flags & MATERIAL_EMISIVE_TEX_DIRTY) { material->setEmissiveId(mEditor->getEmissiveId(), true); } - else if ((reverted_flags & MATERIAL_EMISIVE_TEX_DIRTY) && can_revert) + else if ((reverted_flags & MATERIAL_EMISIVE_TEX_DIRTY) && revert_mat.notNull()) { - material->setEmissiveId(nodep->mSavedGLTFOverrideMaterials[te]->mEmissiveId, true); + material->setEmissiveId(revert_mat->mEmissiveId, false); } if (changed_flags & MATERIAL_DOUBLE_SIDED_DIRTY) { material->setDoubleSided(mEditor->getDoubleSided(), true); } - else if ((reverted_flags & MATERIAL_DOUBLE_SIDED_DIRTY) && can_revert) + else if ((reverted_flags & MATERIAL_DOUBLE_SIDED_DIRTY) && revert_mat.notNull()) { - material->setDoubleSided(nodep->mSavedGLTFOverrideMaterials[te]->mDoubleSided, true); + material->setDoubleSided(revert_mat->mDoubleSided, false); } if (changed_flags & MATERIAL_ALPHA_MODE_DIRTY) { material->setAlphaMode(mEditor->getAlphaMode(), true); } - else if ((reverted_flags & MATERIAL_ALPHA_MODE_DIRTY) && can_revert) + else if ((reverted_flags & MATERIAL_ALPHA_MODE_DIRTY) && revert_mat.notNull()) { - material->setAlphaMode(nodep->mSavedGLTFOverrideMaterials[te]->mAlphaMode, true); + material->setAlphaMode(revert_mat->mAlphaMode, false); } if (changed_flags & MATERIAL_ALPHA_CUTOFF_DIRTY) { material->setAlphaCutoff(mEditor->getAlphaCutoff(), true); } - else if ((reverted_flags & MATERIAL_ALPHA_CUTOFF_DIRTY) && can_revert) + else if ((reverted_flags & MATERIAL_ALPHA_CUTOFF_DIRTY) && revert_mat.notNull()) { - material->setAlphaCutoff(nodep->mSavedGLTFOverrideMaterials[te]->mAlphaCutoff, true); + material->setAlphaCutoff(revert_mat->mAlphaCutoff, false); } #if 1 -- cgit v1.2.3 From 76de36c40520445d7ad77f85cd6c601942b97032 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 10 Nov 2022 13:21:06 -0600 Subject: SL-18602 Integrate queueModify/queueApply/queueUpdate into all the places that used to post to ModifyMaterialParams directly. --- indra/newview/llmaterialeditor.cpp | 29 ++--------------------------- 1 file changed, 2 insertions(+), 27 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index cd3f122101..a9728e26da 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -2353,11 +2353,9 @@ class LLRenderMaterialOverrideFunctor : public LLSelectedNodeFunctor public: LLRenderMaterialOverrideFunctor( LLMaterialEditor * me, - std::string const & url, const LLUUID &report_on_object_id, S32 report_on_te) : mEditor(me) - , mCapUrl(url) , mSuccess(false) , mObjectId(report_on_object_id) , mObjectTE(report_on_te) @@ -2530,34 +2528,12 @@ public: material->setAlphaCutoff(revert_mat->mAlphaCutoff, false); } -#if 1 if (mObjectTE == te && mObjectId == objectp->getID()) { mSuccess = true; } - LLGLTFMaterialList::queueModifyMaterial(objectp->getID(), te, material); -#else - - std::string overrides_json = material->asJSON(); - - LLSD overrides = llsd::map( - "object_id", objectp->getID(), - "side", te, - "gltf_json", overrides_json - ); - - void(*done_callback)(bool) = nullptr; - if (mObjectTE == te - && mObjectId == objectp->getID()) - { - mSuccess = true; - // We only want callback for face we are displayig material from - // even if we are setting all of them - done_callback = modifyCallback; - } - LLCoros::instance().launch("modifyMaterialCoro", std::bind(&LLGLTFMaterialList::modifyMaterialCoro, mCapUrl, overrides, done_callback)); -#endif + LLGLTFMaterialList::queueModify(objectp->getID(), te, material); } return true; } @@ -2576,7 +2552,6 @@ public: private: LLMaterialEditor * mEditor; - std::string mCapUrl; LLUUID mObjectId; S32 mObjectTE; bool mSuccess; @@ -2603,7 +2578,7 @@ void LLMaterialEditor::applyToSelection() { mOverrideInProgress = true; LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); - LLRenderMaterialOverrideFunctor override_func(this, url, mOverrideObjectId, mOverrideObjectTE); + LLRenderMaterialOverrideFunctor override_func(this, mOverrideObjectId, mOverrideObjectTE); selected_objects->applyToNodes(&override_func); void(*done_callback)(bool) = LLRenderMaterialOverrideFunctor::modifyCallback; -- cgit v1.2.3 From bfe5e3f289e4a260f10bcfffb8eca809c89f65d6 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 16 Nov 2022 23:23:43 +0200 Subject: SL-18648 Material editor should only allow full-perm textures --- indra/newview/llmaterialeditor.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index a9728e26da..7491f17f9e 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -378,6 +378,17 @@ BOOL LLMaterialEditor::postBuild() mBaseColorCtrl = getChild("base color"); mEmissiveColorCtrl = getChild("emissive color"); + // Only allow fully permissive textures + mBaseColorTextureCtrl->setImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); + mBaseColorTextureCtrl->setNonImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); + mMetallicTextureCtrl->setImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); + mMetallicTextureCtrl->setNonImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); + mEmissiveTextureCtrl->setImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); + mEmissiveTextureCtrl->setNonImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); + mNormalTextureCtrl->setImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); + mNormalTextureCtrl->setNonImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); + + // Texture callback mBaseColorTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitTexture, this, _1, _2, MATERIAL_BASE_COLOR_TEX_DIRTY)); mMetallicTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitTexture, this, _1, _2, MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY)); mEmissiveTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitTexture, this, _1, _2, MATERIAL_EMISIVE_TEX_DIRTY)); -- cgit v1.2.3 From 6387fbb378ff3ec5a8cf1e217eb4f2d71134c180 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 16 Nov 2022 23:55:45 +0200 Subject: SL-18648 Simplify permission testing --- indra/newview/llmaterialeditor.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 7491f17f9e..d5948b297c 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -378,15 +378,18 @@ BOOL LLMaterialEditor::postBuild() mBaseColorCtrl = getChild("base color"); mEmissiveColorCtrl = getChild("emissive color"); - // Only allow fully permissive textures - mBaseColorTextureCtrl->setImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); - mBaseColorTextureCtrl->setNonImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); - mMetallicTextureCtrl->setImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); - mMetallicTextureCtrl->setNonImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); - mEmissiveTextureCtrl->setImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); - mEmissiveTextureCtrl->setNonImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); - mNormalTextureCtrl->setImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); - mNormalTextureCtrl->setNonImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); + if (!gAgent.isGodlike()) + { + // Only allow fully permissive textures + mBaseColorTextureCtrl->setImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); + mBaseColorTextureCtrl->setNonImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); + mMetallicTextureCtrl->setImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); + mMetallicTextureCtrl->setNonImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); + mEmissiveTextureCtrl->setImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); + mEmissiveTextureCtrl->setNonImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); + mNormalTextureCtrl->setImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); + mNormalTextureCtrl->setNonImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); + } // Texture callback mBaseColorTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitTexture, this, _1, _2, MATERIAL_BASE_COLOR_TEX_DIRTY)); -- cgit v1.2.3 From 32984b56ea8fa4f4357379a40627b5e9267d7543 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 24 Nov 2022 12:16:59 +0200 Subject: SL-18701 llsd is not thread safe, parse it before using --- indra/newview/llmaterialeditor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index d5948b297c..d5339777c4 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1008,7 +1008,7 @@ static U32 write_texture(const LLUUID& id, tinygltf::Model& model) void LLMaterialEditor::onClickSave() { - if (!capabilitiesAvalaible()) + if (!capabilitiesAvailable()) { LLNotificationsUtil::add("MissingMaterialCaps"); return; @@ -3067,7 +3067,7 @@ void LLMaterialEditor::loadDefaults() setFromGltfModel(model_in, 0, true); } -bool LLMaterialEditor::capabilitiesAvalaible() +bool LLMaterialEditor::capabilitiesAvailable() { const LLViewerRegion* region = gAgent.getRegion(); if (!region) -- cgit v1.2.3 From 9f7967fcdc5ccb60bd72e8e9e1b7652dc2058524 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 29 Nov 2022 23:35:18 +0200 Subject: SL-18727 Save material to Inventoryshould prioritize picked face --- indra/newview/llmaterialeditor.cpp | 106 ++++++++++++++++++++++++++----------- 1 file changed, 76 insertions(+), 30 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index d5339777c4..fe674abeee 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -46,6 +46,7 @@ #include "llsdutil.h" #include "llselectmgr.h" #include "llstatusbar.h" // can_afford_transaction() +#include "lltoolpie.h" #include "llviewerinventory.h" #include "llinventory.h" #include "llviewerregion.h" @@ -322,9 +323,17 @@ bool LLSelectedTEGetMatData::apply(LLViewerObject* objectp, S32 te_index) mLocalMaterial = local_mat; } mMaterial = tep->getGLTFRenderMaterial(); + + if (mMaterial.isNull()) + { + // Shouldn't be possible? + LL_WARNS("MaterialEditor") << "Object has material id, but no material" << LL_ENDL; + mMaterial = gGLTFMaterialList.getMaterial(mat_id); + } } + return true; } - return true; + return false; } ///---------------------------------------------------------------------------- @@ -1816,58 +1825,95 @@ void LLMaterialEditor::loadLive() void LLMaterialEditor::saveObjectsMaterialAs() { - - // Find an applicable material. - // Do this before showing message, because - // message is going to drop selection. LLSelectedTEGetMatData func(false); LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func, true /*first applicable*/); + saveMaterialAs(func.mMaterial, func.mLocalMaterial); +} +void LLMaterialEditor::savePickedMaterialAs() +{ + LLPickInfo pick = LLToolPie::getInstance()->getPick(); + if (pick.mPickType != LLPickInfo::PICK_OBJECT || !pick.getObject()) + { + return; + } + + LLPointer render_material; + LLPointer local_material; - if (func.mLocalMaterial.notNull()) + LLViewerObject *objectp = pick.getObject(); + LLUUID mat_id = objectp->getRenderMaterialID(pick.mObjectFace); + if (mat_id.notNull() && objectp->permCopy()) + { + // Try a face user picked first + // (likely the only method we need, but in such case + // enable_object_save_gltf_material will need to check this) + LLTextureEntry *tep = objectp->getTE(pick.mObjectFace); + LLGLTFMaterial *mat = tep->getGLTFMaterial(); + LLLocalGLTFMaterial *local_mat = dynamic_cast(mat); + + if (local_mat) + { + local_material = local_mat; + } + render_material = tep->getGLTFRenderMaterial(); + } + else + { + // Find an applicable material. + // Do this before showing message, because + // message is going to drop selection. + LLSelectedTEGetMatData func(false); + LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func, true /*first applicable*/); + local_material = func.mLocalMaterial; + render_material = func.mMaterial; + } + + saveMaterialAs(render_material, local_material); +} + +void LLMaterialEditor::saveMaterialAs(const LLGLTFMaterial* render_material, const LLLocalGLTFMaterial *local_material) +{ + if (local_material) { // This is a local material, reload it from file // so that user won't end up with grey textures // on next login. - LLMaterialEditor::loadMaterialFromFile(func.mLocalMaterial->getFilename(), func.mLocalMaterial->getIndexInFile()); + LLMaterialEditor::loadMaterialFromFile(local_material->getFilename(), local_material->getIndexInFile()); LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor"); if (me) { - // apply differences on top - LLGLTFMaterial* local_mat = func.mLocalMaterial.get(); - // don't use override mat here, it has 'hacked ids' - // and values, use end result. - LLGLTFMaterial* cmp_mat = func.mMaterial.get(); - - me->setBaseColor(cmp_mat->mBaseColor); - me->setMetalnessFactor(cmp_mat->mMetallicFactor); - me->setRoughnessFactor(cmp_mat->mRoughnessFactor); - me->setEmissiveColor(cmp_mat->mEmissiveColor); - me->setDoubleSided(cmp_mat->mDoubleSided); - me->setAlphaMode(cmp_mat->getAlphaMode()); - me->setAlphaCutoff(cmp_mat->mAlphaCutoff); + // don't use override material here, it has 'hacked ids' + // and values, use end result, apply it on top of local. + me->setBaseColor(render_material->mBaseColor); + me->setMetalnessFactor(render_material->mMetallicFactor); + me->setRoughnessFactor(render_material->mRoughnessFactor); + me->setEmissiveColor(render_material->mEmissiveColor); + me->setDoubleSided(render_material->mDoubleSided); + me->setAlphaMode(render_material->getAlphaMode()); + me->setAlphaCutoff(render_material->mAlphaCutoff); // most things like colors we can apply without verifying // but texture ids are going to be different from both, base and override // so only apply override id if there is actually a difference - if (local_mat->mBaseColorId != cmp_mat->mBaseColorId) + if (local_material->mBaseColorId != render_material->mBaseColorId) { - me->setBaseColorId(cmp_mat->mBaseColorId); + me->setBaseColorId(render_material->mBaseColorId); me->childSetValue("base_color_upload_fee", me->getString("no_upload_fee_string")); } - if (local_mat->mNormalId != cmp_mat->mNormalId) + if (local_material->mNormalId != render_material->mNormalId) { - me->setNormalId(cmp_mat->mNormalId); + me->setNormalId(render_material->mNormalId); me->childSetValue("normal_upload_fee", me->getString("no_upload_fee_string")); } - if (local_mat->mMetallicRoughnessId != cmp_mat->mMetallicRoughnessId) + if (local_material->mMetallicRoughnessId != render_material->mMetallicRoughnessId) { - me->setMetallicRoughnessId(cmp_mat->mMetallicRoughnessId); + me->setMetallicRoughnessId(render_material->mMetallicRoughnessId); me->childSetValue("metallic_upload_fee", me->getString("no_upload_fee_string")); } - if (local_mat->mEmissiveId != cmp_mat->mEmissiveId) + if (local_material->mEmissiveId != render_material->mEmissiveId) { - me->setEmissiveId(cmp_mat->mEmissiveId); + me->setEmissiveId(render_material->mEmissiveId); me->childSetValue("emissive_upload_fee", me->getString("no_upload_fee_string")); } @@ -1879,9 +1925,9 @@ void LLMaterialEditor::saveObjectsMaterialAs() } LLSD payload; - if (func.mMaterial.notNull()) + if (render_material) { - payload["data"] = func.mMaterial->asJSON(); + payload["data"] = render_material->asJSON(); } else { -- cgit v1.2.3 From 361571cdb330dea18ad5a3575d7b06c69371e11b Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 29 Nov 2022 13:51:23 -0800 Subject: SL-18732: Use override update callback for LLMaterialEditor::updateLive as well --- indra/newview/llmaterialeditor.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index d5339777c4..f1fd276402 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -399,6 +399,9 @@ BOOL LLMaterialEditor::postBuild() if (mIsOverride) { + // Material override change success callback + LLGLTFMaterialList::addUpdateCallback(&LLMaterialEditor::updateLive); + // Live editing needs a recovery mechanism on cancel mBaseColorTextureCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_BASE_COLOR_TEX_DIRTY)); mMetallicTextureCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY)); -- cgit v1.2.3 From bfcb07270ed7036c87a4ece7fa1f5416123fff85 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 29 Nov 2022 15:20:44 -0800 Subject: SL-18732: Review feedback --- indra/newview/llmaterialeditor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index f1fd276402..8c8a07bc21 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -400,7 +400,7 @@ BOOL LLMaterialEditor::postBuild() if (mIsOverride) { // Material override change success callback - LLGLTFMaterialList::addUpdateCallback(&LLMaterialEditor::updateLive); + LLGLTFMaterialList::addSelectionUpdateCallback(&LLMaterialEditor::updateLive); // Live editing needs a recovery mechanism on cancel mBaseColorTextureCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_BASE_COLOR_TEX_DIRTY)); -- cgit v1.2.3 From 7c489e0480221b9c85a919f02f2a1d45b936f6e7 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 30 Nov 2022 17:18:31 +0200 Subject: SL-18648 Clean up unused mNonImmediateFilterPermMask --- indra/newview/llmaterialeditor.cpp | 4 ---- 1 file changed, 4 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 07c283e9c2..4b9d870d18 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -391,13 +391,9 @@ BOOL LLMaterialEditor::postBuild() { // Only allow fully permissive textures mBaseColorTextureCtrl->setImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); - mBaseColorTextureCtrl->setNonImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); mMetallicTextureCtrl->setImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); - mMetallicTextureCtrl->setNonImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); mEmissiveTextureCtrl->setImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); - mEmissiveTextureCtrl->setNonImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); mNormalTextureCtrl->setImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); - mNormalTextureCtrl->setNonImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); } // Texture callback -- cgit v1.2.3 From c0f598c10376f12310660a729f4a763dbf46368e Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 1 Dec 2022 06:42:10 +0200 Subject: SL-18725 Texture picker should explain why dropping texture isn't allowed Show a tooltip on drag&drop --- indra/newview/llmaterialeditor.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 4b9d870d18..ea6b34c96e 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -390,10 +390,10 @@ BOOL LLMaterialEditor::postBuild() if (!gAgent.isGodlike()) { // Only allow fully permissive textures - mBaseColorTextureCtrl->setImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); - mMetallicTextureCtrl->setImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); - mEmissiveTextureCtrl->setImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); - mNormalTextureCtrl->setImmediateFilterPermMask(PERM_ITEM_UNRESTRICTED); + mBaseColorTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); + mMetallicTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); + mEmissiveTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); + mNormalTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); } // Texture callback -- cgit v1.2.3 From 321c7895d00b0b88675c06b8f1cef063632fd686 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 1 Dec 2022 21:54:49 +0200 Subject: SL-18741 Basic bulk upload for gltf materials #1 --- indra/newview/llmaterialeditor.cpp | 66 ++++++++++++++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 6 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index ea6b34c96e..660ad879ca 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1400,8 +1400,6 @@ void LLMaterialEditor::createInventoryItem(const std::string &buffer, const std: LLNotificationsUtil::add("MaterialCreated", params); }); - // todo: apply permissions from textures here if server doesn't - // if any texture is 'no transfer', material should be 'no transfer' as well const LLViewerRegion* region = gAgent.getRegion(); if (region) { @@ -1684,6 +1682,59 @@ static void pack_textures( } } +void LLMaterialEditor::uploadMaterialFromFile(const std::string& filename, S32 index) +{ + if (index < 0) + { + return; + } + + tinygltf::TinyGLTF loader; + std::string error_msg; + std::string warn_msg; + + bool loaded = false; + tinygltf::Model model_in; + + std::string filename_lc = filename; + LLStringUtil::toLower(filename_lc); + + // Load a tinygltf model fom a file. Assumes that the input filename has already been + // been sanitized to one of (.gltf , .glb) extensions, so does a simple find to distinguish. + if (std::string::npos == filename_lc.rfind(".gltf")) + { // file is binary + loaded = loader.LoadBinaryFromFile(&model_in, &error_msg, &warn_msg, filename); + } + else + { // file is ascii + loaded = loader.LoadASCIIFromFile(&model_in, &error_msg, &warn_msg, filename); + } + + if (!loaded) + { + LLNotificationsUtil::add("CannotUploadMaterial"); + return; + } + + if (model_in.materials.empty()) + { + // materials are missing + return; + } + + if (index >= 0 && model_in.materials.size() <= index) + { + // material is missing + return; + } + + // Todo: no point in loading whole editor + LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", LLSD().with("filename", filename).with("index", LLSD::Integer(index))); + me->loadMaterial(model_in, filename_lc, index, false); + me->saveIfNeeded(); +} + + void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 index) { tinygltf::TinyGLTF loader; @@ -1976,7 +2027,7 @@ void LLMaterialEditor::loadFromGLTFMaterial(LLUUID &asset_id) me->setFocus(TRUE); } -void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std::string &filename_lc, S32 index) +void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std::string &filename_lc, S32 index, bool open_floater) { if (model_in.materials.size() <= index) { @@ -2074,10 +2125,13 @@ void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std:: markChangesUnsaved(U32_MAX); - openFloater(); - setFocus(TRUE); + if (open_floater) + { + openFloater(getKey()); + setFocus(TRUE); - applyToSelection(); + applyToSelection(); + } } bool LLMaterialEditor::setFromGltfModel(const tinygltf::Model& model, S32 index, bool set_textures) -- cgit v1.2.3 From c033278ec2d16181b94d6433a3353765c8981850 Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko Date: Wed, 7 Dec 2022 01:32:01 +0200 Subject: SL-18795 Overrides are not applied to one face --- indra/newview/llmaterialeditor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 660ad879ca..2d5f3df6a1 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -2506,7 +2506,7 @@ public: { // overrides are not supposed to work or apply if // there is no base material to work from - return false; + continue; } LLPointer material = tep->getGLTFMaterialOverride(); -- cgit v1.2.3 From c69c8aa347363bc51ed256523bc368d4584dbfd1 Mon Sep 17 00:00:00 2001 From: akleshchev <117672381+akleshchev@users.noreply.github.com> Date: Wed, 7 Dec 2022 02:16:12 +0200 Subject: SL-18777 PBR upload was stuck waiting for texture Handle obscure upload failure case - floater was waiting for a texture upload indefinetely. Unblock floater if upload fails. --- indra/newview/llmaterialeditor.cpp | 201 +++++++++++++++++++++++++++---------- 1 file changed, 147 insertions(+), 54 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 2d5f3df6a1..903ca60350 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -347,6 +347,7 @@ LLMaterialEditor::LLMaterialEditor(const LLSD& key) , mRevertedChanges(0) , mExpectedUploadCost(0) , mUploadingTexturesCount(0) + , mUploadingTexturesFailure(false) { const LLInventoryItem* item = getItem(); if (item) @@ -1251,9 +1252,9 @@ bool LLMaterialEditor::saveIfNeeded() { if (mUploadingTexturesCount > 0) { - // upload already in progress - // wait until textures upload - // will retry saving on callback + // Upload already in progress, wait until + // textures upload will retry saving on callback. + // Also should prevent some failure-callbacks return true; } @@ -1318,18 +1319,38 @@ bool LLMaterialEditor::updateInventoryItem(const std::string &buffer, const LLUU if (task_id.isNull() && !agent_url.empty()) { uploadInfo = std::make_shared(item_id, LLAssetType::AT_MATERIAL, buffer, - [](LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD) { - LLMaterialEditor::finishInventoryUpload(itemId, newAssetId, newItemId); - }); + [](LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD) + { + // done callback + LLMaterialEditor::finishInventoryUpload(itemId, newAssetId, newItemId); + }, + nullptr // failure callback + ); url = agent_url; } else if (!task_id.isNull() && !task_url.empty()) { LLUUID object_uuid(task_id); uploadInfo = std::make_shared(task_id, item_id, LLAssetType::AT_MATERIAL, buffer, - [object_uuid](LLUUID itemId, LLUUID, LLUUID newAssetId, LLSD) { - LLMaterialEditor::finishTaskUpload(itemId, newAssetId, object_uuid); - }); + [](LLUUID itemId, LLUUID task_id, LLUUID newAssetId, LLSD) + { + // done callback + LLMaterialEditor::finishTaskUpload(itemId, newAssetId, task_id); + }, + [](LLUUID itemId, LLUUID task_id, LLSD response, std::string reason) + { + // failure callback + LLSD floater_key; + floater_key["taskid"] = task_id; + floater_key["itemid"] = itemId; + LLMaterialEditor* me = LLFloaterReg::findTypedInstance("material_editor", floater_key); + if (me) + { + me->setEnabled(true); + } + return true; + } + ); url = task_url; } @@ -1394,11 +1415,15 @@ void LLMaterialEditor::createInventoryItem(const std::string &buffer, const std: inv_item_id, LLAssetType::AT_MATERIAL, output, - [](LLUUID item_id, LLUUID new_asset_id, LLUUID new_item_id, LLSD response) { - LL_INFOS("Material") << "inventory item uploaded. item: " << item_id << " asset: " << new_asset_id << " new_item_id: " << new_item_id << " response: " << response << LL_ENDL; - LLSD params = llsd::map("ASSET_ID", new_asset_id); - LLNotificationsUtil::add("MaterialCreated", params); - }); + [](LLUUID item_id, LLUUID new_asset_id, LLUUID new_item_id, LLSD response) + { + // done callback + LL_INFOS("Material") << "inventory item uploaded. item: " << item_id << " asset: " << new_asset_id << " new_item_id: " << new_item_id << " response: " << response << LL_ENDL; + LLSD params = llsd::map("ASSET_ID", new_asset_id); + LLNotificationsUtil::add("MaterialCreated", params); + }, + nullptr // failure callback, floater already closed + ); const LLViewerRegion* region = gAgent.getRegion(); if (region) @@ -1729,6 +1754,8 @@ void LLMaterialEditor::uploadMaterialFromFile(const std::string& filename, S32 i } // Todo: no point in loading whole editor + // This uses 'filename' to make sure multiple bulk uploads work + // instead of fighting for a single instance. LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", LLSD().with("filename", filename).with("index", LLSD::Integer(index))); me->loadMaterial(model_in, filename_lc, index, false); me->saveIfNeeded(); @@ -2012,21 +2039,6 @@ void LLMaterialEditor::onSaveObjectsMaterialAsMsgCallback(const LLSD& notificati } } -void LLMaterialEditor::loadFromGLTFMaterial(LLUUID &asset_id) -{ - if (asset_id.isNull()) - { - LL_WARNS("MaterialEditor") << "Trying to open material with null id" << LL_ENDL; - return; - } - LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor"); - me->mMaterialName = LLTrans::getString("New Material"); - me->setTitle(me->mMaterialName); - me->setFromGLTFMaterial(gGLTFMaterialList.getMaterial(asset_id)); - me->openFloater(); - me->setFocus(TRUE); -} - void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std::string &filename_lc, S32 index, bool open_floater) { if (model_in.materials.size() <= index) @@ -3008,6 +3020,16 @@ void LLMaterialEditor::saveTexture(LLImageJ2C* img, const std::string& name, con U32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(); + LLSD key = getKey(); + std::function failed_upload([key](LLUUID assetId, LLSD response, std::string reason) + { + LLMaterialEditor* me = LLFloaterReg::findTypedInstance("material_editor", key); + if (me) + { + me->setFailedToUploadTexture(); + } + return true; // handled + }); LLResourceUploadInfo::ptr_t uploadInfo(std::make_shared( buffer, @@ -3023,13 +3045,26 @@ void LLMaterialEditor::saveTexture(LLImageJ2C* img, const std::string& name, con LLFloaterPerms::getEveryonePerms("Uploads"), expected_upload_cost, false, - cb)); + cb, + failed_upload)); upload_new_resource(uploadInfo); } +void LLMaterialEditor::setFailedToUploadTexture() +{ + mUploadingTexturesFailure = true; + mUploadingTexturesCount--; + if (mUploadingTexturesCount == 0) + { + setEnabled(true); + } +} + S32 LLMaterialEditor::saveTextures() { + mUploadingTexturesFailure = false; // not supposed to get here if already uploading + S32 work_count = 0; LLSD key = getKey(); // must be locally declared for lambda's capture to work if (mBaseColorTextureUploadId == getBaseColorId() && mBaseColorTextureUploadId.notNull()) @@ -3044,16 +3079,29 @@ S32 LLMaterialEditor::saveTextures() if (response["success"].asBoolean()) { me->setBaseColorId(newAssetId); + + // discard upload buffers once texture have been saved + me->mBaseColorJ2C = nullptr; + me->mBaseColorFetched = nullptr; + me->mBaseColorTextureUploadId.setNull(); + + me->mUploadingTexturesCount--; + + if (!me->mUploadingTexturesFailure) + { + // try saving + me->saveIfNeeded(); + } + else if (me->mUploadingTexturesCount == 0) + { + me->setEnabled(true); + } } else { - // To make sure that we won't retry (some failures can cb immediately) - me->setBaseColorId(LLUUID::null); + // stop upload if possible, unblock and let user decide + me->setFailedToUploadTexture(); } - me->mUploadingTexturesCount--; - - // try saving - me->saveIfNeeded(); } }); } @@ -3069,16 +3117,29 @@ S32 LLMaterialEditor::saveTextures() if (response["success"].asBoolean()) { me->setNormalId(newAssetId); + + // discard upload buffers once texture have been saved + me->mNormalJ2C = nullptr; + me->mNormalFetched = nullptr; + me->mNormalTextureUploadId.setNull(); + + me->mUploadingTexturesCount--; + + if (!me->mUploadingTexturesFailure) + { + // try saving + me->saveIfNeeded(); + } + else if (me->mUploadingTexturesCount == 0) + { + me->setEnabled(true); + } } else { - me->setNormalId(LLUUID::null); + // stop upload if possible, unblock and let user decide + me->setFailedToUploadTexture(); } - me->setNormalId(newAssetId); - me->mUploadingTexturesCount--; - - // try saving - me->saveIfNeeded(); } }); } @@ -3094,15 +3155,29 @@ S32 LLMaterialEditor::saveTextures() if (response["success"].asBoolean()) { me->setMetallicRoughnessId(newAssetId); + + // discard upload buffers once texture have been saved + me->mMetallicRoughnessJ2C = nullptr; + me->mMetallicRoughnessFetched = nullptr; + me->mMetallicTextureUploadId.setNull(); + + me->mUploadingTexturesCount--; + + if (!me->mUploadingTexturesFailure) + { + // try saving + me->saveIfNeeded(); + } + else if (me->mUploadingTexturesCount == 0) + { + me->setEnabled(true); + } } else { - me->setMetallicRoughnessId(LLUUID::null); + // stop upload if possible, unblock and let user decide + me->setFailedToUploadTexture(); } - me->mUploadingTexturesCount--; - - // try saving - me->saveIfNeeded(); } }); } @@ -3119,21 +3194,39 @@ S32 LLMaterialEditor::saveTextures() if (response["success"].asBoolean()) { me->setEmissiveId(newAssetId); + + // discard upload buffers once texture have been saved + me->mEmissiveJ2C = nullptr; + me->mEmissiveFetched = nullptr; + me->mEmissiveTextureUploadId.setNull(); + + me->mUploadingTexturesCount--; + + if (!me->mUploadingTexturesFailure) + { + // try saving + me->saveIfNeeded(); + } + else if (me->mUploadingTexturesCount == 0) + { + me->setEnabled(true); + } } else { - me->setEmissiveId(LLUUID::null); + // stop upload if possible, unblock and let user decide + me->setFailedToUploadTexture(); } - me->mUploadingTexturesCount--; - - // try saving - me->saveIfNeeded(); } }); } - // discard upload buffers once textures have been saved - clearTextures(); + if (!work_count) + { + // Discard upload buffers once textures have been confirmed as saved. + // Otherwise we keep buffers for potential upload failure recovery. + clearTextures(); + } // asset storage can callback immediately, causing a decrease // of mUploadingTexturesCount, report amount of work scheduled -- cgit v1.2.3 From 76c6f3f002693459b77669df39d51fb4e456650d Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 7 Dec 2022 21:18:42 +0200 Subject: SL-18741 Don't allow bulk upload without caps --- indra/newview/llmaterialeditor.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 903ca60350..2e57c35326 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1559,6 +1559,12 @@ void LLMaterialEditor::refreshFromInventory(const LLUUID& new_item_id) void LLMaterialEditor::onClickSaveAs() { + if (!LLMaterialEditor::capabilitiesAvailable()) + { + LLNotificationsUtil::add("MissingMaterialCaps"); + return; + } + if (!can_afford_transaction(mExpectedUploadCost)) { LLSD args; @@ -1709,7 +1715,7 @@ static void pack_textures( void LLMaterialEditor::uploadMaterialFromFile(const std::string& filename, S32 index) { - if (index < 0) + if (index < 0 || !LLMaterialEditor::capabilitiesAvailable()) { return; } -- cgit v1.2.3 From 3e1afc3c917e655e8fd91a3b4b369c95a44ad981 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 11 Jan 2023 23:56:41 +0200 Subject: SL-18947 No modify materials can lock material floater Not supposed to happen, yet somehow did --- indra/newview/llmaterialeditor.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 2e57c35326..dbbd6edb7d 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1324,7 +1324,16 @@ bool LLMaterialEditor::updateInventoryItem(const std::string &buffer, const LLUU // done callback LLMaterialEditor::finishInventoryUpload(itemId, newAssetId, newItemId); }, - nullptr // failure callback + [](LLUUID itemId, LLUUID taskId, LLSD response, std::string reason) + { + // failure callback + LLMaterialEditor* me = LLFloaterReg::findTypedInstance("material_editor", LLSD(itemId)); + if (me) + { + me->setEnabled(true); + } + return true; + } ); url = agent_url; } -- cgit v1.2.3 From 10a4319c303a30789ff02f89e3e59028573f5b46 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 12 Jan 2023 19:03:36 +0200 Subject: SL-18962 PBR Materials should be viewable even if they are no-copy --- indra/newview/llmaterialeditor.cpp | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index dbbd6edb7d..9efe5dc1f1 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -2899,19 +2899,14 @@ void LLMaterialEditor::loadAsset() setEnableEditing(false); // wait for it to load - // request the asset. - gAssetStorage->getInvItemAsset(source_sim, - gAgent.getID(), - gAgent.getSessionID(), - item->getPermissions().getOwner(), - mObjectUUID, - item->getUUID(), - item->getAssetUUID(), - item->getType(), + mAssetStatus = PREVIEW_ASSET_LOADING; + + // May callback immediately + gAssetStorage->getAssetData(item->getAssetUUID(), + LLAssetType::AT_MATERIAL, &onLoadComplete, (void*)user_data, TRUE); - mAssetStatus = PREVIEW_ASSET_LOADING; } } } @@ -2962,7 +2957,7 @@ void LLMaterialEditor::onLoadComplete(const LLUUID& asset_uuid, { if (asset_uuid != editor->mAssetID) { - LL_WARNS() << "Asset id mismatch, expected: " << editor->mAssetID << " got: " << asset_uuid << LL_ENDL; + LL_WARNS("MaterialEditor") << "Asset id mismatch, expected: " << editor->mAssetID << " got: " << asset_uuid << LL_ENDL; } if (0 == status) { @@ -2991,6 +2986,8 @@ void LLMaterialEditor::onLoadComplete(const LLUUID& asset_uuid, } else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status) { + // Not supposed to happen? + LL_WARNS("MaterialEditor") << "No permission to view material " << asset_uuid << LL_ENDL; LLNotificationsUtil::add("MaterialNoPermissions"); } else @@ -2999,7 +2996,7 @@ void LLMaterialEditor::onLoadComplete(const LLUUID& asset_uuid, } editor->setEnableEditing(false); - LL_WARNS() << "Problem loading material: " << status << LL_ENDL; + LL_WARNS("MaterialEditor") << "Problem loading material: " << status << LL_ENDL; editor->mAssetStatus = PREVIEW_ASSET_ERROR; } } -- cgit v1.2.3 From 7c853be544ba2313d82ddbc6960ae1bdd806e4d2 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 19 Jan 2023 19:43:37 +0200 Subject: SL-19005 Fix save button for local uploads --- indra/newview/llmaterialeditor.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 9efe5dc1f1..dabc7d16ea 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -2156,6 +2156,7 @@ void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std:: { openFloater(getKey()); setFocus(TRUE); + setCanSave(true); applyToSelection(); } -- cgit v1.2.3 From a3f43b4b73cc8fbd48a0574ebd74bbe660f8af50 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 23 Jan 2023 19:17:46 +0200 Subject: SL-19014 Sanitize the override data sent for faces without GLTF materials --- indra/newview/llmaterialeditor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index dabc7d16ea..a36ddeb532 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -2674,7 +2674,7 @@ public: { mSuccess = true; } - LLGLTFMaterialList::queueModify(objectp->getID(), te, material); + LLGLTFMaterialList::queueModify(objectp, te, material); } return true; } -- cgit v1.2.3 From 503e18fc646c6d88cd8006ad2210a8afd0bced83 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 25 Jan 2023 15:42:27 +0200 Subject: SL-19005 Fix 'save as' button for local uploads --- indra/newview/llmaterialeditor.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index a36ddeb532..5628327ebe 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -2157,6 +2157,7 @@ void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std:: openFloater(getKey()); setFocus(TRUE); setCanSave(true); + setCanSaveAs(true); applyToSelection(); } -- cgit v1.2.3 From dc1dd7a274e1ce49eb68ca525eba7f2e39032fa8 Mon Sep 17 00:00:00 2001 From: Brad Linden Date: Thu, 2 Feb 2023 12:25:03 -0800 Subject: Fix some unused variable warnings in DRTVWR-559 --- indra/newview/llmaterialeditor.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 5628327ebe..14ebfa451a 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -770,7 +770,7 @@ void LLMaterialEditor::markChangesUnsaved(U32 dirty_flag) const LLInventoryItem* item = getItem(); if (item) { - LLPermissions perm(item->getPermissions()); + //LLPermissions perm(item->getPermissions()); bool allow_modify = canModify(mObjectUUID, item); bool source_library = mObjectUUID.isNull() && gInventory.isObjectDescendentOf(mItemUUID, gInventory.getLibraryRootFolderID()); bool source_notecard = mNotecardInventoryID.notNull(); @@ -1339,7 +1339,6 @@ bool LLMaterialEditor::updateInventoryItem(const std::string &buffer, const LLUU } else if (!task_id.isNull() && !task_url.empty()) { - LLUUID object_uuid(task_id); uploadInfo = std::make_shared(task_id, item_id, LLAssetType::AT_MATERIAL, buffer, [](LLUUID itemId, LLUUID task_id, LLUUID newAssetId, LLSD) { @@ -1390,7 +1389,6 @@ void LLMaterialEditor::createInventoryItem(const std::string &buffer, const std: // gen a new uuid for this asset LLTransactionID tid; tid.generate(); // timestamp-based randomization + uniquification - LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); U32 next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Materials"); LLUUID parent = gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_MATERIAL); const U8 subtype = NO_INV_SUBTYPE; // TODO maybe use AT_SETTINGS and LLSettingsType::ST_MATERIAL ? -- cgit v1.2.3 From d6841c07983a46ff805ed23a7318efbf9cca3b24 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Thu, 9 Feb 2023 15:04:46 -0800 Subject: SL-19080: Update GLTF Material asset upload to v1.1, with stricter GLTF compliance and removal of unsupported features --- indra/newview/llmaterialeditor.cpp | 209 ++++++++++--------------------------- 1 file changed, 53 insertions(+), 156 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 5628327ebe..173f5620c6 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -277,10 +277,10 @@ bool LLSelectedTEGetMatData::apply(LLViewerObject* objectp, S32 te_index) llassert(mat.notNull()); // by this point shouldn't be null if (mat.notNull()) { - tex_color_id = mat->mBaseColorId; - tex_metal_id = mat->mMetallicRoughnessId; - tex_emissive_id = mat->mEmissiveId; - tex_normal_id = mat->mNormalId; + tex_color_id = mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]; + tex_metal_id = mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]; + tex_emissive_id = mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]; + tex_normal_id = mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]; } if (mFirst) { @@ -949,7 +949,7 @@ void LLMaterialEditor::onSelectCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_ } case MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY: { - nodep->mSavedGLTFOverrideMaterials[te]->setMetallicRoughnessId(mCtrl->getValue().asUUID(), true); + nodep->mSavedGLTFOverrideMaterials[te]->setOcclusionRoughnessMetallicId(mCtrl->getValue().asUUID(), true); break; } case MATERIAL_EMISIVE_TEX_DIRTY: @@ -991,30 +991,6 @@ void LLMaterialEditor::onSelectCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_ LLSelectMgr::getInstance()->getSelection()->applyToNodes(&func); } -static void write_color(const LLColor4& color, std::vector& c) -{ - for (int i = 0; i < c.size(); ++i) // NOTE -- use c.size because some gltf colors are 3-component - { - c[i] = color.mV[i]; - } -} - -static U32 write_texture(const LLUUID& id, tinygltf::Model& model) -{ - tinygltf::Image image; - image.uri = id.asString(); - model.images.push_back(image); - U32 image_idx = model.images.size() - 1; - - tinygltf::Texture texture; - texture.source = image_idx; - model.textures.push_back(texture); - U32 texture_idx = model.textures.size() - 1; - - return texture_idx; -} - - void LLMaterialEditor::onClickSave() { if (!capabilitiesAvailable()) @@ -1034,109 +1010,14 @@ void LLMaterialEditor::onClickSave() saveIfNeeded(); } - -std::string LLMaterialEditor::getGLTFJson(bool prettyprint) -{ - tinygltf::Model model; - getGLTFModel(model); - - std::ostringstream str; - - tinygltf::TinyGLTF gltf; - - gltf.WriteGltfSceneToStream(&model, str, prettyprint, false); - - std::string dump = str.str(); - - return dump; -} - -void LLMaterialEditor::getGLBData(std::vector& data) -{ - tinygltf::Model model; - getGLTFModel(model); - - std::ostringstream str; - - tinygltf::TinyGLTF gltf; - - gltf.WriteGltfSceneToStream(&model, str, false, true); - - std::string dump = str.str(); - - data.resize(dump.length()); - - memcpy(&data[0], dump.c_str(), dump.length()); -} - -void LLMaterialEditor::getGLTFModel(tinygltf::Model& model) -{ - model.materials.resize(1); - tinygltf::PbrMetallicRoughness& pbrMaterial = model.materials[0].pbrMetallicRoughness; - - // write base color - LLColor4 base_color = getBaseColor(); - base_color.mV[3] = getTransparency(); - write_color(base_color, pbrMaterial.baseColorFactor); - - model.materials[0].alphaCutoff = getAlphaCutoff(); - model.materials[0].alphaMode = getAlphaMode(); - - LLUUID base_color_id = getBaseColorId(); - - if (base_color_id.notNull()) - { - U32 texture_idx = write_texture(base_color_id, model); - - pbrMaterial.baseColorTexture.index = texture_idx; - } - - // write metallic/roughness - F32 metalness = getMetalnessFactor(); - F32 roughness = getRoughnessFactor(); - - pbrMaterial.metallicFactor = metalness; - pbrMaterial.roughnessFactor = roughness; - - LLUUID mr_id = getMetallicRoughnessId(); - if (mr_id.notNull()) - { - U32 texture_idx = write_texture(mr_id, model); - pbrMaterial.metallicRoughnessTexture.index = texture_idx; - } - - //write emissive - LLColor4 emissive_color = getEmissiveColor(); - model.materials[0].emissiveFactor.resize(3); - write_color(emissive_color, model.materials[0].emissiveFactor); - - LLUUID emissive_id = getEmissiveId(); - if (emissive_id.notNull()) - { - U32 idx = write_texture(emissive_id, model); - model.materials[0].emissiveTexture.index = idx; - } - - //write normal - LLUUID normal_id = getNormalId(); - if (normal_id.notNull()) - { - U32 idx = write_texture(normal_id, model); - model.materials[0].normalTexture.index = idx; - } - - //write doublesided - model.materials[0].doubleSided = getDoubleSided(); - - model.asset.version = "2.0"; -} - std::string LLMaterialEditor::getEncodedAsset() { LLSD asset; - asset["version"] = "1.0"; - asset["type"] = "GLTF 2.0"; - asset["data"] = getGLTFJson(false); + asset["version"] = LLGLTFMaterial::ASSET_VERSION; + asset["type"] = LLGLTFMaterial::ASSET_TYPE; + LLGLTFMaterial mat; + getGLTFMaterial(&mat); + asset["data"] = mat.asJSON(); std::ostringstream str; LLSDSerialize::serialize(asset, str, LLSDSerialize::LLSD_BINARY); @@ -1151,9 +1032,9 @@ bool LLMaterialEditor::decodeAsset(const std::vector& buffer) std::istrstream str(&buffer[0], buffer.size()); if (LLSDSerialize::deserialize(asset, str, buffer.size())) { - if (asset.has("version") && asset["version"] == "1.0") + if (asset.has("version") && LLGLTFMaterial::isAcceptedVersion(asset["version"].asString())) { - if (asset.has("type") && asset["type"] == "GLTF 2.0") + if (asset.has("type") && asset["type"] == LLGLTFMaterial::ASSET_TYPE) { if (asset.has("data") && asset["data"].isString()) { @@ -1169,6 +1050,12 @@ bool LLMaterialEditor::decodeAsset(const std::vector& buffer) if (loader.LoadASCIIFromString(&model_in, &error_msg, &warn_msg, data.c_str(), data.length(), "")) { // assets are only supposed to have one item + // *NOTE: This duplicates some functionality from + // LLGLTFMaterial::fromJSON, but currently does the job + // better for the material editor use case. + // However, LLGLTFMaterial::asJSON should always be + // used when uploading materials, to ensure the + // asset is valid. return setFromGltfModel(model_in, 0, true); } else @@ -1977,7 +1864,9 @@ void LLMaterialEditor::saveMaterialAs(const LLGLTFMaterial* render_material, con { // don't use override material here, it has 'hacked ids' // and values, use end result, apply it on top of local. - me->setBaseColor(render_material->mBaseColor); + const LLColor4& base_color = render_material->mBaseColor; + me->setBaseColor(LLColor3(base_color)); + me->setTransparency(base_color[VW]); me->setMetalnessFactor(render_material->mMetallicFactor); me->setRoughnessFactor(render_material->mRoughnessFactor); me->setEmissiveColor(render_material->mEmissiveColor); @@ -1988,24 +1877,24 @@ void LLMaterialEditor::saveMaterialAs(const LLGLTFMaterial* render_material, con // most things like colors we can apply without verifying // but texture ids are going to be different from both, base and override // so only apply override id if there is actually a difference - if (local_material->mBaseColorId != render_material->mBaseColorId) + if (local_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] != render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]) { - me->setBaseColorId(render_material->mBaseColorId); + me->setBaseColorId(render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]); me->childSetValue("base_color_upload_fee", me->getString("no_upload_fee_string")); } - if (local_material->mNormalId != render_material->mNormalId) + if (local_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] != render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]) { - me->setNormalId(render_material->mNormalId); + me->setNormalId(render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]); me->childSetValue("normal_upload_fee", me->getString("no_upload_fee_string")); } - if (local_material->mMetallicRoughnessId != render_material->mMetallicRoughnessId) + if (local_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] != render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]) { - me->setMetallicRoughnessId(render_material->mMetallicRoughnessId); + me->setMetallicRoughnessId(render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]); me->childSetValue("metallic_upload_fee", me->getString("no_upload_fee_string")); } - if (local_material->mEmissiveId != render_material->mEmissiveId) + if (local_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] != render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]) { - me->setEmissiveId(render_material->mEmissiveId); + me->setEmissiveId(render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]); me->childSetValue("emissive_upload_fee", me->getString("no_upload_fee_string")); } @@ -2019,7 +1908,11 @@ void LLMaterialEditor::saveMaterialAs(const LLGLTFMaterial* render_material, con LLSD payload; if (render_material) { - payload["data"] = render_material->asJSON(); + // Make a copy of the render material with unsupported transforms removed + LLGLTFMaterial asset_material = *render_material; + asset_material.sanitizeAssetMaterial(); + // Serialize the sanitized render material + payload["data"] = asset_material.asJSON(); } else { @@ -2042,8 +1935,9 @@ void LLMaterialEditor::onSaveObjectsMaterialAsMsgCallback(const LLSD& notificati if (0 == option) { LLSD asset; - asset["version"] = "1.0"; - asset["type"] = "GLTF 2.0"; + asset["version"] = LLGLTFMaterial::ASSET_VERSION; + asset["type"] = LLGLTFMaterial::ASSET_TYPE; + // This is the string serialized from LLGLTFMaterial::asJSON asset["data"] = notification["payload"]["data"]; std::ostringstream str; @@ -2586,7 +2480,7 @@ public: } else if ((reverted_flags & MATERIAL_BASE_COLOR_TEX_DIRTY) && revert_mat.notNull()) { - material->setBaseColorId(revert_mat->mBaseColorId, false); + material->setBaseColorId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR], false); } if (changed_flags & MATERIAL_NORMAL_TEX_DIRTY) @@ -2595,16 +2489,16 @@ public: } else if ((reverted_flags & MATERIAL_NORMAL_TEX_DIRTY) && revert_mat.notNull()) { - material->setNormalId(revert_mat->mNormalId, false); + material->setNormalId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL], false); } if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) { - material->setMetallicRoughnessId(mEditor->getMetallicRoughnessId(), true); + material->setOcclusionRoughnessMetallicId(mEditor->getMetallicRoughnessId(), true); } else if ((reverted_flags & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) && revert_mat.notNull()) { - material->setMetallicRoughnessId(revert_mat->mMetallicRoughnessId, false); + material->setOcclusionRoughnessMetallicId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS], false); } if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY) @@ -2640,7 +2534,7 @@ public: } else if ((reverted_flags & MATERIAL_EMISIVE_TEX_DIRTY) && revert_mat.notNull()) { - material->setEmissiveId(revert_mat->mEmissiveId, false); + material->setEmissiveId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE], false); } if (changed_flags & MATERIAL_DOUBLE_SIDED_DIRTY) @@ -2753,20 +2647,23 @@ void LLMaterialEditor::applyToSelection() } } +// Get a dump of the json representation of the current state of the editor UI +// in GLTF format, excluding transforms as they are not supported in material +// assets. (See also LLGLTFMaterial::sanitizeAssetMaterial()) void LLMaterialEditor::getGLTFMaterial(LLGLTFMaterial* mat) { mat->mBaseColor = getBaseColor(); mat->mBaseColor.mV[3] = getTransparency(); - mat->mBaseColorId = getBaseColorId(); + mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] = getBaseColorId(); - mat->mNormalId = getNormalId(); + mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] = getNormalId(); - mat->mMetallicRoughnessId = getMetallicRoughnessId(); + mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] = getMetallicRoughnessId(); mat->mMetallicFactor = getMetalnessFactor(); mat->mRoughnessFactor = getRoughnessFactor(); mat->mEmissiveColor = getEmissiveColor(); - mat->mEmissiveId = getEmissiveId(); + mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] = getEmissiveId(); mat->mDoubleSided = getDoubleSided(); mat->setAlphaMode(getAlphaMode()); @@ -2776,15 +2673,15 @@ void LLMaterialEditor::getGLTFMaterial(LLGLTFMaterial* mat) void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat) { setBaseColor(mat->mBaseColor); - setBaseColorId(mat->mBaseColorId); - setNormalId(mat->mNormalId); + setBaseColorId(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]); + setNormalId(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]); - setMetallicRoughnessId(mat->mMetallicRoughnessId); + setMetallicRoughnessId(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]); setMetalnessFactor(mat->mMetallicFactor); setRoughnessFactor(mat->mRoughnessFactor); setEmissiveColor(mat->mEmissiveColor); - setEmissiveId(mat->mEmissiveId); + setEmissiveId(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]); setDoubleSided(mat->mDoubleSided); setAlphaMode(mat->getAlphaMode()); -- cgit v1.2.3 From 17d3f3786376578b765cd7a9b7f9a9e391e53cb9 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 16 Feb 2023 21:33:14 +0200 Subject: SL-17640 Fix 'Apply now' being enabled when importing --- indra/newview/llmaterialeditor.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 41085afb3d..64ce5fd4d2 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -420,6 +420,13 @@ BOOL LLMaterialEditor::postBuild() mEmissiveTextureCtrl->setOnSelectCallback(boost::bind(&LLMaterialEditor::onSelectCtrl, this, _1, _2, MATERIAL_EMISIVE_TEX_DIRTY)); mNormalTextureCtrl->setOnSelectCallback(boost::bind(&LLMaterialEditor::onSelectCtrl, this, _1, _2, MATERIAL_NORMAL_TEX_DIRTY)); } + else + { + mBaseColorTextureCtrl->setCanApplyImmediately(false); + mMetallicTextureCtrl->setCanApplyImmediately(false); + mEmissiveTextureCtrl->setCanApplyImmediately(false); + mNormalTextureCtrl->setCanApplyImmediately(false); + } if (!mIsOverride) { @@ -461,6 +468,10 @@ BOOL LLMaterialEditor::postBuild() mBaseColorCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_BASE_COLOR_DIRTY)); mBaseColorCtrl->setOnSelectCallback(boost::bind(&LLMaterialEditor::onSelectCtrl, this, _1, _2, MATERIAL_BASE_COLOR_DIRTY)); } + else + { + mBaseColorCtrl->setCanApplyImmediately(false); + } // transparency is a part of base color childSetCommitCallback("transparency", changes_callback, (void*)&MATERIAL_BASE_COLOR_DIRTY); childSetCommitCallback("alpha mode", changes_callback, (void*)&MATERIAL_ALPHA_MODE_DIRTY); @@ -477,6 +488,10 @@ BOOL LLMaterialEditor::postBuild() mEmissiveColorCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_EMISIVE_COLOR_DIRTY)); mEmissiveColorCtrl->setOnSelectCallback(boost::bind(&LLMaterialEditor::onSelectCtrl, this, _1, _2, MATERIAL_EMISIVE_COLOR_DIRTY)); } + else + { + mEmissiveColorCtrl->setCanApplyImmediately(false); + } if (!mIsOverride) { -- cgit v1.2.3 From b9b913a60ada97fc61bf2176e443dc72c8359ccb Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 7 Mar 2023 09:38:43 -0600 Subject: SL-19349 Fix for hang on bulk upload of materials, add bulk upload option to material selector, incidental decruft. --- indra/newview/llmaterialeditor.cpp | 60 +++++++++++++++----------------------- 1 file changed, 24 insertions(+), 36 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 64ce5fd4d2..4cdc503af8 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1622,40 +1622,13 @@ static void pack_textures( } } -void LLMaterialEditor::uploadMaterialFromFile(const std::string& filename, S32 index) +void LLMaterialEditor::uploadMaterialFromModel(const std::string& filename, tinygltf::Model& model_in, S32 index) { if (index < 0 || !LLMaterialEditor::capabilitiesAvailable()) { return; } - tinygltf::TinyGLTF loader; - std::string error_msg; - std::string warn_msg; - - bool loaded = false; - tinygltf::Model model_in; - - std::string filename_lc = filename; - LLStringUtil::toLower(filename_lc); - - // Load a tinygltf model fom a file. Assumes that the input filename has already been - // been sanitized to one of (.gltf , .glb) extensions, so does a simple find to distinguish. - if (std::string::npos == filename_lc.rfind(".gltf")) - { // file is binary - loaded = loader.LoadBinaryFromFile(&model_in, &error_msg, &warn_msg, filename); - } - else - { // file is ascii - loaded = loader.LoadASCIIFromFile(&model_in, &error_msg, &warn_msg, filename); - } - - if (!loaded) - { - LLNotificationsUtil::add("CannotUploadMaterial"); - return; - } - if (model_in.materials.empty()) { // materials are missing @@ -1672,13 +1645,15 @@ void LLMaterialEditor::uploadMaterialFromFile(const std::string& filename, S32 i // This uses 'filename' to make sure multiple bulk uploads work // instead of fighting for a single instance. LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", LLSD().with("filename", filename).with("index", LLSD::Integer(index))); - me->loadMaterial(model_in, filename_lc, index, false); + me->loadMaterial(model_in, filename, index, false); me->saveIfNeeded(); } void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 index) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; + tinygltf::TinyGLTF loader; std::string error_msg; std::string warn_msg; @@ -1725,12 +1700,12 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind if (index >= 0) { // Prespecified material - me->loadMaterial(model_in, filename_lc, index); + me->loadMaterial(model_in, filename, index); } else if (model_in.materials.size() == 1) { // Only one, just load it - me->loadMaterial(model_in, filename_lc, 0); + me->loadMaterial(model_in, filename, 0); } else { @@ -1738,6 +1713,7 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind std::list material_list; std::vector::const_iterator mat_iter = model_in.materials.begin(); std::vector::const_iterator mat_end = model_in.materials.end(); + for (; mat_iter != mat_end; mat_iter++) { std::string mat_name = mat_iter->name; @@ -1750,10 +1726,13 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind material_list.push_back(mat_name); } } + + material_list.push_back(me->getString("material_batch_import_text")); + LLFloaterComboOptions::showUI( - [me, model_in, filename_lc](const std::string& option, S32 index) + [me, model_in, filename](const std::string& option, S32 index) { - me->loadMaterial(model_in, filename_lc, index); + me->loadMaterial(model_in, filename, index); }, me->getString("material_selection_title"), me->getString("material_selection_text"), @@ -1961,13 +1940,22 @@ void LLMaterialEditor::onSaveObjectsMaterialAsMsgCallback(const LLSD& notificati } } -void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std::string &filename_lc, S32 index, bool open_floater) +const void upload_bulk(const std::vector& filenames, LLFilePicker::ELoadFilter type); + +void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std::string &filename, S32 index, bool open_floater) { + if (index == model_in.materials.size()) + { + // bulk upload all the things + upload_bulk({ filename }, LLFilePicker::FFLOAD_MATERIAL); + return; + } + if (model_in.materials.size() <= index) { return; } - std::string folder = gDirUtilp->getDirName(filename_lc); + std::string folder = gDirUtilp->getDirName(filename); tinygltf::Material material_in = model_in.materials[index]; @@ -2055,7 +2043,7 @@ void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std:: setFromGltfModel(model_in, index); - setFromGltfMetaData(filename_lc, model_in, index); + setFromGltfMetaData(filename, model_in, index); markChangesUnsaved(U32_MAX); -- cgit v1.2.3 From b30cde2a05c5217018d8be7608f14bda8b66127a Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 21 Mar 2023 21:31:18 +0200 Subject: SL-19392 Disable "Double Sided" by default when importing double sided materials --- indra/newview/llmaterialeditor.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 4cdc503af8..609d8ea5d7 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -2045,6 +2045,15 @@ void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std:: setFromGltfMetaData(filename, model_in, index); + if (getDoubleSided()) + { + // SL-19392 Double sided materials double the number of pixels that must be rasterized, + // and a great many tools that export GLTF simply leave double sided enabled whether + // or not it is necessary. + LL_DEBUGS("MaterialEditor") << "Defaulting Double Sided to disabled on import" << LL_ENDL; + setDoubleSided(false); + } + markChangesUnsaved(U32_MAX); if (open_floater) -- cgit v1.2.3 From df1eb38b2109bf9cb57b42e2c361c4143276ae5a Mon Sep 17 00:00:00 2001 From: Brad Linden Date: Thu, 13 Jul 2023 10:08:19 -0700 Subject: SL-19999 stop outputing debug info about created material asset id unnecessarily --- indra/newview/llmaterialeditor.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 609d8ea5d7..3a0e64985c 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1327,9 +1327,7 @@ void LLMaterialEditor::createInventoryItem(const std::string &buffer, const std: [](LLUUID item_id, LLUUID new_asset_id, LLUUID new_item_id, LLSD response) { // done callback - LL_INFOS("Material") << "inventory item uploaded. item: " << item_id << " asset: " << new_asset_id << " new_item_id: " << new_item_id << " response: " << response << LL_ENDL; - LLSD params = llsd::map("ASSET_ID", new_asset_id); - LLNotificationsUtil::add("MaterialCreated", params); + LL_INFOS("Material") << "inventory item uploaded. item: " << item_id << " new_item_id: " << new_item_id << " response: " << response << LL_ENDL; }, nullptr // failure callback, floater already closed ); -- cgit v1.2.3 From ca6f465088be904fa5b85297396227f905792a3b Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Mon, 24 Jul 2023 16:16:52 -0700 Subject: SL-20024: Disable material editor on prim when contained material is no mod --- indra/newview/llmaterialeditor.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 3a0e64985c..b30f94e145 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -238,6 +238,7 @@ struct LLSelectedTEGetMatData : public LLSelectedTEFunctor LLUUID mTexNormalId; LLUUID mObjectId; S32 mObjectTE; + LLUUID mMaterialId; LLPointer mMaterial; LLPointer mLocalMaterial; }; @@ -259,6 +260,7 @@ bool LLSelectedTEGetMatData::apply(LLViewerObject* objectp, S32 te_index) return false; } LLUUID mat_id = objectp->getRenderMaterialID(te_index); + mMaterialId = mat_id; bool can_use = mIsOverride ? objectp->permModify() : objectp->permCopy(); LLTextureEntry *tep = objectp->getTE(te_index); // We might want to disable this entirely if at least @@ -2708,7 +2710,10 @@ bool LLMaterialEditor::setFromSelection() if (func.mMaterial.notNull()) { setFromGLTFMaterial(func.mMaterial); - setEnableEditing(true); + LLViewerObject* selected_object = selected_objects->getFirstSelectedObject(NULL); + const LLViewerInventoryItem* item = selected_object->getInventoryItemByAsset(func.mMaterialId); + const bool allow_modify = !item || canModify(selected_object, item); + setEnableEditing(allow_modify); } else { -- cgit v1.2.3 From 7bf6103ad95c281c2ed680c9eb9b07cc584ddc91 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 25 Jul 2023 14:52:56 -0700 Subject: SL-20024: (WIP) (not tested) Improved behavior for saving material to inventory. Check perms, keep perms. --- indra/newview/llmaterialeditor.cpp | 164 +++++++++++++++++++++++++++---------- 1 file changed, 121 insertions(+), 43 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index b30f94e145..6e043ecee5 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -237,6 +237,7 @@ struct LLSelectedTEGetMatData : public LLSelectedTEFunctor LLUUID mTexEmissiveId; LLUUID mTexNormalId; LLUUID mObjectId; + LLViewerObject* mObject = nullptr; S32 mObjectTE; LLUUID mMaterialId; LLPointer mMaterial; @@ -293,6 +294,7 @@ bool LLSelectedTEGetMatData::apply(LLViewerObject* objectp, S32 te_index) mTexNormalId = tex_normal_id; mObjectTE = te_index; mObjectId = objectp->getID(); + mObject = objectp; mFirst = false; } else @@ -1194,7 +1196,9 @@ bool LLMaterialEditor::saveIfNeeded() { //make a new inventory item std::string res_desc = buildMaterialDescription(); - createInventoryItem(buffer, mMaterialName, res_desc); + LLPermissions local_permissions; + local_permissions.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null); + createInventoryItem(buffer, mMaterialName, res_desc, local_permissions); // We do not update floater with uploaded asset yet, so just close it. closeFloater(); @@ -1288,7 +1292,7 @@ bool LLMaterialEditor::updateInventoryItem(const std::string &buffer, const LLUU return true; } -void LLMaterialEditor::createInventoryItem(const std::string &buffer, const std::string &name, const std::string &desc) +void LLMaterialEditor::createInventoryItem(const std::string &buffer, const std::string &name, const std::string &desc, const LLPermissions& owner_permissions) { // gen a new uuid for this asset LLTransactionID tid; @@ -1299,7 +1303,7 @@ void LLMaterialEditor::createInventoryItem(const std::string &buffer, const std: create_inventory_item(gAgent.getID(), gAgent.getSessionID(), parent, tid, name, desc, LLAssetType::AT_MATERIAL, LLInventoryType::IT_MATERIAL, subtype, next_owner_perm, - new LLBoostFuncInventoryCallback([output = buffer](LLUUID const& inv_item_id) + new LLBoostFuncInventoryCallback([output = buffer, owner_permissions](LLUUID const& inv_item_id) { LLViewerInventoryItem* item = gInventory.getItem(inv_item_id); if (item) @@ -1309,8 +1313,15 @@ void LLMaterialEditor::createInventoryItem(const std::string &buffer, const std: if (perm.getMaskEveryone() != LLFloaterPerms::getEveryonePerms("Materials") || perm.getMaskGroup() != LLFloaterPerms::getGroupPerms("Materials")) { - perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Materials")); - perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Materials")); + LLPermissions floater_perm; + floater_perm.set(perm); + floater_perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Materials")); + floater_perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Materials")); + perm.accumulate(floater_perm); + perm.accumulate(owner_permissions); + // TODO: Decide if these are needed + perm.setCreator(owner_permissions.getCreator()); + perm.setLastOwner(owner_permissions.getLastOwner()); item->setPermissions(perm); @@ -1794,55 +1805,112 @@ void LLMaterialEditor::loadLive() } } -void LLMaterialEditor::saveObjectsMaterialAs() +// *NOTE: permissions_out ignores user preferences for new item creation +// (LLFloaterPerms). Those are applied later on in +// LLMaterialEditor::createInventoryItem. +bool can_save_objects_material(LLSelectedTEGetMatData& func, LLPermissions& permissions_out) { - LLSelectedTEGetMatData func(false); LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func, true /*first applicable*/); - saveMaterialAs(func.mMaterial, func.mLocalMaterial); -} -void LLMaterialEditor::savePickedMaterialAs() -{ - LLPickInfo pick = LLToolPie::getInstance()->getPick(); - if (pick.mPickType != LLPickInfo::PICK_OBJECT || !pick.getObject()) + LLViewerObject* selected_object = func.mObject; + llassert(selected_object); // Note the function name + const LLViewerInventoryItem* item = selected_object->getInventoryItemByAsset(func.mMaterialId); + + LLPermissions item_permissions; + const bool previous_item_owned = item && item->getPermissions().getLastOwner().notNull(); + if (item) { - return; + item_permissions.set(item->getPermissions()); + if (!gAgent.allowOperation(PERM_MODIFY, item_permissions, GP_OBJECT_MANIPULATE)) + { + return false; + } + if (!gAgent.allowOperation(PERM_COPY, item_permissions, GP_OBJECT_MANIPULATE)) + { + return false; + } + if (!item_permissions.setOwnerAndGroup(LLUUID::null, gAgent.getID(), LLUUID::null, true)) + { + llassert(false); + return false; + } } - - LLPointer render_material; - LLPointer local_material; - - LLViewerObject *objectp = pick.getObject(); - LLUUID mat_id = objectp->getRenderMaterialID(pick.mObjectFace); - if (mat_id.notNull() && objectp->permCopy()) + else { - // Try a face user picked first - // (likely the only method we need, but in such case - // enable_object_save_gltf_material will need to check this) - LLTextureEntry *tep = objectp->getTE(pick.mObjectFace); - LLGLTFMaterial *mat = tep->getGLTFMaterial(); - LLLocalGLTFMaterial *local_mat = dynamic_cast(mat); + item_permissions.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null); + } - if (local_mat) + LLPermissions* object_permissions_p = LLSelectMgr::getInstance()->findObjectPermissions(selected_object); + LLPermissions object_permissions; + const bool previous_object_owned = object_permissions_p && object_permissions_p->getLastOwner().notNull(); + if (object_permissions_p) + { + object_permissions.set(*object_permissions_p); + if (!gAgent.allowOperation(PERM_MODIFY, object_permissions, GP_OBJECT_MANIPULATE)) { - local_material = local_mat; + return false; + } + if (!gAgent.allowOperation(PERM_COPY, object_permissions, GP_OBJECT_MANIPULATE)) + { + return false; + } + if (!object_permissions.setOwnerAndGroup(LLUUID::null, gAgent.getID(), LLUUID::null, true)) + { + llassert(false); + return false; } - render_material = tep->getGLTFRenderMaterial(); } else { - // Find an applicable material. - // Do this before showing message, because - // message is going to drop selection. - LLSelectedTEGetMatData func(false); - LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func, true /*first applicable*/); - local_material = func.mLocalMaterial; - render_material = func.mMaterial; + object_permissions.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null); } - saveMaterialAs(render_material, local_material); + permissions_out.set(item_permissions); + permissions_out.accumulate(object_permissions); + + if (previous_item_owned != previous_object_owned) + { + // Likely ownership history conflict. Prefer the item history. Fall + // back to object history if no associated item. + if (previous_item_owned) + { + permissions_out.setCreator(item_permissions.getCreator()); + permissions_out.setLastOwner(item_permissions.getLastOwner()); + } + else if (previous_object_owned) + { + permissions_out.setCreator(object_permissions.getCreator()); + permissions_out.setLastOwner(object_permissions.getLastOwner()); + } + } + + llassert(permissions_out.getOwner() == gAgent.getID()); + llassert(permissions_out.getCreator().notNull()); + llassert(permissions_out.getGroup().isNull()); + + return true; +} + +bool LLMaterialEditor::canSaveObjectsMaterial() +{ + LLSelectedTEGetMatData func(false); + LLPermissions permissions; + return can_save_objects_material(func, permissions); } -void LLMaterialEditor::saveMaterialAs(const LLGLTFMaterial* render_material, const LLLocalGLTFMaterial *local_material) +void LLMaterialEditor::saveObjectsMaterialAs() +{ + LLSelectedTEGetMatData func(false); + LLPermissions permissions; + bool allowed = can_save_objects_material(func, permissions); + if (!allowed) + { + LL_WARNS("MaterialEditor") << "Failed to save GLTF material from object" << LL_ENDL; + return; + } + saveMaterialAs(func.mMaterial, func.mLocalMaterial, permissions); +} + +void LLMaterialEditor::saveMaterialAs(const LLGLTFMaterial* render_material, const LLLocalGLTFMaterial *local_material, const LLPermissions& permissions) { if (local_material) { @@ -1918,10 +1986,20 @@ void LLMaterialEditor::saveMaterialAs(const LLGLTFMaterial* render_material, con LLSD args; args["DESC"] = LLTrans::getString("New Material"); - LLNotificationsUtil::add("SaveMaterialAs", args, payload, boost::bind(&LLMaterialEditor::onSaveObjectsMaterialAsMsgCallback, _1, _2)); + // At this point, last owner, etc should be set. LLFloaterPerms will be honored later on + if (local_material) + { + LLPermissions local_permissions; + local_permissions.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null); + LLNotificationsUtil::add("SaveMaterialAs", args, payload, boost::bind(&LLMaterialEditor::onSaveObjectsMaterialAsMsgCallback, _1, _2, local_permissions)); + } + else + { + LLNotificationsUtil::add("SaveMaterialAs", args, payload, boost::bind(&LLMaterialEditor::onSaveObjectsMaterialAsMsgCallback, _1, _2, permissions)); + } } -void LLMaterialEditor::onSaveObjectsMaterialAsMsgCallback(const LLSD& notification, const LLSD& response) +void LLMaterialEditor::onSaveObjectsMaterialAsMsgCallback(const LLSD& notification, const LLSD& response, const LLPermissions& permissions) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); if (0 == option) @@ -1936,7 +2014,7 @@ void LLMaterialEditor::onSaveObjectsMaterialAsMsgCallback(const LLSD& notificati LLSDSerialize::serialize(asset, str, LLSDSerialize::LLSD_BINARY); std::string new_name = response["message"].asString(); - createInventoryItem(str.str(), new_name, std::string()); + createInventoryItem(str.str(), new_name, std::string(), permissions); } } @@ -2710,7 +2788,7 @@ bool LLMaterialEditor::setFromSelection() if (func.mMaterial.notNull()) { setFromGLTFMaterial(func.mMaterial); - LLViewerObject* selected_object = selected_objects->getFirstSelectedObject(NULL); + LLViewerObject* selected_object = func.mObject; const LLViewerInventoryItem* item = selected_object->getInventoryItemByAsset(func.mMaterialId); const bool allow_modify = !item || canModify(selected_object, item); setEnableEditing(allow_modify); -- cgit v1.2.3 From a5d318567cc5c3e8f2f86fce1132f5883014e14e Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 28 Jul 2023 17:29:09 -0700 Subject: SL-20024: (WIP) (untested) Fix GLTF material permissions in some more edge cases --- indra/newview/llmaterialeditor.cpp | 139 ++++++++++++++++++++----------------- 1 file changed, 75 insertions(+), 64 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 6e043ecee5..af40c9e931 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -293,8 +293,8 @@ bool LLSelectedTEGetMatData::apply(LLViewerObject* objectp, S32 te_index) mTexEmissiveId = tex_emissive_id; mTexNormalId = tex_normal_id; mObjectTE = te_index; - mObjectId = objectp->getID(); mObject = objectp; + mObjectId = objectp->getID(); mFirst = false; } else @@ -322,6 +322,7 @@ bool LLSelectedTEGetMatData::apply(LLViewerObject* objectp, S32 te_index) LLGLTFMaterial *mat = tep->getGLTFMaterial(); LLLocalGLTFMaterial *local_mat = dynamic_cast(mat); + mObject = objectp; if (local_mat) { mLocalMaterial = local_mat; @@ -1297,38 +1298,39 @@ void LLMaterialEditor::createInventoryItem(const std::string &buffer, const std: // gen a new uuid for this asset LLTransactionID tid; tid.generate(); // timestamp-based randomization + uniquification - U32 next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Materials"); + LLPermissions final_perm; + { + final_perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null); + + LLPermissions floater_perm; + floater_perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null); + floater_perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Materials")); + floater_perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Materials")); + floater_perm.setMaskNext(LLFloaterPerms::getNextOwnerPerms("Materials")); + + final_perm.accumulate(floater_perm); + final_perm.accumulate(owner_permissions); + } + // NOTE: create_inventory_item doesn't allow presetting some permissions. + // The rest will be fixed after the callback. LLUUID parent = gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_MATERIAL); const U8 subtype = NO_INV_SUBTYPE; // TODO maybe use AT_SETTINGS and LLSettingsType::ST_MATERIAL ? create_inventory_item(gAgent.getID(), gAgent.getSessionID(), parent, tid, name, desc, - LLAssetType::AT_MATERIAL, LLInventoryType::IT_MATERIAL, subtype, next_owner_perm, - new LLBoostFuncInventoryCallback([output = buffer, owner_permissions](LLUUID const& inv_item_id) + LLAssetType::AT_MATERIAL, LLInventoryType::IT_MATERIAL, subtype, final_perm.getMaskNextOwner(), + new LLBoostFuncInventoryCallback([output = buffer, final_perm](LLUUID const& inv_item_id) { LLViewerInventoryItem* item = gInventory.getItem(inv_item_id); if (item) { // create_inventory_item doesn't allow presetting some permissions, fix it now LLPermissions perm = item->getPermissions(); - if (perm.getMaskEveryone() != LLFloaterPerms::getEveryonePerms("Materials") - || perm.getMaskGroup() != LLFloaterPerms::getGroupPerms("Materials")) - { - LLPermissions floater_perm; - floater_perm.set(perm); - floater_perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Materials")); - floater_perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Materials")); - perm.accumulate(floater_perm); - perm.accumulate(owner_permissions); - // TODO: Decide if these are needed - perm.setCreator(owner_permissions.getCreator()); - perm.setLastOwner(owner_permissions.getLastOwner()); + perm.accumulate(final_perm); + item->setPermissions(perm); - item->setPermissions(perm); - - item->updateServer(FALSE); - gInventory.updateItem(item); - gInventory.notifyObservers(); - } + item->updateServer(FALSE); + gInventory.updateItem(item); + gInventory.notifyObservers(); } // from reference in LLSettingsVOBase::createInventoryItem()/updateInventoryItem() @@ -1805,29 +1807,47 @@ void LLMaterialEditor::loadLive() } } -// *NOTE: permissions_out ignores user preferences for new item creation -// (LLFloaterPerms). Those are applied later on in +// *NOTE: permissions_out ignores user preferences for new item creation. See +// LLFloaterPerms. Preferences are applied later on in // LLMaterialEditor::createInventoryItem. -bool can_save_objects_material(LLSelectedTEGetMatData& func, LLPermissions& permissions_out) +bool can_use_objects_material(LLSelectedTEGetMatData& func, const std::vector& ops, LLPermissions& permissions_out) { + if (!LLMaterialEditor::capabilitiesAvailable()) + { + return false; + } + LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func, true /*first applicable*/); LLViewerObject* selected_object = func.mObject; - llassert(selected_object); // Note the function name + if (!selected_object) + { + // LLSelectedTEGetMatData can fail if there are no selected faces + // with materials, but we expect at least some object is selected. + llassert(LLSelectMgr::getInstance()->getSelection()->getFirstObject()); + return false; + } + for (PermissionBit op : ops) + { + if (op == PERM_MODIFY && selected_object->isPermanentEnforced()) + { + return false; + } + } + const LLViewerInventoryItem* item = selected_object->getInventoryItemByAsset(func.mMaterialId); LLPermissions item_permissions; - const bool previous_item_owned = item && item->getPermissions().getLastOwner().notNull(); if (item) { item_permissions.set(item->getPermissions()); - if (!gAgent.allowOperation(PERM_MODIFY, item_permissions, GP_OBJECT_MANIPULATE)) - { - return false; - } - if (!gAgent.allowOperation(PERM_COPY, item_permissions, GP_OBJECT_MANIPULATE)) + for (PermissionBit op : ops) { - return false; + if (!gAgent.allowOperation(op, item_permissions, GP_OBJECT_MANIPULATE)) + { + return false; + } } + // Update flags for new owner if (!item_permissions.setOwnerAndGroup(LLUUID::null, gAgent.getID(), LLUUID::null, true)) { llassert(false); @@ -1839,20 +1859,21 @@ bool can_save_objects_material(LLSelectedTEGetMatData& func, LLPermissions& perm item_permissions.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null); } - LLPermissions* object_permissions_p = LLSelectMgr::getInstance()->findObjectPermissions(selected_object); + // Use root object for permissions checking + LLViewerObject* root_object = selected_object->getRootEdit(); + LLPermissions* object_permissions_p = LLSelectMgr::getInstance()->findObjectPermissions(root_object); LLPermissions object_permissions; - const bool previous_object_owned = object_permissions_p && object_permissions_p->getLastOwner().notNull(); if (object_permissions_p) { object_permissions.set(*object_permissions_p); - if (!gAgent.allowOperation(PERM_MODIFY, object_permissions, GP_OBJECT_MANIPULATE)) + for (PermissionBit op : ops) { - return false; - } - if (!gAgent.allowOperation(PERM_COPY, object_permissions, GP_OBJECT_MANIPULATE)) - { - return false; + if (!gAgent.allowOperation(op, object_permissions, GP_OBJECT_MANIPULATE)) + { + return false; + } } + // Update flags for new owner if (!object_permissions.setOwnerAndGroup(LLUUID::null, gAgent.getID(), LLUUID::null, true)) { llassert(false); @@ -1865,43 +1886,34 @@ bool can_save_objects_material(LLSelectedTEGetMatData& func, LLPermissions& perm } permissions_out.set(item_permissions); + // *NOTE: A close inspection of LLPermissions::accumulate shows that + // conflicting UUIDs will be unset. This is acceptable behavior for now. + // The server doesn't allow us to create an item while claiming someone + // else was the creator/previous owner. permissions_out.accumulate(object_permissions); - if (previous_item_owned != previous_object_owned) - { - // Likely ownership history conflict. Prefer the item history. Fall - // back to object history if no associated item. - if (previous_item_owned) - { - permissions_out.setCreator(item_permissions.getCreator()); - permissions_out.setLastOwner(item_permissions.getLastOwner()); - } - else if (previous_object_owned) - { - permissions_out.setCreator(object_permissions.getCreator()); - permissions_out.setLastOwner(object_permissions.getLastOwner()); - } - } - - llassert(permissions_out.getOwner() == gAgent.getID()); - llassert(permissions_out.getCreator().notNull()); - llassert(permissions_out.getGroup().isNull()); - return true; } +bool LLMaterialEditor::canModifyObjectsMaterial() +{ + LLSelectedTEGetMatData func(false); + LLPermissions permissions; + return can_use_objects_material(func, std::vector({PERM_MODIFY}), permissions); +} + bool LLMaterialEditor::canSaveObjectsMaterial() { LLSelectedTEGetMatData func(false); LLPermissions permissions; - return can_save_objects_material(func, permissions); + return can_use_objects_material(func, std::vector({PERM_COPY, PERM_MODIFY}), permissions); } void LLMaterialEditor::saveObjectsMaterialAs() { LLSelectedTEGetMatData func(false); LLPermissions permissions; - bool allowed = can_save_objects_material(func, permissions); + bool allowed = can_use_objects_material(func, std::vector({PERM_COPY, PERM_MODIFY}), permissions); if (!allowed) { LL_WARNS("MaterialEditor") << "Failed to save GLTF material from object" << LL_ENDL; @@ -1986,7 +1998,6 @@ void LLMaterialEditor::saveMaterialAs(const LLGLTFMaterial* render_material, con LLSD args; args["DESC"] = LLTrans::getString("New Material"); - // At this point, last owner, etc should be set. LLFloaterPerms will be honored later on if (local_material) { LLPermissions local_permissions; -- cgit v1.2.3 From 76c8cca9363c0ef55bf66a2bbff4a86a02f37acf Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Mon, 7 Aug 2023 14:26:33 -0700 Subject: SL-20024: Fix author attributions not transferring for saved object materials, fix item not renamed --- indra/newview/llmaterialeditor.cpp | 178 +++++++++++++++++++++++++++---------- 1 file changed, 130 insertions(+), 48 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index af40c9e931..bc3d5b88ab 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -37,6 +37,7 @@ #include "llfilesystem.h" #include "llgltfmateriallist.h" #include "llinventorymodel.h" +#include "llinventoryobserver.h" #include "lllocalgltfmaterials.h" #include "llnotificationsutil.h" #include "lltexturectrl.h" @@ -323,6 +324,7 @@ bool LLSelectedTEGetMatData::apply(LLViewerObject* objectp, S32 te_index) LLLocalGLTFMaterial *local_mat = dynamic_cast(mat); mObject = objectp; + mObjectId = objectp->getID(); if (local_mat) { mLocalMaterial = local_mat; @@ -1293,44 +1295,38 @@ bool LLMaterialEditor::updateInventoryItem(const std::string &buffer, const LLUU return true; } -void LLMaterialEditor::createInventoryItem(const std::string &buffer, const std::string &name, const std::string &desc, const LLPermissions& owner_permissions) +// Callback intended for when an item is copied from an object's inventory and +// needs to be modified to reflect the new asset/name. For example: When saving +// a modified material to the inventory from the build floater. +class LLObjectsMaterialItemCallback : public LLInventoryCallback { - // gen a new uuid for this asset - LLTransactionID tid; - tid.generate(); // timestamp-based randomization + uniquification - LLPermissions final_perm; +public: + LLObjectsMaterialItemCallback(const LLPermissions& permissions, const std::string& asset_data, const std::string& new_name) + : mPermissions(permissions), + mAssetData(asset_data), + mNewName(new_name) { - final_perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null); - - LLPermissions floater_perm; - floater_perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null); - floater_perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Materials")); - floater_perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Materials")); - floater_perm.setMaskNext(LLFloaterPerms::getNextOwnerPerms("Materials")); - - final_perm.accumulate(floater_perm); - final_perm.accumulate(owner_permissions); } - // NOTE: create_inventory_item doesn't allow presetting some permissions. - // The rest will be fixed after the callback. - LLUUID parent = gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_MATERIAL); - const U8 subtype = NO_INV_SUBTYPE; // TODO maybe use AT_SETTINGS and LLSettingsType::ST_MATERIAL ? - create_inventory_item(gAgent.getID(), gAgent.getSessionID(), parent, tid, name, desc, - LLAssetType::AT_MATERIAL, LLInventoryType::IT_MATERIAL, subtype, final_perm.getMaskNextOwner(), - new LLBoostFuncInventoryCallback([output = buffer, final_perm](LLUUID const& inv_item_id) + void fire(const LLUUID& inv_item_id) override { LLViewerInventoryItem* item = gInventory.getItem(inv_item_id); - if (item) + if (!item) { - // create_inventory_item doesn't allow presetting some permissions, fix it now - LLPermissions perm = item->getPermissions(); - perm.accumulate(final_perm); - item->setPermissions(perm); + return; + } - item->updateServer(FALSE); - gInventory.updateItem(item); - gInventory.notifyObservers(); + // create_inventory_item/copy_inventory_item don't allow presetting some permissions, fix it now + item->setPermissions(mPermissions); + item->updateServer(FALSE); + gInventory.updateItem(item); + gInventory.notifyObservers(); + + if (item->getName() != mNewName) + { + LLSD updates; + updates["name"] = mNewName; + update_inventory_item(inv_item_id, updates, NULL); } // from reference in LLSettingsVOBase::createInventoryItem()/updateInventoryItem() @@ -1338,7 +1334,7 @@ void LLMaterialEditor::createInventoryItem(const std::string &buffer, const std: std::make_shared( inv_item_id, LLAssetType::AT_MATERIAL, - output, + mAssetData, [](LLUUID item_id, LLUUID new_asset_id, LLUUID new_item_id, LLSD response) { // done callback @@ -1357,8 +1353,25 @@ void LLMaterialEditor::createInventoryItem(const std::string &buffer, const std: } LLViewerAssetUpload::EnqueueInventoryUpload(agent_url, uploadInfo); } - }) - ); + } +private: + LLPermissions mPermissions; + std::string mAssetData; + std::string mNewName; +}; + +void LLMaterialEditor::createInventoryItem(const std::string &buffer, const std::string &name, const std::string &desc, const LLPermissions& permissions) +{ + // gen a new uuid for this asset + LLTransactionID tid; + tid.generate(); // timestamp-based randomization + uniquification + LLUUID parent = gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_MATERIAL); + const U8 subtype = NO_INV_SUBTYPE; // TODO maybe use AT_SETTINGS and LLSettingsType::ST_MATERIAL ? + + LLPointer cb = new LLObjectsMaterialItemCallback(permissions, buffer, name); + create_inventory_item(gAgent.getID(), gAgent.getSessionID(), parent, tid, name, desc, + LLAssetType::AT_MATERIAL, LLInventoryType::IT_MATERIAL, subtype, permissions.getMaskNextOwner(), + cb); } void LLMaterialEditor::finishInventoryUpload(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId) @@ -1807,10 +1820,8 @@ void LLMaterialEditor::loadLive() } } -// *NOTE: permissions_out ignores user preferences for new item creation. See -// LLFloaterPerms. Preferences are applied later on in -// LLMaterialEditor::createInventoryItem. -bool can_use_objects_material(LLSelectedTEGetMatData& func, const std::vector& ops, LLPermissions& permissions_out) +// *NOTE: permissions_out includes user preferences for new item creation (LLFloaterPerms) +bool can_use_objects_material(LLSelectedTEGetMatData& func, const std::vector& ops, LLPermissions& permissions_out, LLViewerInventoryItem*& item_out) { if (!LLMaterialEditor::capabilitiesAvailable()) { @@ -1834,12 +1845,12 @@ bool can_use_objects_material(LLSelectedTEGetMatData& func, const std::vectorgetInventoryItemByAsset(func.mMaterialId); + item_out = selected_object->getInventoryItemByAsset(func.mMaterialId); LLPermissions item_permissions; - if (item) + if (item_out) { - item_permissions.set(item->getPermissions()); + item_permissions.set(item_out->getPermissions()); for (PermissionBit op : ops) { if (!gAgent.allowOperation(op, item_permissions, GP_OBJECT_MANIPULATE)) @@ -1885,12 +1896,19 @@ bool can_use_objects_material(LLSelectedTEGetMatData& func, const std::vectorgetUUID())); + } + else + { + LLNotificationsUtil::add("SaveMaterialAs", args, payload, boost::bind(&LLMaterialEditor::onSaveObjectsMaterialAsMsgCallback, _1, _2, permissions)); + } } } +// static +void LLMaterialEditor::onCopyObjectsMaterialAsMsgCallback(const LLSD& notification, const LLSD& response, const LLPermissions& permissions, const LLUUID& object_id, const LLUUID& item_id) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (0 == option) + { + LLSD asset; + asset["version"] = LLGLTFMaterial::ASSET_VERSION; + asset["type"] = LLGLTFMaterial::ASSET_TYPE; + // This is the string serialized from LLGLTFMaterial::asJSON + asset["data"] = notification["payload"]["data"]; + + std::ostringstream str; + LLSDSerialize::serialize(asset, str, LLSDSerialize::LLSD_BINARY); + + LLViewerObject* object = gObjectList.findObject(object_id); + if (!object) + { + return; + } + const LLInventoryItem* item = object->getInventoryItem(item_id); + if (!item) + { + return; + } + + std::string new_name = response["message"].asString(); + LLInventoryObject::correctInventoryName(new_name); + if (new_name.empty()) + { + return; + } + + const LLUUID destination_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MATERIAL); + + // TODO: Test + // TODO: Rename the item + LLPointer cb = new LLObjectsMaterialItemCallback(permissions, str.str(), new_name); + // NOTE: This should be an item copy. Saving a material to an inventory should be disabled when the associated material is no-copy. + move_or_copy_inventory_from_object(destination_id, + object_id, + item_id, + cb); + } +} + +// static void LLMaterialEditor::onSaveObjectsMaterialAsMsgCallback(const LLSD& notification, const LLSD& response, const LLPermissions& permissions) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); @@ -2025,6 +2102,11 @@ void LLMaterialEditor::onSaveObjectsMaterialAsMsgCallback(const LLSD& notificati LLSDSerialize::serialize(asset, str, LLSDSerialize::LLSD_BINARY); std::string new_name = response["message"].asString(); + LLInventoryObject::correctInventoryName(new_name); + if (new_name.empty()) + { + return; + } createInventoryItem(str.str(), new_name, std::string(), permissions); } } -- cgit v1.2.3 From 57cc252fd6e3956d53da3c4eb4cad512ddf75e8c Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Mon, 7 Aug 2023 16:31:03 -0700 Subject: SL-20024: Miscellaneous cleanup --- indra/newview/llmaterialeditor.cpp | 110 +++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 53 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index bc3d5b88ab..989f18f1f4 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1940,11 +1940,12 @@ void LLMaterialEditor::saveObjectsMaterialAs() LL_WARNS("MaterialEditor") << "Failed to save GLTF material from object" << LL_ENDL; return; } - saveObjectsMaterialAs(func.mMaterial, func.mLocalMaterial, permissions, func.mObjectId, item); + const LLUUID item_id = item ? item->getUUID() : LLUUID::null; + saveObjectsMaterialAs(func.mMaterial, func.mLocalMaterial, permissions, func.mObjectId, item_id); } -void LLMaterialEditor::saveObjectsMaterialAs(const LLGLTFMaterial* render_material, const LLLocalGLTFMaterial *local_material, const LLPermissions& permissions, const LLUUID& object_id, LLViewerInventoryItem* item) // TODO: item should probably just be an ID at this point +void LLMaterialEditor::saveObjectsMaterialAs(const LLGLTFMaterial* render_material, const LLLocalGLTFMaterial *local_material, const LLPermissions& permissions, const LLUUID& object_id, const LLUUID& item_id) { if (local_material) { @@ -2028,10 +2029,10 @@ void LLMaterialEditor::saveObjectsMaterialAs(const LLGLTFMaterial* render_materi } else { - if (item) + if (item_id.notNull()) { // Copy existing item from object inventory, and create new composite asset on top of it - LLNotificationsUtil::add("SaveMaterialAs", args, payload, boost::bind(&LLMaterialEditor::onCopyObjectsMaterialAsMsgCallback, _1, _2, permissions, object_id, item->getUUID())); + LLNotificationsUtil::add("SaveMaterialAs", args, payload, boost::bind(&LLMaterialEditor::onCopyObjectsMaterialAsMsgCallback, _1, _2, permissions, object_id, item_id)); } else { @@ -2044,71 +2045,74 @@ void LLMaterialEditor::saveObjectsMaterialAs(const LLGLTFMaterial* render_materi void LLMaterialEditor::onCopyObjectsMaterialAsMsgCallback(const LLSD& notification, const LLSD& response, const LLPermissions& permissions, const LLUUID& object_id, const LLUUID& item_id) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (0 == option) + if (0 != option) { - LLSD asset; - asset["version"] = LLGLTFMaterial::ASSET_VERSION; - asset["type"] = LLGLTFMaterial::ASSET_TYPE; - // This is the string serialized from LLGLTFMaterial::asJSON - asset["data"] = notification["payload"]["data"]; - - std::ostringstream str; - LLSDSerialize::serialize(asset, str, LLSDSerialize::LLSD_BINARY); + return; + } - LLViewerObject* object = gObjectList.findObject(object_id); - if (!object) - { - return; - } - const LLInventoryItem* item = object->getInventoryItem(item_id); - if (!item) - { - return; - } + LLSD asset; + asset["version"] = LLGLTFMaterial::ASSET_VERSION; + asset["type"] = LLGLTFMaterial::ASSET_TYPE; + // This is the string serialized from LLGLTFMaterial::asJSON + asset["data"] = notification["payload"]["data"]; - std::string new_name = response["message"].asString(); - LLInventoryObject::correctInventoryName(new_name); - if (new_name.empty()) - { - return; - } + std::ostringstream str; + LLSDSerialize::serialize(asset, str, LLSDSerialize::LLSD_BINARY); - const LLUUID destination_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MATERIAL); + LLViewerObject* object = gObjectList.findObject(object_id); + if (!object) + { + return; + } + const LLInventoryItem* item = object->getInventoryItem(item_id); + if (!item) + { + return; + } - // TODO: Test - // TODO: Rename the item - LLPointer cb = new LLObjectsMaterialItemCallback(permissions, str.str(), new_name); - // NOTE: This should be an item copy. Saving a material to an inventory should be disabled when the associated material is no-copy. - move_or_copy_inventory_from_object(destination_id, - object_id, - item_id, - cb); + std::string new_name = response["message"].asString(); + LLInventoryObject::correctInventoryName(new_name); + if (new_name.empty()) + { + return; } + + const LLUUID destination_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MATERIAL); + + LLPointer cb = new LLObjectsMaterialItemCallback(permissions, str.str(), new_name); + // NOTE: This should be an item copy. Saving a material to an inventory should be disabled when the associated material is no-copy. + move_or_copy_inventory_from_object(destination_id, + object_id, + item_id, + cb); } // static void LLMaterialEditor::onSaveObjectsMaterialAsMsgCallback(const LLSD& notification, const LLSD& response, const LLPermissions& permissions) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (0 == option) + if (0 != option) { - LLSD asset; - asset["version"] = LLGLTFMaterial::ASSET_VERSION; - asset["type"] = LLGLTFMaterial::ASSET_TYPE; - // This is the string serialized from LLGLTFMaterial::asJSON - asset["data"] = notification["payload"]["data"]; + return; + } + + LLSD asset; + asset["version"] = LLGLTFMaterial::ASSET_VERSION; + asset["type"] = LLGLTFMaterial::ASSET_TYPE; + // This is the string serialized from LLGLTFMaterial::asJSON + asset["data"] = notification["payload"]["data"]; - std::ostringstream str; - LLSDSerialize::serialize(asset, str, LLSDSerialize::LLSD_BINARY); + std::ostringstream str; + LLSDSerialize::serialize(asset, str, LLSDSerialize::LLSD_BINARY); - std::string new_name = response["message"].asString(); - LLInventoryObject::correctInventoryName(new_name); - if (new_name.empty()) - { - return; - } - createInventoryItem(str.str(), new_name, std::string(), permissions); + std::string new_name = response["message"].asString(); + LLInventoryObject::correctInventoryName(new_name); + if (new_name.empty()) + { + return; } + + createInventoryItem(str.str(), new_name, std::string(), permissions); } const void upload_bulk(const std::vector& filenames, LLFilePicker::ELoadFilter type); -- cgit v1.2.3 From 076a02e2d8ddb10856602c3f5f3115ace41327b5 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Mon, 7 Aug 2023 17:27:30 -0700 Subject: SL-20024: Strike a better balance with saved material permissions handling, w/r/t author intent and being easier to understand --- indra/newview/llmaterialeditor.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 989f18f1f4..41df58914b 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1295,9 +1295,8 @@ bool LLMaterialEditor::updateInventoryItem(const std::string &buffer, const LLUU return true; } -// Callback intended for when an item is copied from an object's inventory and -// needs to be modified to reflect the new asset/name. For example: When saving -// a modified material to the inventory from the build floater. +// Callback intended for when a material is saved from an object and needs to +// be modified to reflect the new asset/name. class LLObjectsMaterialItemCallback : public LLInventoryCallback { public: @@ -1902,12 +1901,22 @@ bool can_use_objects_material(LLSelectedTEGetMatData& func, const std::vector Date: Fri, 11 Aug 2023 17:18:06 -0700 Subject: SL-20024: Double-check object inventory is not pending when save button pressed --- indra/newview/llmaterialeditor.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 41df58914b..92042ad49f 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1836,6 +1836,10 @@ bool can_use_objects_material(LLSelectedTEGetMatData& func, const std::vectorgetSelection()->getFirstObject()); return false; } + if (selected_object->isInventoryPending()) + { + return false; + } for (PermissionBit op : ops) { if (op == PERM_MODIFY && selected_object->isPermanentEnforced()) -- cgit v1.2.3 From a388c5494e2e5b6669820995a2f4d62a308b870f Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 18 Aug 2023 16:08:03 -0700 Subject: SL-20024: Fix unable to modify a no-copy material from the build floater --- indra/newview/llmaterialeditor.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 92042ad49f..54d85c87ac 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1827,7 +1827,12 @@ bool can_use_objects_material(LLSelectedTEGetMatData& func, const std::vectorgetSelection()->applyToTEs(&func, true /*first applicable*/); + LLViewerObject* selected_object = func.mObject; if (!selected_object) { @@ -1928,7 +1933,7 @@ bool can_use_objects_material(LLSelectedTEGetMatData& func, const std::vector Date: Fri, 1 Sep 2023 17:36:00 -0700 Subject: SL-20167: Grey out the clipboard when copying the material to clipboard is not allowed --- indra/newview/llmaterialeditor.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 54d85c87ac..8f4e0658f6 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1947,6 +1947,14 @@ bool LLMaterialEditor::canSaveObjectsMaterial() return can_use_objects_material(func, std::vector({PERM_COPY, PERM_MODIFY}), permissions, item_out); } +bool LLMaterialEditor::canClipboardObjectsMaterial() +{ + LLSelectedTEGetMatData func(true); + LLPermissions permissions; + LLViewerInventoryItem* item_out; + return can_use_objects_material(func, std::vector({PERM_COPY, PERM_MODIFY, PERM_TRANSFER}), permissions, item_out); +} + void LLMaterialEditor::saveObjectsMaterialAs() { LLSelectedTEGetMatData func(true); -- cgit v1.2.3 From acc7f6a271ce7695fd681ae67dd4071ad5246f10 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 4 Sep 2023 17:08:43 +0300 Subject: SL-18125 Fixed default upload permissions being ignored --- indra/newview/llmaterialeditor.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 54d85c87ac..daf6fdb20d 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1197,10 +1197,16 @@ bool LLMaterialEditor::saveIfNeeded() } else { - //make a new inventory item - std::string res_desc = buildMaterialDescription(); + // Make a new inventory item and set upload permissions LLPermissions local_permissions; local_permissions.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null); + + U32 everyone_perm = LLFloaterPerms::getEveryonePerms("Materials"); + U32 group_perm = LLFloaterPerms::getGroupPerms("Materials"); + U32 next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Materials"); + local_permissions.initMasks(PERM_ALL, PERM_ALL, everyone_perm, group_perm, next_owner_perm); + + std::string res_desc = buildMaterialDescription(); createInventoryItem(buffer, mMaterialName, res_desc, local_permissions); // We do not update floater with uploaded asset yet, so just close it. -- cgit v1.2.3 From c0bcc3740ea4c6662f9707d49ab5c7132bb2a0a8 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 6 Sep 2023 11:47:34 -0700 Subject: SL-20167: Don't block clipboard if GLTF material is null --- indra/newview/llmaterialeditor.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 8f4e0658f6..d4ea725af7 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1949,6 +1949,24 @@ bool LLMaterialEditor::canSaveObjectsMaterial() bool LLMaterialEditor::canClipboardObjectsMaterial() { + if (LLSelectMgr::getInstance()->getSelection()->getObjectCount() != 1) + { + return false; + } + + struct LLSelectedTEGetNullMat : public LLSelectedTEFunctor + { + bool apply(LLViewerObject* objectp, S32 te_index) + { + return objectp->getRenderMaterialID(te_index).isNull(); + } + } null_func; + + if (LLSelectMgr::getInstance()->getSelection()->applyToTEs(&null_func)) + { + return true; + } + LLSelectedTEGetMatData func(true); LLPermissions permissions; LLViewerInventoryItem* item_out; -- cgit v1.2.3 From 1b493d56905a2d3875648196ac1bc39fc71e895a Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 27 Sep 2023 21:11:01 +0300 Subject: SL-20343 Material floater was disconnected from object's face --- indra/newview/llmaterialeditor.cpp | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index a0c3fd9a28..0897ed14c6 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -412,9 +412,6 @@ BOOL LLMaterialEditor::postBuild() if (mIsOverride) { - // Material override change success callback - LLGLTFMaterialList::addSelectionUpdateCallback(&LLMaterialEditor::updateLive); - // Live editing needs a recovery mechanism on cancel mBaseColorTextureCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_BASE_COLOR_TEX_DIRTY)); mMetallicTextureCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY)); @@ -542,12 +539,6 @@ void LLMaterialEditor::draw() { if (mIsOverride) { - bool selection_empty = LLSelectMgr::getInstance()->getSelection()->isEmpty(); - if (selection_empty && mHasSelection) - { - mSelectionNeedsUpdate = true; - } - if (mSelectionNeedsUpdate) { mSelectionNeedsUpdate = false; @@ -1790,22 +1781,6 @@ void LLMaterialEditor::updateLive() mOverrideInProgress = false; } -void LLMaterialEditor::updateLive(const LLUUID &object_id, S32 te) -{ - if (mOverrideObjectId != object_id - || mOverrideObjectTE != te) - { - // Ignore if waiting for override, - // if not waiting, mark selection dirty - mSelectionNeedsUpdate |= !mOverrideInProgress; - return; - } - - // update for currently displayed object and face - mSelectionNeedsUpdate = true; - mOverrideInProgress = false; -} - void LLMaterialEditor::loadLive() { LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("live_material_editor"); @@ -2816,7 +2791,7 @@ public: // something went wrong update selection LLMaterialEditor::updateLive(); } - // else we will get updateLive(obj, id) from applied overrides + // else we will get updateLive() from panel face } bool getResult() { return mSuccess; } -- cgit v1.2.3 From 5566f28b039e2f3999e397a26243707affc80991 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 3 Oct 2023 19:27:26 +0300 Subject: D559 Post merge fixes --- indra/newview/llmaterialeditor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 0897ed14c6..be6f8d72e5 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1530,7 +1530,7 @@ void LLMaterialEditor::onSaveAsMsgCallback(const LLSD& notification, const LLSD& } if (item) { - const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); + const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS); LLUUID parent_id = item->getParentUUID(); if (mObjectUUID.notNull() || marketplacelistings_id == parent_id || gInventory.isObjectDescendentOf(item->getUUID(), gInventory.getLibraryRootFolderID())) { -- cgit v1.2.3 From b877e80d70875ff01ee0f522b775b766838d7404 Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko Date: Fri, 13 Oct 2023 20:08:02 +0300 Subject: SL-20464 Don't allow enetring non-unicode material name --- indra/newview/llmaterialeditor.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index be6f8d72e5..6b70b40860 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1571,7 +1571,11 @@ void LLMaterialEditor::onSaveAsMsgCallback(const LLSD& notification, const LLSD& } else { - LLNotificationsUtil::add("InvalidMaterialName"); + LLNotificationsUtil::add("InvalidMaterialName", LLSD(), LLSD(), [this](const LLSD& notification, const LLSD& response) + { + LLNotificationsUtil::add("SaveMaterialAs", LLSD().with("DESC", mMaterialName), LLSD(), + boost::bind(&LLMaterialEditor::onSaveAsMsgCallback, this, _1, _2)); + }); } } } -- cgit v1.2.3 From 4db38a86cbdc98d50facb89d1b8ad7d050ff76f8 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Tue, 17 Oct 2023 15:31:48 -0700 Subject: Update llmaterialeditor.cpp SL-20392 --- indra/newview/llmaterialeditor.cpp | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 6b70b40860..218e241185 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -3199,7 +3199,11 @@ S32 LLMaterialEditor::saveTextures() { mUploadingTexturesCount++; work_count++; - saveTexture(mBaseColorJ2C, mBaseColorName, mBaseColorTextureUploadId, [key](LLUUID newAssetId, LLSD response) + + // For ease of inventory management, we prepend the material name. + std::string name = mMaterialName + ": " + mBaseColorName; + + saveTexture(mBaseColorJ2C, name, mBaseColorTextureUploadId, [key](LLUUID newAssetId, LLSD response) { LLMaterialEditor* me = LLFloaterReg::findTypedInstance("material_editor", key); if (me) @@ -3237,7 +3241,11 @@ S32 LLMaterialEditor::saveTextures() { mUploadingTexturesCount++; work_count++; - saveTexture(mNormalJ2C, mNormalName, mNormalTextureUploadId, [key](LLUUID newAssetId, LLSD response) + + // For ease of inventory management, we prepend the material name. + std::string name = mMaterialName + ": " + mNormalName; + + saveTexture(mNormalJ2C, name, mNormalTextureUploadId, [key](LLUUID newAssetId, LLSD response) { LLMaterialEditor* me = LLFloaterReg::findTypedInstance("material_editor", key); if (me) @@ -3275,7 +3283,11 @@ S32 LLMaterialEditor::saveTextures() { mUploadingTexturesCount++; work_count++; - saveTexture(mMetallicRoughnessJ2C, mMetallicRoughnessName, mMetallicTextureUploadId, [key](LLUUID newAssetId, LLSD response) + + // For ease of inventory management, we prepend the material name. + std::string name = mMaterialName + ": " + mNormalName; + + saveTexture(mMetallicRoughnessJ2C, name, mMetallicTextureUploadId, [key](LLUUID newAssetId, LLSD response) { LLMaterialEditor* me = LLFloaterReg::findTypedInstance("material_editor", key); if (me) @@ -3314,7 +3326,11 @@ S32 LLMaterialEditor::saveTextures() { mUploadingTexturesCount++; work_count++; - saveTexture(mEmissiveJ2C, mEmissiveName, mEmissiveTextureUploadId, [key](LLUUID newAssetId, LLSD response) + + // For ease of inventory management, we prepend the material name. + std::string name = mMaterialName + ": " + mNormalName; + + saveTexture(mEmissiveJ2C, name, mEmissiveTextureUploadId, [key](LLUUID newAssetId, LLSD response) { LLMaterialEditor* me = LLFloaterReg::findTypedInstance("material_editor", LLSD(key)); if (me) -- cgit v1.2.3 From 89fe8d61336b213ccebc1e4a937df4b83f492243 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Tue, 17 Oct 2023 15:37:36 -0700 Subject: Update llmaterialeditor.cpp SL-20392 --- indra/newview/llmaterialeditor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 218e241185..7a65231a2d 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -3285,7 +3285,7 @@ S32 LLMaterialEditor::saveTextures() work_count++; // For ease of inventory management, we prepend the material name. - std::string name = mMaterialName + ": " + mNormalName; + std::string name = mMaterialName + ": " + mMetallicRoughnessName; saveTexture(mMetallicRoughnessJ2C, name, mMetallicTextureUploadId, [key](LLUUID newAssetId, LLSD response) { @@ -3328,7 +3328,7 @@ S32 LLMaterialEditor::saveTextures() work_count++; // For ease of inventory management, we prepend the material name. - std::string name = mMaterialName + ": " + mNormalName; + std::string name = mMaterialName + ": " + mEmissiveName; saveTexture(mEmissiveJ2C, name, mEmissiveTextureUploadId, [key](LLUUID newAssetId, LLSD response) { -- cgit v1.2.3 From dc63dfc0dd6554f5f45b1d80bd4cb9258eefee95 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 25 Oct 2023 23:38:12 +0300 Subject: SL-20523 Local textures not updating on PBR Materials #1 Update editor in which texture changed to local --- indra/newview/llmaterialeditor.cpp | 75 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 7a65231a2d..63d86cda61 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -532,6 +532,11 @@ void LLMaterialEditor::onClose(bool app_quitting) mSelectionUpdateSlot.disconnect(); } + for (boost::signals2::connection& cn : mTextureChangesUpdates) + { + cn.disconnect(); + } + LLPreview::onClose(app_quitting); } @@ -861,6 +866,47 @@ void LLMaterialEditor::setEnableEditing(bool can_modify) mNormalTextureCtrl->setEnabled(can_modify); } +void LLMaterialEditor::replaceTexture(const LLUUID& old_id, const LLUUID& new_id) +{ + // todo: might be a good idea to set mBaseColorTextureUploadId here + // and when texturectrl picks a local texture + if (getBaseColorId() == old_id) + { + mBaseColorTextureCtrl->setValue(new_id); + } + if (mBaseColorTextureCtrl->getDefaultImageAssetID() == old_id) + { + mBaseColorTextureCtrl->setDefaultImageAssetID(new_id); + } + + if (getMetallicRoughnessId() == old_id) + { + mMetallicTextureCtrl->setValue(new_id); + } + if (mMetallicTextureCtrl->getDefaultImageAssetID() == old_id) + { + mMetallicTextureCtrl->setDefaultImageAssetID(new_id); + } + + if (getEmissiveId() == old_id) + { + mEmissiveTextureCtrl->setValue(new_id); + } + if (mEmissiveTextureCtrl->getDefaultImageAssetID() == old_id) + { + mEmissiveTextureCtrl->setDefaultImageAssetID(new_id); + } + + if (getNormalId() == old_id) + { + mNormalTextureCtrl->setValue(new_id); + } + if (mNormalTextureCtrl->getDefaultImageAssetID() == old_id) + { + mNormalTextureCtrl->setDefaultImageAssetID(new_id); + } +} + void LLMaterialEditor::onCommitTexture(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag) { if (!mIsOverride) @@ -911,6 +957,20 @@ void LLMaterialEditor::onCommitTexture(LLUICtrl* ctrl, const LLSD& data, S32 dir // the texture that is not in use childSetValue(upload_fee_ctrl_name, getString("no_upload_fee_string")); } + + LLTextureCtrl* tex_ctrl = (LLTextureCtrl*)ctrl; + if (tex_ctrl->isImageLocal()) + { + // Theoretically LLSD should be smart enough to not need this, but for extra safety + LLSD key = llsd_clone(getKey()); + // Subscribe material editor to local texture updates + mTextureChangesUpdates.push_back( + LLLocalBitmapMgr::getInstance()->setOnChangedCallback(tex_ctrl->getLocalTrackingID(), + [this](const LLUUID &old_id, const LLUUID& new_id) + { + replaceTexture(old_id, new_id); + })); + } } markChangesUnsaved(dirty_flag); @@ -923,6 +983,17 @@ void LLMaterialEditor::onCancelCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_ applyToSelection(); } +void update_local_texture(LLUICtrl* ctrl, LLGLTFMaterial* mat) +{ + LLTextureCtrl* tex_ctrl = (LLTextureCtrl*)ctrl; + if (tex_ctrl->isImageLocal()) + { + mat->setHasLocalTextures(true); + // Todo: subscrive material for an update + // tex_ctrl->getLocalTrackingID(); + } +} + void LLMaterialEditor::onSelectCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag) { mUnsavedChanges |= dirty_flag; @@ -958,21 +1029,25 @@ void LLMaterialEditor::onSelectCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_ case MATERIAL_BASE_COLOR_TEX_DIRTY: { nodep->mSavedGLTFOverrideMaterials[te]->setBaseColorId(mCtrl->getValue().asUUID(), true); + update_local_texture(mCtrl, nodep->mSavedGLTFOverrideMaterials[te].get()); break; } case MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY: { nodep->mSavedGLTFOverrideMaterials[te]->setOcclusionRoughnessMetallicId(mCtrl->getValue().asUUID(), true); + update_local_texture(mCtrl, nodep->mSavedGLTFOverrideMaterials[te].get()); break; } case MATERIAL_EMISIVE_TEX_DIRTY: { nodep->mSavedGLTFOverrideMaterials[te]->setEmissiveId(mCtrl->getValue().asUUID(), true); + update_local_texture(mCtrl, nodep->mSavedGLTFOverrideMaterials[te].get()); break; } case MATERIAL_NORMAL_TEX_DIRTY: { nodep->mSavedGLTFOverrideMaterials[te]->setNormalId(mCtrl->getValue().asUUID(), true); + update_local_texture(mCtrl, nodep->mSavedGLTFOverrideMaterials[te].get()); break; } // Colors -- cgit v1.2.3 From 596a63051ebabfec51e48be02bbec33ab962d915 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 27 Oct 2023 23:41:13 +0300 Subject: SL-20523 Local textures not updating on PBR Materials #2 --- indra/newview/llmaterialeditor.cpp | 121 +++++++++++++++++++++++++++++++------ 1 file changed, 103 insertions(+), 18 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 63d86cda61..b8e34b7409 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -363,6 +363,15 @@ LLMaterialEditor::LLMaterialEditor(const LLSD& key) } } +LLMaterialEditor::~LLMaterialEditor() +{ + for (mat_connection_map_t::value_type cn : mTextureChangesUpdates) + { + cn.second.mConnection.disconnect(); + } + mTextureChangesUpdates.clear(); +} + void LLMaterialEditor::setObjectID(const LLUUID& object_id) { LLPreview::setObjectID(object_id); @@ -532,11 +541,6 @@ void LLMaterialEditor::onClose(bool app_quitting) mSelectionUpdateSlot.disconnect(); } - for (boost::signals2::connection& cn : mTextureChangesUpdates) - { - cn.disconnect(); - } - LLPreview::onClose(app_quitting); } @@ -866,7 +870,27 @@ void LLMaterialEditor::setEnableEditing(bool can_modify) mNormalTextureCtrl->setEnabled(can_modify); } -void LLMaterialEditor::replaceTexture(const LLUUID& old_id, const LLUUID& new_id) +void LLMaterialEditor::subscribeToLocalTexture(S32 dirty_flag, const LLUUID& tracking_id) +{ + LocalTextureConnection info; + info.mTrackingId = tracking_id; + info.mConnection = LLLocalBitmapMgr::getInstance()->setOnChangedCallback(tracking_id, + [this, dirty_flag](const LLUUID& tracking_id, const LLUUID& old_id, const LLUUID& new_id) + { + if (new_id.isNull()) + { + mTextureChangesUpdates[dirty_flag].mConnection.disconnect(); + mTextureChangesUpdates.erase(dirty_flag); + } + else + { + replaceLocalTexture(old_id, new_id); + } + }); + mTextureChangesUpdates[dirty_flag] = info; +} + +void LLMaterialEditor::replaceLocalTexture(const LLUUID& old_id, const LLUUID& new_id) { // todo: might be a good idea to set mBaseColorTextureUploadId here // and when texturectrl picks a local texture @@ -958,18 +982,17 @@ void LLMaterialEditor::onCommitTexture(LLUICtrl* ctrl, const LLSD& data, S32 dir childSetValue(upload_fee_ctrl_name, getString("no_upload_fee_string")); } + // unsubcribe potential old callabck + mat_connection_map_t::iterator found = mTextureChangesUpdates.find(dirty_flag); + if (found != mTextureChangesUpdates.end()) + { + found->second.mConnection.disconnect(); + } + LLTextureCtrl* tex_ctrl = (LLTextureCtrl*)ctrl; if (tex_ctrl->isImageLocal()) { - // Theoretically LLSD should be smart enough to not need this, but for extra safety - LLSD key = llsd_clone(getKey()); - // Subscribe material editor to local texture updates - mTextureChangesUpdates.push_back( - LLLocalBitmapMgr::getInstance()->setOnChangedCallback(tex_ctrl->getLocalTrackingID(), - [this](const LLUUID &old_id, const LLUUID& new_id) - { - replaceTexture(old_id, new_id); - })); + subscribeToLocalTexture(dirty_flag, tex_ctrl->getLocalTrackingID()); } } @@ -988,9 +1011,8 @@ void update_local_texture(LLUICtrl* ctrl, LLGLTFMaterial* mat) LLTextureCtrl* tex_ctrl = (LLTextureCtrl*)ctrl; if (tex_ctrl->isImageLocal()) { - mat->setHasLocalTextures(true); - // Todo: subscrive material for an update - // tex_ctrl->getLocalTrackingID(); + // subscrive material to updates of local textures + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tex_ctrl->getLocalTrackingID(), mat); } } @@ -1465,6 +1487,20 @@ void LLMaterialEditor::finishInventoryUpload(LLUUID itemId, LLUUID newAssetId, L { me->refreshFromInventory(itemId); } + + if (me && !me->mTextureChangesUpdates.empty()) + { + const LLInventoryItem* item = me->getItem(); + if (item) + { + // local materials were assigned, force load material and init tracking + LLGLTFMaterial* mat = gGLTFMaterialList.getMaterial(item->getAssetUUID()); + for (mat_connection_map_t::value_type val : me->mTextureChangesUpdates) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.second.mTrackingId, mat); + } + } + } } } @@ -1479,6 +1515,16 @@ void LLMaterialEditor::finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID me->setAssetId(newAssetId); me->refreshFromInventory(); me->setEnabled(true); + + if (me && !me->mTextureChangesUpdates.empty()) + { + // local materials were assigned, force load material and init tracking + LLGLTFMaterial* mat = gGLTFMaterialList.getMaterial(newAssetId); + for (mat_connection_map_t::value_type val : me->mTextureChangesUpdates) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.second.mTrackingId, mat); + } + } } } @@ -1512,6 +1558,17 @@ void LLMaterialEditor::finishSaveAs( { me->loadAsset(); me->setEnabled(true); + + // Local texure support + if (!me->mTextureChangesUpdates.empty()) + { + // local materials were assigned, force load material and init tracking + LLGLTFMaterial* mat = gGLTFMaterialList.getMaterial(item->getAssetUUID()); + for (mat_connection_map_t::value_type val : me->mTextureChangesUpdates) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.second.mTrackingId, mat); + } + } } } else if(has_unsaved_changes) @@ -2975,6 +3032,34 @@ void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat) setDoubleSided(mat->mDoubleSided); setAlphaMode(mat->getAlphaMode()); setAlphaCutoff(mat->mAlphaCutoff); + + + for (mat_connection_map_t::value_type cn : mTextureChangesUpdates) + { + cn.second.mConnection.disconnect(); + } + mTextureChangesUpdates.clear(); + + for (const LLUUID& tracking_id : mat->mLocalTextureTrackingIds) + { + LLUUID world_id = LLLocalBitmapMgr::getInstance()->getWorldID(tracking_id); + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]) + { + subscribeToLocalTexture(MATERIAL_BASE_COLOR_TEX_DIRTY, tracking_id); + } + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]) + { + subscribeToLocalTexture(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY, tracking_id); + } + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]) + { + subscribeToLocalTexture(MATERIAL_EMISIVE_TEX_DIRTY, tracking_id); + } + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]) + { + subscribeToLocalTexture(MATERIAL_NORMAL_TEX_DIRTY, tracking_id); + } + } } bool LLMaterialEditor::setFromSelection() -- cgit v1.2.3 From 3a5b678eba5d86acccb1a1f233f862d292258fac Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 30 Oct 2023 23:56:33 +0200 Subject: SL-20523 Local textures not updating on PBR Materials #3 --- indra/newview/llmaterialeditor.cpp | 58 ++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 27 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index b8e34b7409..836ea5c869 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -365,11 +365,6 @@ LLMaterialEditor::LLMaterialEditor(const LLSD& key) LLMaterialEditor::~LLMaterialEditor() { - for (mat_connection_map_t::value_type cn : mTextureChangesUpdates) - { - cn.second.mConnection.disconnect(); - } - mTextureChangesUpdates.clear(); } void LLMaterialEditor::setObjectID(const LLUUID& object_id) @@ -540,6 +535,11 @@ void LLMaterialEditor::onClose(bool app_quitting) { mSelectionUpdateSlot.disconnect(); } + for (mat_connection_map_t::value_type cn : mTextureChangesUpdates) + { + cn.second.mConnection.disconnect(); + } + mTextureChangesUpdates.clear(); LLPreview::onClose(app_quitting); } @@ -872,22 +872,24 @@ void LLMaterialEditor::setEnableEditing(bool can_modify) void LLMaterialEditor::subscribeToLocalTexture(S32 dirty_flag, const LLUUID& tracking_id) { - LocalTextureConnection info; - info.mTrackingId = tracking_id; - info.mConnection = LLLocalBitmapMgr::getInstance()->setOnChangedCallback(tracking_id, - [this, dirty_flag](const LLUUID& tracking_id, const LLUUID& old_id, const LLUUID& new_id) - { - if (new_id.isNull()) - { - mTextureChangesUpdates[dirty_flag].mConnection.disconnect(); - mTextureChangesUpdates.erase(dirty_flag); - } - else - { - replaceLocalTexture(old_id, new_id); - } - }); - mTextureChangesUpdates[dirty_flag] = info; + if (mTextureChangesUpdates[dirty_flag].mTrackingId != tracking_id) + { + mTextureChangesUpdates[dirty_flag].mConnection.disconnect(); + mTextureChangesUpdates[dirty_flag].mTrackingId = tracking_id; + mTextureChangesUpdates[dirty_flag].mConnection = LLLocalBitmapMgr::getInstance()->setOnChangedCallback(tracking_id, + [this, dirty_flag](const LLUUID& tracking_id, const LLUUID& old_id, const LLUUID& new_id) + { + if (new_id.isNull()) + { + mTextureChangesUpdates[dirty_flag].mConnection.disconnect(); + //mTextureChangesUpdates.erase(dirty_flag); + } + else + { + replaceLocalTexture(old_id, new_id); + } + }); + } } void LLMaterialEditor::replaceLocalTexture(const LLUUID& old_id, const LLUUID& new_id) @@ -981,19 +983,21 @@ void LLMaterialEditor::onCommitTexture(LLUICtrl* ctrl, const LLSD& data, S32 dir // the texture that is not in use childSetValue(upload_fee_ctrl_name, getString("no_upload_fee_string")); } + } + LLTextureCtrl* tex_ctrl = (LLTextureCtrl*)ctrl; + if (tex_ctrl->isImageLocal()) + { + subscribeToLocalTexture(dirty_flag, tex_ctrl->getLocalTrackingID()); + } + else + { // unsubcribe potential old callabck mat_connection_map_t::iterator found = mTextureChangesUpdates.find(dirty_flag); if (found != mTextureChangesUpdates.end()) { found->second.mConnection.disconnect(); } - - LLTextureCtrl* tex_ctrl = (LLTextureCtrl*)ctrl; - if (tex_ctrl->isImageLocal()) - { - subscribeToLocalTexture(dirty_flag, tex_ctrl->getLocalTrackingID()); - } } markChangesUnsaved(dirty_flag); -- cgit v1.2.3 From 52c60ab3fdb8617471eccd9df52cc126e0243e76 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 2 Nov 2023 00:33:39 +0200 Subject: SL-20523 Local textures not updating on PBR Materials #4 --- indra/newview/llmaterialeditor.cpp | 115 +++++++++++++++++++++++++++++++++---- 1 file changed, 103 insertions(+), 12 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 836ea5c869..1b606b0311 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -892,6 +892,16 @@ void LLMaterialEditor::subscribeToLocalTexture(S32 dirty_flag, const LLUUID& tra } } +LLUUID LLMaterialEditor::getLocalTextureTrackingIdFromFlag(U32 flag) +{ + mat_connection_map_t::iterator found = mTextureChangesUpdates.find(flag); + if (found != mTextureChangesUpdates.end()) + { + return found->second.mTrackingId; + } + return LLUUID(); +} + void LLMaterialEditor::replaceLocalTexture(const LLUUID& old_id, const LLUUID& new_id) { // todo: might be a good idea to set mBaseColorTextureUploadId here @@ -2827,28 +2837,58 @@ public: if (changed_flags & MATERIAL_BASE_COLOR_TEX_DIRTY) { material->setBaseColorId(mEditor->getBaseColorId(), true); + LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_BASE_COLOR_TEX_DIRTY); + if (tracking_id.notNull()) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material); + } } else if ((reverted_flags & MATERIAL_BASE_COLOR_TEX_DIRTY) && revert_mat.notNull()) { material->setBaseColorId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR], false); + LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_BASE_COLOR_TEX_DIRTY); + if (tracking_id.notNull()) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material); + } } if (changed_flags & MATERIAL_NORMAL_TEX_DIRTY) { material->setNormalId(mEditor->getNormalId(), true); + LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_NORMAL_TEX_DIRTY); + if (tracking_id.notNull()) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material); + } } else if ((reverted_flags & MATERIAL_NORMAL_TEX_DIRTY) && revert_mat.notNull()) { material->setNormalId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL], false); + LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_NORMAL_TEX_DIRTY); + if (tracking_id.notNull()) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material); + } } if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) { material->setOcclusionRoughnessMetallicId(mEditor->getMetallicRoughnessId(), true); + LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY); + if (tracking_id.notNull()) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material); + } } else if ((reverted_flags & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) && revert_mat.notNull()) { material->setOcclusionRoughnessMetallicId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS], false); + LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY); + if (tracking_id.notNull()) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material); + } } if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY) @@ -2881,10 +2921,20 @@ public: if (changed_flags & MATERIAL_EMISIVE_TEX_DIRTY) { material->setEmissiveId(mEditor->getEmissiveId(), true); + LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_EMISIVE_TEX_DIRTY); + if (tracking_id.notNull()) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material); + } } else if ((reverted_flags & MATERIAL_EMISIVE_TEX_DIRTY) && revert_mat.notNull()) { material->setEmissiveId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE], false); + LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_EMISIVE_TEX_DIRTY); + if (tracking_id.notNull()) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material); + } } if (changed_flags & MATERIAL_DOUBLE_SIDED_DIRTY) @@ -3044,24 +3094,65 @@ void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat) } mTextureChangesUpdates.clear(); - for (const LLUUID& tracking_id : mat->mLocalTextureTrackingIds) + if (mat->hasLocalTextures()) { - LLUUID world_id = LLLocalBitmapMgr::getInstance()->getWorldID(tracking_id); - if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]) - { - subscribeToLocalTexture(MATERIAL_BASE_COLOR_TEX_DIRTY, tracking_id); - } - if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]) + for (mat_connection_map_t::value_type cn : mTextureChangesUpdates) { - subscribeToLocalTexture(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY, tracking_id); + cn.second.mConnection.disconnect(); } - if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]) + mTextureChangesUpdates.clear(); + + for (LLGLTFMaterial::local_tex_map_t::value_type val : mat->mTrackingIdToLocalTexture) { - subscribeToLocalTexture(MATERIAL_EMISIVE_TEX_DIRTY, tracking_id); + LLUUID world_id = LLLocalBitmapMgr::getInstance()->getWorldID(val.first); + if (val.second != world_id) + { + LL_WARNS() << "world id mismatch" << LL_ENDL; + } + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]) + { + subscribeToLocalTexture(MATERIAL_BASE_COLOR_TEX_DIRTY, val.first); + } + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]) + { + subscribeToLocalTexture(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY, val.first); + } + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]) + { + subscribeToLocalTexture(MATERIAL_EMISIVE_TEX_DIRTY, val.first); + } + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]) + { + subscribeToLocalTexture(MATERIAL_NORMAL_TEX_DIRTY, val.first); + } } - if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]) + } + else + { + for (mat_connection_map_t::value_type cn : mTextureChangesUpdates) { - subscribeToLocalTexture(MATERIAL_NORMAL_TEX_DIRTY, tracking_id); + LLUUID world_id = LLLocalBitmapMgr::getInstance()->getWorldID(cn.second.mTrackingId); + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); + continue; + } + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); + continue; + } + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); + continue; + } + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); + continue; + } + cn.second.mConnection.disconnect(); } } } -- cgit v1.2.3 From 0d8893822d8975194313e940914afc8945754a21 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 2 Nov 2023 23:49:55 +0200 Subject: SL-20523 Local textures not updating on PBR Materials #5 --- indra/newview/llmaterialeditor.cpp | 130 ++++++++++++++++++++++++------------- 1 file changed, 84 insertions(+), 46 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 1b606b0311..7d1ac32282 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -343,6 +343,39 @@ bool LLSelectedTEGetMatData::apply(LLViewerObject* objectp, S32 te_index) return false; } +class LLSelectedTEUpdateOverrides: public LLSelectedNodeFunctor +{ +public: + LLSelectedTEUpdateOverrides(LLMaterialEditor* me) : mEditor(me) {} + + virtual bool apply(LLSelectNode* nodep); + + LLMaterialEditor* mEditor; +}; + +bool LLSelectedTEUpdateOverrides::apply(LLSelectNode* nodep) +{ + LLViewerObject* objectp = nodep->getObject(); + if (!objectp) + { + return false; + } + S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); // avatars have TEs but no faces + for (S32 te_index = 0; te_index < num_tes; ++te_index) + { + + LLTextureEntry* tep = objectp->getTE(te_index); + LLGLTFMaterial* override_mat = tep->getGLTFMaterialOverride(); + if (mEditor->updateMaterialLocalSubscription(override_mat)) + { + LLGLTFMaterial* render_mat = tep->getGLTFRenderMaterial(); + mEditor->updateMaterialLocalSubscription(render_mat); + } + } + + return true; +} + ///---------------------------------------------------------------------------- /// Class LLMaterialEditor ///---------------------------------------------------------------------------- @@ -535,7 +568,7 @@ void LLMaterialEditor::onClose(bool app_quitting) { mSelectionUpdateSlot.disconnect(); } - for (mat_connection_map_t::value_type cn : mTextureChangesUpdates) + for (mat_connection_map_t::value_type &cn : mTextureChangesUpdates) { cn.second.mConnection.disconnect(); } @@ -902,6 +935,45 @@ LLUUID LLMaterialEditor::getLocalTextureTrackingIdFromFlag(U32 flag) return LLUUID(); } +bool LLMaterialEditor::updateMaterialLocalSubscription(LLGLTFMaterial* mat) +{ + if (!mat) + { + return false; + } + + bool res = false; + for (mat_connection_map_t::value_type& cn : mTextureChangesUpdates) + { + LLUUID world_id = LLLocalBitmapMgr::getInstance()->getWorldID(cn.second.mTrackingId); + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); + res = true; + continue; + } + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); + res = true; + continue; + } + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); + res = true; + continue; + } + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); + res = true; + continue; + } + } + return res; +} + void LLMaterialEditor::replaceLocalTexture(const LLUUID& old_id, const LLUUID& new_id) { // todo: might be a good idea to set mBaseColorTextureUploadId here @@ -1509,7 +1581,7 @@ void LLMaterialEditor::finishInventoryUpload(LLUUID itemId, LLUUID newAssetId, L { // local materials were assigned, force load material and init tracking LLGLTFMaterial* mat = gGLTFMaterialList.getMaterial(item->getAssetUUID()); - for (mat_connection_map_t::value_type val : me->mTextureChangesUpdates) + for (mat_connection_map_t::value_type &val : me->mTextureChangesUpdates) { LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.second.mTrackingId, mat); } @@ -1534,7 +1606,7 @@ void LLMaterialEditor::finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID { // local materials were assigned, force load material and init tracking LLGLTFMaterial* mat = gGLTFMaterialList.getMaterial(newAssetId); - for (mat_connection_map_t::value_type val : me->mTextureChangesUpdates) + for (mat_connection_map_t::value_type &val : me->mTextureChangesUpdates) { LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.second.mTrackingId, mat); } @@ -1578,7 +1650,7 @@ void LLMaterialEditor::finishSaveAs( { // local materials were assigned, force load material and init tracking LLGLTFMaterial* mat = gGLTFMaterialList.getMaterial(item->getAssetUUID()); - for (mat_connection_map_t::value_type val : me->mTextureChangesUpdates) + for (mat_connection_map_t::value_type &val : me->mTextureChangesUpdates) { LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.second.mTrackingId, mat); } @@ -3087,22 +3159,9 @@ void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat) setAlphaMode(mat->getAlphaMode()); setAlphaCutoff(mat->mAlphaCutoff); - - for (mat_connection_map_t::value_type cn : mTextureChangesUpdates) - { - cn.second.mConnection.disconnect(); - } - mTextureChangesUpdates.clear(); - if (mat->hasLocalTextures()) { - for (mat_connection_map_t::value_type cn : mTextureChangesUpdates) - { - cn.second.mConnection.disconnect(); - } - mTextureChangesUpdates.clear(); - - for (LLGLTFMaterial::local_tex_map_t::value_type val : mat->mTrackingIdToLocalTexture) + for (LLGLTFMaterial::local_tex_map_t::value_type &val : mat->mTrackingIdToLocalTexture) { LLUUID world_id = LLLocalBitmapMgr::getInstance()->getWorldID(val.first); if (val.second != world_id) @@ -3127,34 +3186,6 @@ void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat) } } } - else - { - for (mat_connection_map_t::value_type cn : mTextureChangesUpdates) - { - LLUUID world_id = LLLocalBitmapMgr::getInstance()->getWorldID(cn.second.mTrackingId); - if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]) - { - LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); - continue; - } - if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]) - { - LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); - continue; - } - if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]) - { - LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); - continue; - } - if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]) - { - LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); - continue; - } - cn.second.mConnection.disconnect(); - } - } } bool LLMaterialEditor::setFromSelection() @@ -3173,6 +3204,8 @@ bool LLMaterialEditor::setFromSelection() const LLViewerInventoryItem* item = selected_object->getInventoryItemByAsset(func.mMaterialId); const bool allow_modify = !item || canModify(selected_object, item); setEnableEditing(allow_modify); + + // todo: apply local texture data to all materials in selection } else { @@ -3195,6 +3228,11 @@ bool LLMaterialEditor::setFromSelection() // Memorize selection data for filtering further updates mOverrideObjectId = func.mObjectId; mOverrideObjectTE = func.mObjectTE; + + // Ovverdired might have been updated, + // refresh state of local textures in overrides + LLSelectedTEUpdateOverrides local_tex_func(this); + selected_objects->applyToNodes(&local_tex_func); } return func.mMaterial.notNull(); -- cgit v1.2.3 From cc089d88ad5ab9088a5036e1d6f301d87cb3b127 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 3 Nov 2023 21:07:46 +0200 Subject: SL-20523 Ensure override gets updated before render material --- indra/newview/llmaterialeditor.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 7d1ac32282..11a528314e 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -3231,6 +3231,10 @@ bool LLMaterialEditor::setFromSelection() // Ovverdired might have been updated, // refresh state of local textures in overrides + // + // Todo: this probably shouldn't be here, but in localbitmap, + // subscried to all material overrides if we want copied + // objects to get properly updated as well LLSelectedTEUpdateOverrides local_tex_func(this); selected_objects->applyToNodes(&local_tex_func); } -- cgit v1.2.3 From 843866d193a0fb5ea882408c8862335ab9c5539b Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Mon, 13 Nov 2023 13:12:48 -0600 Subject: Drtvwr 596 11/8/2023 (#501) * SL-20570 Fix for lossy (and square) normal maps when importing GLTF materials. * SL-20582 Fix for overriding to alpha mode blend not working. Incidental decruft of dead code (thanks, Rye!) --- indra/newview/llmaterialeditor.cpp | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'indra/newview/llmaterialeditor.cpp') diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 11a528314e..a5437f7a88 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1840,17 +1840,9 @@ static void pack_textures( if (normal_img) { - normal_j2c = LLViewerTextureList::convertToUploadFile(normal_img); - - LLPointer test; - test = LLViewerTextureList::convertToUploadFile(normal_img, 1024, true); - - S32 lossy_bytes = normal_j2c->getDataSize(); - S32 lossless_bytes = test->getDataSize(); - - LL_DEBUGS("MaterialEditor") << llformat("Lossless vs Lossy: (%d/%d) = %.2f", lossless_bytes, lossy_bytes, (F32)lossless_bytes / lossy_bytes) << LL_ENDL; - - normal_j2c = test; + // create a losslessly compressed version of the normal map + normal_j2c = LLViewerTextureList::convertToUploadFile(normal_img, 1024, false, true); + LL_DEBUGS("MaterialEditor") << "Normal: " << normal_j2c->getDataSize() << LL_ENDL; } if (mr_img) -- cgit v1.2.3