diff options
| -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" | 
