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.h | 58 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 indra/newview/llmaterialeditor.h (limited to 'indra/newview/llmaterialeditor.h') diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h new file mode 100644 index 0000000000..febdb3bbc1 --- /dev/null +++ b/indra/newview/llmaterialeditor.h @@ -0,0 +1,58 @@ +/** + * @file llmaterialeditor.h + * @brief LLMaterialEditor class header file + * + * $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$ + */ + +#pragma once + +#include "llfloater.h" + +class LLMaterialEditor : public LLFloater +{ +public: + LLMaterialEditor(const LLSD& key); + + void onClickSave(); + + // llpanel + BOOL postBuild() override; + + LLUUID getAlbedoId(); + LLColor4 getAlbedoColor(); + F32 getTransparency(); + std::string getAlphaMode(); + F32 getAlphaCutoff(); + + LLUUID getMetallicRoughnessId(); + F32 getMetalnessFactor(); + F32 getRoughnessFactor(); + + LLUUID getEmissiveId(); + LLColor4 getEmissiveColor(); + + LLUUID getNormalId(); + + bool getDoubleSided(); +}; + -- cgit v1.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/llfilepicker.cpp | 5 + indra/newview/llfilepicker.h | 3 +- indra/newview/llmaterialeditor.cpp | 241 +++++++++++++++++++++ indra/newview/llmaterialeditor.h | 23 ++ indra/newview/llviewermenufile.cpp | 34 ++- indra/newview/skins/default/xui/en/menu_viewer.xml | 10 + 6 files changed, 314 insertions(+), 2 deletions(-) (limited to 'indra/newview/llmaterialeditor.h') diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index 4e2cc34207..2809988ba0 100644 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -60,6 +60,7 @@ LLFilePicker LLFilePicker::sInstance; #define SLOBJECT_FILTER L"Objects (*.slobject)\0*.slobject\0" #define RAW_FILTER L"RAW files (*.raw)\0*.raw\0" #define MODEL_FILTER L"Model files (*.dae; *.gltf; *.glb)\0*.dae;*.gltf;*.glb\0" +#define MATERIAL_FILTER L"GLTF Files (*.gltf; *.glb)\0*.gltf;*.glb\0" #define SCRIPT_FILTER L"Script files (*.lsl)\0*.lsl\0" #define DICTIONARY_FILTER L"Dictionary files (*.dic; *.xcu)\0*.dic;*.xcu\0" #endif @@ -215,6 +216,10 @@ BOOL LLFilePicker::setupFilter(ELoadFilter filter) mOFN.lpstrFilter = MODEL_FILTER \ L"\0"; break; + case FFLOAD_MATERIAL: + mOFN.lpstrFilter = MATERIAL_FILTER \ + L"\0"; + break; case FFLOAD_SCRIPT: mOFN.lpstrFilter = SCRIPT_FILTER \ L"\0"; diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h index a314207da6..cb57c8437d 100644 --- a/indra/newview/llfilepicker.h +++ b/indra/newview/llfilepicker.h @@ -86,7 +86,8 @@ public: FFLOAD_SCRIPT = 11, FFLOAD_DICTIONARY = 12, FFLOAD_DIRECTORY = 13, // To call from lldirpicker. - FFLOAD_EXE = 14 // Note: EXE will be treated as ALL on Windows and Linux but not on Darwin + FFLOAD_EXE = 14, // Note: EXE will be treated as ALL on Windows and Linux but not on Darwin + FFLOAD_MATERIAL = 15 }; enum ESaveFilter 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 diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index febdb3bbc1..f0c5dca44d 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -33,26 +33,49 @@ class LLMaterialEditor : public LLFloater public: LLMaterialEditor(const LLSD& key); + // open a file dialog and select a gltf/glb file for import + void importMaterial(); + void onClickSave(); // llpanel BOOL postBuild() override; LLUUID getAlbedoId(); + void setAlbedoId(const LLUUID& id); + LLColor4 getAlbedoColor(); + + // sets both albedo color and transparency + void setAlbedoColor(const LLColor4& color); + F32 getTransparency(); + std::string getAlphaMode(); + void setAlphaMode(const std::string& alpha_mode); + F32 getAlphaCutoff(); + void setAlphaCutoff(F32 alpha_cutoff); LLUUID getMetallicRoughnessId(); + void setMetallicRoughnessId(const LLUUID& id); + F32 getMetalnessFactor(); + void setMetalnessFactor(F32 factor); + F32 getRoughnessFactor(); + void setRoughnessFactor(F32 factor); LLUUID getEmissiveId(); + void setEmissiveId(const LLUUID& id); + LLColor4 getEmissiveColor(); + void setEmissiveColor(const LLColor4& color); LLUUID getNormalId(); + void setNormalId(const LLUUID& id); bool getDoubleSided(); + void setDoubleSided(bool double_sided); }; diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 32fdfe282d..975e3b97ec 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -37,6 +37,7 @@ #include "llbuycurrencyhtml.h" #include "llfloatermap.h" #include "llfloatermodelpreview.h" +#include "llmaterialeditor.h" #include "llfloatersnapshot.h" #include "llfloateroutfitsnapshot.h" #include "llimage.h" @@ -101,6 +102,20 @@ class LLFileEnableUploadModel : public view_listener_t } }; +class LLFileEnableUploadMaterial : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::findInstance("material_editor"); + if (me && me->isShown()) + { + return false; + } + + return true; + } +}; + class LLMeshEnabled : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -282,6 +297,7 @@ static std::string SLOBJECT_EXTENSIONS = "slobject"; #endif static std::string ALL_FILE_EXTENSIONS = "*.*"; static std::string MODEL_EXTENSIONS = "dae"; +static std::string MATERIAL_EXTENSIONS = "gltf glb"; std::string build_extensions_string(LLFilePicker::ELoadFilter filter) { @@ -298,6 +314,8 @@ std::string build_extensions_string(LLFilePicker::ELoadFilter filter) return SLOBJECT_EXTENSIONS; case LLFilePicker::FFLOAD_MODEL: return MODEL_EXTENSIONS; + case LLFilePicker::FFLOAD_MATERIAL: + return MATERIAL_EXTENSIONS; case LLFilePicker::FFLOAD_XML: return XML_EXTENSIONS; case LLFilePicker::FFLOAD_ALL: @@ -566,7 +584,20 @@ class LLFileUploadModel : public view_listener_t return TRUE; } }; - + +class LLFileUploadMaterial : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor"); + if (me) + { + me->importMaterial(); + } + return TRUE; + } +}; + class LLFileUploadSound : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -1097,6 +1128,7 @@ void init_menu_file() view_listener_t::addCommit(new LLFileUploadSound(), "File.UploadSound"); view_listener_t::addCommit(new LLFileUploadAnim(), "File.UploadAnim"); view_listener_t::addCommit(new LLFileUploadModel(), "File.UploadModel"); + view_listener_t::addCommit(new LLFileUploadMaterial(), "File.UploadMaterial"); view_listener_t::addCommit(new LLFileUploadBulk(), "File.UploadBulk"); view_listener_t::addCommit(new LLFileCloseWindow(), "File.CloseWindow"); view_listener_t::addCommit(new LLFileCloseAllWindows(), "File.CloseAllWindows"); diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 623d0d88eb..4b3c61d7f0 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -1583,6 +1583,16 @@ function="World.EnvPreset" + + + + 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/llprimitive/llmaterialid.cpp | 7 +++++ indra/llprimitive/llmaterialid.h | 1 + indra/llprimitive/lltextureentry.h | 8 ++++++ indra/newview/llmaterialeditor.cpp | 37 ++++++++++++++++++++++++- indra/newview/llmaterialeditor.h | 3 ++ indra/newview/llspatialpartition.h | 13 +++++++-- indra/newview/llviewerobject.cpp | 56 ++++++++++++++++++++++++++++---------- indra/newview/llviewerobject.h | 14 ++++++++++ indra/newview/llvovolume.cpp | 40 +++++++++++++++++++++++---- 9 files changed, 156 insertions(+), 23 deletions(-) (limited to 'indra/newview/llmaterialeditor.h') diff --git a/indra/llprimitive/llmaterialid.cpp b/indra/llprimitive/llmaterialid.cpp index f88a607c4f..340a83801c 100644 --- a/indra/llprimitive/llmaterialid.cpp +++ b/indra/llprimitive/llmaterialid.cpp @@ -155,6 +155,13 @@ std::string LLMaterialID::asString() const return materialIDString; } +LLUUID LLMaterialID::asUUID() const +{ + LLUUID ret; + memcpy(ret.mData, mID, MATERIAL_ID_SIZE); + return ret; +} + std::ostream& operator<<(std::ostream& s, const LLMaterialID &material_id) { s << material_id.asString(); diff --git a/indra/llprimitive/llmaterialid.h b/indra/llprimitive/llmaterialid.h index ee663f8f99..e6165dfc91 100644 --- a/indra/llprimitive/llmaterialid.h +++ b/indra/llprimitive/llmaterialid.h @@ -61,6 +61,7 @@ public: LLSD asLLSD() const; std::string asString() const; + LLUUID asUUID() const; friend std::ostream& operator<<(std::ostream& s, const LLMaterialID &material_id); diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h index dc2e201044..1549b2ce87 100644 --- a/indra/llprimitive/lltextureentry.h +++ b/indra/llprimitive/lltextureentry.h @@ -32,6 +32,7 @@ #include "llsd.h" #include "llmaterialid.h" #include "llmaterial.h" +#include "llgltfmaterial.h" // These bits are used while unpacking TEM messages to tell which aspects of // the texture entry changed. @@ -134,6 +135,10 @@ public: S32 setMaterialID(const LLMaterialID& pMaterialID); S32 setMaterialParams(const LLMaterialPtr pMaterialParams); + void setGLTFMaterial(LLGLTFMaterial* material) { mGLTFMaterial = material; } + LLGLTFMaterial* getGLTFMaterial() { return mGLTFMaterial; } + + virtual const LLUUID &getID() const { return mID; } const LLColor4 &getColor() const { return mColor; } const F32 getAlpha() const { return mColor.mV[VALPHA]; } @@ -162,6 +167,8 @@ public: const LLMaterialID& getMaterialID() const { return mMaterialID; }; const LLMaterialPtr getMaterialParams() const { return mMaterial; }; + LLGLTFMaterial* getGLTFMaterial() const { return mGLTFMaterial; } + // *NOTE: it is possible for hasMedia() to return true, but getMediaData() to return NULL. // CONVERSELY, it is also possible for hasMedia() to return false, but getMediaData() // to NOT return NULL. @@ -219,6 +226,7 @@ protected: bool mMaterialUpdatePending; LLMaterialID mMaterialID; LLMaterialPtr mMaterial; + LLPointer mGLTFMaterial; // if present, ignore mMaterial // Note the media data is not sent via the same message structure as the rest of the TE LLMediaEntry* mMediaEntry; // The media data for the face 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); + } + } +} diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index f0c5dca44d..e773ecd169 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -36,6 +36,9 @@ public: // open a file dialog and select a gltf/glb file for import void importMaterial(); + // for live preview, apply current material to currently selected object + void applyToSelection(); + void onClickSave(); // llpanel diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 07d62be7af..c3e9d8ceb9 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -113,9 +113,14 @@ public: LL_ALIGN_16(LLFace* mFace); //associated face F32 mDistance; U32 mDrawMode; - LLMaterialPtr mMaterial; // If this is null, the following parameters are unused. - LLMaterialID mMaterialID; - U32 mShaderMask; + + // Material points here are likely for debugging only and are immaterial (zing!) + LLMaterialPtr mMaterial; + LLPointer mGLTFMaterial; + + LLUUID mMaterialID; // id of LLGLTFMaterial or LLMaterial applied to this draw info + + U32 mShaderMask; U32 mBlendFuncSrc; U32 mBlendFuncDst; BOOL mHasGlow; @@ -123,6 +128,8 @@ public: const LLMatrix4* mSpecularMapMatrix; LLPointer mNormalMap; const LLMatrix4* mNormalMapMatrix; + LLPointer mEmissiveMap; + LLVector4 mSpecColor; // XYZ = Specular RGB, W = Specular Exponent F32 mEnvIntensity; F32 mAlphaMaskCutoff; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 857a94d7be..16479e02a2 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -406,6 +406,11 @@ void LLViewerObject::deleteTEImages() delete[] mTESpecularMaps; mTESpecularMaps = NULL; } + + mGLTFAlbedoMaps.clear(); + mGLTFNormalMaps.clear(); + mGLTFMetallicRoughnessMaps.clear(); + mGLTFEmissiveMaps.clear(); } void LLViewerObject::markDead() @@ -4731,6 +4736,11 @@ void LLViewerObject::setNumTEs(const U8 num_tes) mTEImages = new_images; mTENormalMaps = new_normmaps; mTESpecularMaps = new_specmaps; + + mGLTFAlbedoMaps.resize(num_tes); + mGLTFNormalMaps.resize(num_tes); + mGLTFMetallicRoughnessMaps.resize(num_tes); + mGLTFEmissiveMaps.resize(num_tes); } else { @@ -4859,23 +4869,28 @@ void LLViewerObject::updateAvatarMeshVisibility(const LLUUID& id, const LLUUID& } } -void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry) + +void LLViewerObject::setTE(const U8 te, const LLTextureEntry& texture_entry) { - LLUUID old_image_id; - if (getTE(te)) - { - old_image_id = getTE(te)->getID(); - } - - LLPrimitive::setTE(te, texture_entry); + LLUUID old_image_id; + if (getTE(te)) + { + old_image_id = getTE(te)->getID(); + } - const LLUUID& image_id = getTE(te)->getID(); - LLViewerTexture* bakedTexture = getBakedTextureForMagicId(image_id); - mTEImages[te] = bakedTexture ? bakedTexture : LLViewerTextureManager::getFetchedTexture(image_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + LLPrimitive::setTE(te, texture_entry); - - updateAvatarMeshVisibility(image_id,old_image_id); + const LLUUID& image_id = getTE(te)->getID(); + LLViewerTexture* bakedTexture = getBakedTextureForMagicId(image_id); + mTEImages[te] = bakedTexture ? bakedTexture : LLViewerTextureManager::getFetchedTexture(image_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + + updateAvatarMeshVisibility(image_id, old_image_id); + updateTEMaterialTextures(te); +} + +void LLViewerObject::updateTEMaterialTextures(U8 te) +{ if (getTE(te)->getMaterialParams().notNull()) { const LLUUID& norm_id = getTE(te)->getMaterialParams()->getNormalID(); @@ -4884,6 +4899,20 @@ void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry) const LLUUID& spec_id = getTE(te)->getMaterialParams()->getSpecularID(); mTESpecularMaps[te] = LLViewerTextureManager::getFetchedTexture(spec_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM, LLViewerTexture::LOD_TEXTURE); } + + auto fetch_texture = [](const LLUUID& id) + { + return LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM, LLViewerTexture::LOD_TEXTURE); + }; + + LLGLTFMaterial* mat = getTE(te)->getGLTFMaterial(); + if (mat != nullptr) + { + mGLTFAlbedoMaps[te] = fetch_texture(mat->mAlbedoId); + mGLTFNormalMaps[te] = fetch_texture(mat->mNormalId); + mGLTFMetallicRoughnessMaps[te] = fetch_texture(mat->mMetallicRoughnessId); + mGLTFEmissiveMaps[te] = fetch_texture(mat->mEmissiveId); + } } void LLViewerObject::refreshBakeTexture() @@ -5424,7 +5453,6 @@ void LLViewerObject::fitFaceTexture(const U8 face) LL_INFOS() << "fitFaceTexture not implemented" << LL_ENDL; } - LLBBox LLViewerObject::getBoundingBoxAgent() const { LLVector3 position_agent; diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 1c4cfc6466..5136a7e5ee 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -321,6 +321,7 @@ public: /*virtual*/ void setNumTEs(const U8 num_tes); /*virtual*/ void setTE(const U8 te, const LLTextureEntry &texture_entry); + void updateTEMaterialTextures(U8 te); /*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid); /*virtual*/ S32 setTENormalMap(const U8 te, const LLUUID &uuid); /*virtual*/ S32 setTESpecularMap(const U8 te, const LLUUID &uuid); @@ -359,6 +360,12 @@ public: LLViewerTexture *getTEImage(const U8 te) const; LLViewerTexture *getTENormalMap(const U8 te) const; LLViewerTexture *getTESpecularMap(const U8 te) const; + + LLViewerTexture* getGLTFAlbedoMap(U8 te) const { return mGLTFAlbedoMaps[te]; } + LLViewerTexture* getGLTFNormalMap(U8 te) const { return mGLTFNormalMaps[te]; } + LLViewerTexture* getGLTFEmissiveMap(U8 te) const { return mGLTFEmissiveMaps[te]; } + LLViewerTexture* getGLTFMetallicRoughnessMap(U8 te) const { return mGLTFMetallicRoughnessMaps[te]; } + bool isImageAlphaBlended(const U8 te) const; @@ -675,6 +682,13 @@ public: LLPointer *mTEImages; LLPointer *mTENormalMaps; LLPointer *mTESpecularMaps; + + std::vector > mGLTFAlbedoMaps; + std::vector > mGLTFNormalMaps; + std::vector > mGLTFMetallicRoughnessMaps; + std::vector > mGLTFEmissiveMaps; + + // true if user can select this object by clicking under any circumstances (even if pick_unselectable is true) // can likely be factored out diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 3a619b4fcc..302a172858 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5390,10 +5390,26 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, LLViewerTexture* tex = facep->getTexture(); + U8 index = facep->getTextureIndex(); - LLMaterial* mat = facep->getTextureEntry()->getMaterialParams().get(); - LLMaterialID mat_id = facep->getTextureEntry()->getMaterialID(); + LLMaterial* mat = nullptr; + + LLUUID mat_id; + + LLGLTFMaterial* gltf_mat = facep->getTextureEntry()->getGLTFMaterial(); + if (gltf_mat != nullptr) + { + mat_id = gltf_mat->getHash(); // TODO: cache this hash + } + else + { + mat = facep->getTextureEntry()->getMaterialParams().get(); + if (mat) + { + mat_id = facep->getTextureEntry()->getMaterialID().asUUID(); + } + } bool batchable = false; @@ -5415,7 +5431,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, if (index < FACE_DO_NOT_BATCH_TEXTURES && idx >= 0) { - if (mat || draw_vec[idx]->mMaterial) + if (mat || gltf_mat || draw_vec[idx]->mMaterial) { //can't batch textures when materials are present (yet) batchable = false; } @@ -5447,7 +5463,6 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange && draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange && #endif - //draw_vec[idx]->mMaterial == mat && draw_vec[idx]->mMaterialID == mat_id && draw_vec[idx]->mFullbright == fullbright && draw_vec[idx]->mBump == bump && @@ -5504,11 +5519,22 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, draw_info->mEnvIntensity = spec; draw_info->mSpecularMap = NULL; draw_info->mMaterial = mat; + draw_info->mGLTFMaterial = gltf_mat; draw_info->mShaderMask = shader_mask; draw_info->mAvatar = facep->mAvatar; draw_info->mSkinInfo = facep->mSkinInfo; - if (mat) + if (gltf_mat) + { + LLViewerObject* vobj = facep->getViewerObject(); + U8 te = facep->getTEOffset(); + + draw_info->mTexture = vobj->getGLTFAlbedoMap(te); + draw_info->mNormalMap = vobj->getGLTFNormalMap(te); + draw_info->mSpecularMap = vobj->getGLTFMetallicRoughnessMap(te); + draw_info->mEmissiveMap = vobj->getGLTFEmissiveMap(te); + } + else if (mat) { draw_info->mMaterialID = mat_id; @@ -5849,6 +5875,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) continue; } +#if 0 #if LL_RELEASE_WITH_DEBUG_INFO const LLUUID pbr_id( "49c88210-7238-2a6b-70ac-92d4f35963cf" ); const LLUUID obj_id( vobj->getID() ); @@ -5856,6 +5883,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) #else bool is_pbr = false; #endif +#else + bool is_pbr = facep->getTextureEntry()->getGLTFMaterial() != nullptr; +#endif //ALWAYS null out vertex buffer on rebuild -- if the face lands in a render // batch, it will recover its vertex buffer reference from the spatial group -- cgit v1.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 ++++++++--- indra/newview/llmaterialeditor.h | 2 ++ indra/newview/lltexturectrl.cpp | 16 +++------ indra/newview/lltexturectrl.h | 2 +- .../default/xui/en/floater_material_editor.xml | 40 ++++++++++++---------- .../newview/skins/default/xui/en/notifications.xml | 8 +++++ 6 files changed, 54 insertions(+), 34 deletions(-) (limited to 'indra/newview/llmaterialeditor.h') 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(); diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index e773ecd169..2af4ccf885 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -59,6 +59,8 @@ public: F32 getAlphaCutoff(); void setAlphaCutoff(F32 alpha_cutoff); + + void setMaterialName(const std::string &name); LLUUID getMetallicRoughnessId(); void setMetallicRoughnessId(const LLUUID& id); diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 1c4a56b549..b761f34790 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -193,10 +193,8 @@ void LLFloaterTexturePicker::setActive( BOOL active ) void LLFloaterTexturePicker::setCanApplyImmediately(BOOL b) { mCanApplyImmediately = b; - if (!mCanApplyImmediately) - { - getChild("apply_immediate_check")->setValue(FALSE); - } + + getChild("apply_immediate_check")->setValue(mCanApplyImmediately); updateFilterPermMask(); } @@ -413,11 +411,7 @@ BOOL LLFloaterTexturePicker::postBuild() getChild("apply_immediate_check")->setValue(gSavedSettings.getBOOL("TextureLivePreview")); childSetCommitCallback("apply_immediate_check", onApplyImmediateCheck, this); - - if (!mCanApplyImmediately) - { - getChildView("show_folders_check")->setEnabled(FALSE); - } + getChildView("apply_immediate_check")->setEnabled(mCanApplyImmediately); getChild("Pipette")->setCommitCallback( boost::bind(&LLFloaterTexturePicker::onBtnPipette, this)); childSetAction("Cancel", LLFloaterTexturePicker::onBtnCancel,this); @@ -483,7 +477,7 @@ void LLFloaterTexturePicker::draw() } getChildView("Default")->setEnabled(mImageAssetID != mDefaultImageAssetID || mTentative); - getChildView("Blank")->setEnabled(mImageAssetID != mBlankImageAssetID || mTentative); + getChildView("Blank")->setEnabled((mImageAssetID != mBlankImageAssetID && mBlankImageAssetID != mDefaultImageAssetID) || mTentative); getChildView("None")->setEnabled(mAllowNoTexture && (!mImageAssetID.isNull() || mTentative)); LLFloater::draw(); @@ -1146,7 +1140,7 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p) mOnCloseCallback(NULL), mOnSelectCallback(NULL), mBorderColor( p.border_color() ), - mAllowNoTexture( FALSE ), + mAllowNoTexture( p.allow_no_texture ), mAllowLocalTexture( TRUE ), mImmediateFilterPermMask( PERM_NONE ), mNonImmediateFilterPermMask( PERM_NONE ), diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index 92f6f89af6..1475c8c6fc 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -91,7 +91,7 @@ public: : image_id("image"), default_image_id("default_image_id"), default_image_name("default_image_name"), - allow_no_texture("allow_no_texture"), + allow_no_texture("allow_no_texture", false), can_apply_immediately("can_apply_immediately"), no_commit_on_selection("no_commit_on_selection", false), label_width("label_width", -1), diff --git a/indra/newview/skins/default/xui/en/floater_material_editor.xml b/indra/newview/skins/default/xui/en/floater_material_editor.xml index 5d72e6f79d..8482795f6f 100644 --- a/indra/newview/skins/default/xui/en/floater_material_editor.xml +++ b/indra/newview/skins/default/xui/en/floater_material_editor.xml @@ -7,8 +7,16 @@ layout="topleft" name="material editor" help_topic="material_editor" - title="Material: [MATERIAL_NAME]" + title="[MATERIAL_NAME]" width="256"> + Albedo: - Metallic-Roughness: - --> -