diff options
author | Dave Parks <davep@lindenlab.com> | 2022-06-15 17:03:38 -0500 |
---|---|---|
committer | Dave Parks <davep@lindenlab.com> | 2022-06-15 17:03:38 -0500 |
commit | f5d66e79eec07384ef6f4fd3f516f7a9d010fb9e (patch) | |
tree | 88a67165f924949c77f0c9ba00408c831f08fb41 /indra/newview | |
parent | ad533fcd6b1a3433273fa6d75e19a7ce56c75867 (diff) |
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
Diffstat (limited to 'indra/newview')
-rw-r--r-- | indra/newview/llfilepicker.cpp | 5 | ||||
-rw-r--r-- | indra/newview/llfilepicker.h | 3 | ||||
-rw-r--r-- | indra/newview/llmaterialeditor.cpp | 241 | ||||
-rw-r--r-- | indra/newview/llmaterialeditor.h | 23 | ||||
-rw-r--r-- | indra/newview/llviewermenufile.cpp | 34 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/menu_viewer.xml | 10 |
6 files changed, 314 insertions, 2 deletions
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<double>& 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<std::string>& 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<std::string>& 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<double>& 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<LLViewerFetchedTexture> 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<LLViewerFetchedTexture> 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<LLViewerFetchedTexture> 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<LLViewerFetchedTexture> 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" <menu_item_call.on_visible function="File.VisibleUploadModel"/> </menu_item_call> + <menu_item_call + label="Material..." + layout="topleft" + name="Upload Material"> + <menu_item_call.on_click + function="File.UploadMaterial" + parameter="" /> + <menu_item_call.on_enable + function="File.EnableUploadMaterial" /> + </menu_item_call> <menu_item_call label="Bulk..." layout="topleft" |