diff options
| author | Ptolemy <ptolemy@lindenlab.com> | 2022-06-30 12:50:49 -0700 | 
|---|---|---|
| committer | Ptolemy <ptolemy@lindenlab.com> | 2022-06-30 12:50:49 -0700 | 
| commit | 82232de0d2aecfddca2988249e79a73b4d972aa5 (patch) | |
| tree | f6dfb8a8c2d0ca9ee3a3e3dca37386130ffe1653 | |
| parent | 38b6f10717918643c1169a4007dc92cfe36fc4d5 (diff) | |
| parent | 68dfa1f5501f58d1ca158aeabcc3fd07e8a2e70f (diff) | |
Merge branch 'DRTVWR-559' of bitbucket.org:lindenlab/viewer into DRTVWR-559
| -rw-r--r-- | indra/llprimitive/llgltfmaterial.h | 2 | ||||
| -rw-r--r-- | indra/llprimitive/llprimitive.cpp | 109 | ||||
| -rw-r--r-- | indra/llprimitive/llprimitive.h | 24 | ||||
| -rw-r--r-- | indra/newview/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | indra/newview/llgltfmateriallist.cpp | 186 | ||||
| -rw-r--r-- | indra/newview/llgltfmateriallist.h | 48 | ||||
| -rw-r--r-- | indra/newview/llinventorybridge.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llmaterialeditor.cpp | 56 | ||||
| -rw-r--r-- | indra/newview/llmaterialeditor.h | 4 | ||||
| -rw-r--r-- | indra/newview/llpanelgroupnotices.cpp | 1 | ||||
| -rw-r--r-- | indra/newview/llpanelobjectinventory.cpp | 1 | ||||
| -rw-r--r-- | indra/newview/lltooldraganddrop.cpp | 80 | ||||
| -rw-r--r-- | indra/newview/lltooldraganddrop.h | 10 | ||||
| -rw-r--r-- | indra/newview/llviewerobject.cpp | 84 | ||||
| -rw-r--r-- | indra/newview/llviewerobject.h | 8 | ||||
| -rw-r--r-- | indra/newview/llviewertexteditor.cpp | 1 | ||||
| -rw-r--r-- | indra/newview/llvovolume.cpp | 27 | ||||
| -rw-r--r-- | indra/newview/llvovolume.h | 4 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/floater_material_editor.xml | 3 | 
19 files changed, 602 insertions, 50 deletions
diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index d6f59cd1a3..a8d5fb8e85 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -53,6 +53,8 @@ public:      F32 mMetallicFactor = 0.f;      F32 mRoughnessFactor = 0.f; +    F32 mAlphaCutoff = 0.f; +      bool mDoubleSided = false;      AlphaMode mAlphaMode = ALPHA_MODE_OPAQUE; diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 9e0a079fd9..3f0059b759 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -1700,7 +1700,7 @@ BOOL LLNetworkData::isValid(U16 param_type, U32 size)      case PARAMS_EXTENDED_MESH:          return (size == 4);      case PARAMS_RENDER_MATERIAL: -        return (size == 16); +        return (size > 1);  	}  	return FALSE; @@ -2312,18 +2312,32 @@ LLRenderMaterialParams::LLRenderMaterialParams()      mType = PARAMS_RENDER_MATERIAL;  } -BOOL LLRenderMaterialParams::pack(LLDataPacker &dp) const +BOOL LLRenderMaterialParams::pack(LLDataPacker& dp) const  { -    return dp.packUUID(mMaterial, "material"); +    U8 count = (U8)llmin((S32)mEntries.size(), 14); //limited to 255 bytes, no more than 14 material ids -//    return TRUE; +    dp.packU8(count, "count"); +    for (auto& entry : mEntries) +    { +        dp.packU8(entry.te_idx, "te_idx"); +        dp.packUUID(entry.id, "id"); +    } + +    return TRUE;  } -BOOL LLRenderMaterialParams::unpack(LLDataPacker &dp) +BOOL LLRenderMaterialParams::unpack(LLDataPacker& dp)  { -    return dp.unpackUUID(mMaterial, "material"); +    U8 count; +    dp.unpackU8(count, "count"); +    mEntries.resize(count); +    for (auto& entry : mEntries) +    { +        dp.unpackU8(entry.te_idx, "te_idx"); +        dp.unpackUUID(entry.id, "te_id"); +    } -//    return TRUE; +    return TRUE;  }  bool LLRenderMaterialParams::operator==(const LLNetworkData& data) const @@ -2333,40 +2347,99 @@ bool LLRenderMaterialParams::operator==(const LLNetworkData& data) const          return false;      } -    const LLRenderMaterialParams ¶m = static_cast<const LLRenderMaterialParams&>(data); +    const LLRenderMaterialParams& param = static_cast<const LLRenderMaterialParams&>(data); + +    if (param.mEntries.size() != mEntries.size()) +    { +        return false; +    } + +    for (auto& entry : mEntries) +    { +        if (param.getMaterial(entry.te_idx) != entry.id) +        { +            return false; +        } +    } -    return param.mMaterial == mMaterial; +    return true;  }  void LLRenderMaterialParams::copy(const LLNetworkData& data)  {      llassert_always(data.mType == PARAMS_RENDER_MATERIAL); -    const LLRenderMaterialParams ¶m = static_cast<const LLRenderMaterialParams&>(data); -    mMaterial = param.mMaterial; +    const LLRenderMaterialParams& param = static_cast<const LLRenderMaterialParams&>(data); +    mEntries = param.mEntries;  }  LLSD LLRenderMaterialParams::asLLSD() const  { -    return llsd::map("material", mMaterial); +    LLSD ret; + +    for (int i = 0; i < mEntries.size(); ++i) +    { +        ret[i]["te_idx"] = mEntries[i].te_idx; +        ret[i]["id"] = mEntries[i].id; +    } + +    return ret;  }  bool LLRenderMaterialParams::fromLLSD(LLSD& sd)  { -    if (sd.has("material")) +    if (sd.isArray())      { -        setMaterial(sd["material"]); +        mEntries.resize(sd.size()); +        for (int i = 0; i < sd.size(); ++i) +        { +            if (sd[i].has("te_idx") && sd.has("id")) +            { +                mEntries[i].te_idx = sd[i]["te_idx"].asInteger(); +                mEntries[i].id = sd[i]["id"].asUUID(); +            } +            else +            { +                return false; +            } +        } +          return true;      }      return false;  } -void LLRenderMaterialParams::setMaterial(const LLUUID & id) +void LLRenderMaterialParams::setMaterial(U8 te, const LLUUID& id)  { -    mMaterial = id; +    for (int i = 0; i < mEntries.size(); ++i) +    { +        if (mEntries[i].te_idx == te) +        { +            if (id.isNull()) +            { +                mEntries.erase(mEntries.begin() + i); +            } +            else +            { +                mEntries[i].id = id; +            } +            return; +        } +    } + +    mEntries.push_back({ te, id });  } -LLUUID LLRenderMaterialParams::getMaterial() const +const LLUUID& LLRenderMaterialParams::getMaterial(U8 te) const  { -    return mMaterial; +    for (int i = 0; i < mEntries.size(); ++i) +    { +        if (mEntries[i].te_idx == te) +        { +            return mEntries[i].id; +        } +    } + +    return LLUUID::null;  } + diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index 25196fb894..d2adfa4a3d 100644 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -369,22 +369,30 @@ public:  class LLRenderMaterialParams : public LLNetworkData  {  private: -    LLUUID mMaterial; +    struct Entry +    { +        U8 te_idx; +        LLUUID id; +    }; +    std::vector< Entry > mEntries;  public:      LLRenderMaterialParams(); -    BOOL pack(LLDataPacker &dp) const override; -    BOOL unpack(LLDataPacker &dp) override; +    BOOL pack(LLDataPacker& dp) const override; +    BOOL unpack(LLDataPacker& dp) override;      bool operator==(const LLNetworkData& data) const override;      void copy(const LLNetworkData& data) override;      LLSD asLLSD() const;      operator LLSD() const { return asLLSD(); }      bool fromLLSD(LLSD& sd); -    void setMaterial(const LLUUID & id); -    LLUUID getMaterial() const; +    void setMaterial(U8 te_idx, const LLUUID& id); +    const LLUUID& getMaterial(U8 te_idx) const; + +    bool isEmpty() { return mEntries.empty(); }  }; +  // This code is not naming-standards compliant. Leaving it like this for  // now to make the connection to code in  // 	BOOL packTEMessage(LLDataPacker &dp) const; @@ -480,12 +488,12 @@ public:  	virtual S32 setTEMediaFlags(const U8 te, const U8 flags);  	virtual S32 setTEGlow(const U8 te, const F32 glow);  	virtual S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID); -	virtual S32 setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams); +    virtual S32 setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams);  	virtual BOOL setMaterial(const U8 material); // returns TRUE if material changed  	virtual void setTESelected(const U8 te, bool sel);  	LLMaterialPtr getTEMaterialParams(const U8 index); - +      	void copyTEs(const LLPrimitive *primitive);  	S32 packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_face_index, EMsgVariableType type) const;  	BOOL packTEMessage(LLMessageSystem *mesgsys) const; @@ -563,6 +571,8 @@ public:  	static LLPCode legacyToPCode(const U8 legacy);  	static U8 pCodeToLegacy(const LLPCode pcode);  	static bool getTESTAxes(const U8 face, U32* s_axis, U32* t_axis); + +    BOOL hasRenderMaterialParams() const;  	inline static BOOL isPrimitive(const LLPCode pcode);  	inline static BOOL isApp(const LLPCode pcode); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index d4bd1c8b57..b67bc91277 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -344,6 +344,7 @@ set(viewer_SOURCE_FILES      llgesturemgr.cpp      llgiveinventory.cpp      llglsandbox.cpp +    llgltfmateriallist.cpp      llgroupactions.cpp      llgroupiconctrl.cpp      llgrouplist.cpp @@ -986,6 +987,7 @@ set(viewer_HEADER_FILES      llgesturelistener.h      llgesturemgr.h      llgiveinventory.h +    llgltfmateriallist.h      llgroupactions.h      llgroupiconctrl.h      llgrouplist.h diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp new file mode 100644 index 0000000000..7ecbc6eeac --- /dev/null +++ b/indra/newview/llgltfmateriallist.cpp @@ -0,0 +1,186 @@ +/** + * @file   llgltfmateriallist.cpp + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, 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 "llgltfmateriallist.h" + +#include "llassetstorage.h" +#include "llfilesystem.h" +#include "llsdserialize.h" + +#include "tinygltf/tiny_gltf.h" +#include <strstream> + +LLGLTFMaterialList gGLTFMaterialList; + +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; +} + +static void set_from_model(LLGLTFMaterial* mat, tinygltf::Model& model) +{ +     +    S32 index; +     +    auto& material_in = model.materials[0]; + +    // get albedo texture +    index = material_in.pbrMetallicRoughness.baseColorTexture.index; +    if (index >= 0) +    { +        mat->mAlbedoId.set(model.images[index].uri); +    } +    else +    { +        mat->mAlbedoId.setNull(); +    } + +    // get normal map +    index = material_in.normalTexture.index; +    if (index >= 0) +    { +        mat->mNormalId.set(model.images[index].uri); +    } +    else +    { +        mat->mNormalId.setNull(); +    } + +    // get metallic-roughness texture +    index = material_in.pbrMetallicRoughness.metallicRoughnessTexture.index; +    if (index >= 0) +    { +        mat->mMetallicRoughnessId.set(model.images[index].uri); +    } +    else +    { +        mat->mMetallicRoughnessId.setNull(); +    } + +    // get emissive texture +    index = material_in.emissiveTexture.index; +    if (index >= 0) +    { +        mat->mEmissiveId.set(model.images[index].uri); +    } +    else +    { +        mat->mEmissiveId.setNull(); +    } + +    mat->setAlphaMode(material_in.alphaMode); +    mat->mAlphaCutoff = material_in.alphaCutoff; + +    mat->mAlbedoColor = get_color(material_in.pbrMetallicRoughness.baseColorFactor); +    mat->mEmissiveColor = get_color(material_in.emissiveFactor); + +    mat->mMetallicFactor = material_in.pbrMetallicRoughness.metallicFactor; +    mat->mRoughnessFactor = material_in.pbrMetallicRoughness.roughnessFactor; + +    mat->mDoubleSided = material_in.doubleSided; +} + +LLGLTFMaterial* LLGLTFMaterialList::getMaterial(const LLUUID& id) +{ +    List::iterator iter = mList.find(id); +    if (iter == mList.end()) +    { +        LLGLTFMaterial* mat = new LLGLTFMaterial(); +        mList[id] = mat; + +        mat->ref(); + +        gAssetStorage->getAssetData(id, LLAssetType::AT_MATERIAL, +            [=](const LLUUID& id, LLAssetType::EType asset_type, void* user_data, S32 status, LLExtStat ext_status) +            { +                if (status) +                {  +                    LL_WARNS() << "Error getting material asset data: " << LLAssetStorage::getErrorString(status) << " (" << status << ")" << LL_ENDL; +                } + +                LLFileSystem file(id, asset_type, LLFileSystem::READ); + +                std::vector<char> buffer; +                buffer.resize(file.getSize()); +                file.read((U8*)&buffer[0], buffer.size()); + +                LLSD asset; + +                // read file into 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("type") && asset["type"].asString() == "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(), "")) +                                { +                                    set_from_model(mat, model_in); +                                } +                                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; +                } + +                mat->unref(); +            }, nullptr); +         +        return mat; +    } + +    return iter->second; +} + diff --git a/indra/newview/llgltfmateriallist.h b/indra/newview/llgltfmateriallist.h new file mode 100644 index 0000000000..c22134c468 --- /dev/null +++ b/indra/newview/llgltfmateriallist.h @@ -0,0 +1,48 @@ +/** + * @file   llgltfmateriallist.h + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, 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 "llgltfmaterial.h" +#include "llpointer.h" + +#include <unordered_map> + +class LLGLTFMaterialList +{ +public: +    LLGLTFMaterialList() {} + +    typedef std::unordered_map<LLUUID, LLPointer<LLGLTFMaterial > > List; +    List mList; + +    LLGLTFMaterial* getMaterial(const LLUUID& id); + +}; + +extern LLGLTFMaterialList gGLTFMaterialList; + + diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 2bb2c9676b..d325831c8f 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -4403,6 +4403,7 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop,  		case DAD_GESTURE:  		case DAD_MESH:          case DAD_SETTINGS: +        case DAD_MATERIAL:  			accept = dragItemIntoFolder(inv_item, drop, tooltip_msg);  			break;  		case DAD_LINK: @@ -6032,6 +6033,7 @@ BOOL LLCallingCardBridge::dragOrDrop(MASK mask, BOOL drop,  			case DAD_GESTURE:  			case DAD_MESH:              case DAD_SETTINGS: +            case DAD_MATERIAL:  			{  				LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data;  				const LLPermissions& perm = inv_item->getPermissions(); diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 2455ad2926..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" @@ -43,7 +44,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 +52,7 @@  #include "llviewertexturelist.h"  #include "llfloaterperms.h" +#include "tinygltf/tiny_gltf.h"  #include <strstream>  ///---------------------------------------------------------------------------- @@ -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<LLUICtrl>("albedo_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); +    getChild<LLUICtrl>("metallic_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); +    getChild<LLUICtrl>("emissive_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); +    getChild<LLUICtrl>("normal_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); +      boost::function<void(LLUICtrl*, void*)> 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<LLUICtrl>("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<LLImageJ2C>& mr_j2c,      LLPointer<LLImageJ2C>& 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; diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index 6ccb27cf27..b2a6e96eac 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -99,6 +99,7 @@ public:      LLUUID getAlbedoId();      void setAlbedoId(const LLUUID& id); +    void setAlbedoUploadId(const LLUUID& id);      LLColor4 getAlbedoColor(); @@ -118,6 +119,7 @@ public:      LLUUID getMetallicRoughnessId();      void setMetallicRoughnessId(const LLUUID& id); +    void setMetallicRoughnessUploadId(const LLUUID& id);      F32 getMetalnessFactor();      void setMetalnessFactor(F32 factor); @@ -127,12 +129,14 @@ public:      LLUUID getEmissiveId();      void setEmissiveId(const LLUUID& id); +    void setEmissiveUploadId(const LLUUID& id);      LLColor4 getEmissiveColor();      void setEmissiveColor(const LLColor4& color);      LLUUID getNormalId();      void setNormalId(const LLUUID& id); +    void setNormalUploadId(const LLUUID& id);      bool getDoubleSided();      void setDoubleSided(bool double_sided); diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp index ab32ea3956..82f880c9ee 100644 --- a/indra/newview/llpanelgroupnotices.cpp +++ b/indra/newview/llpanelgroupnotices.cpp @@ -156,6 +156,7 @@ BOOL LLGroupDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,  		case DAD_CALLINGCARD:  		case DAD_MESH:          case DAD_SETTINGS: +        case DAD_MATERIAL:  		{  			LLViewerInventoryItem* inv_item = (LLViewerInventoryItem*)cargo_data;  			if(gInventory.getItem(inv_item->getUUID()) diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index defd7025b8..998cffef4a 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -704,6 +704,7 @@ BOOL LLTaskCategoryBridge::dragOrDrop(MASK mask, BOOL drop,  		case DAD_CALLINGCARD:  		case DAD_MESH:          case DAD_SETTINGS: +        case DAD_MATERIAL:  			accept = LLToolDragAndDrop::isInventoryDropAcceptable(object, (LLViewerInventoryItem*)cargo_data);  			if(accept && drop)  			{ diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 50868d0fa5..55e8a3b98b 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -256,7 +256,8 @@ LLToolDragAndDrop::LLDragAndDropDictionary::LLDragAndDropDictionary()  	//      										|-------------------------------|----------------------------------------------|-----------------------------------------------|---------------------------------------------------|--------------------------------|  	addEntry(DAD_NONE, 			new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL,	&LLToolDragAndDrop::dad3dNULL,					&LLToolDragAndDrop::dad3dNULL,					&LLToolDragAndDrop::dad3dNULL,						&LLToolDragAndDrop::dad3dNULL));  	addEntry(DAD_TEXTURE, 		new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL,	&LLToolDragAndDrop::dad3dNULL,					&LLToolDragAndDrop::dad3dGiveInventory,			&LLToolDragAndDrop::dad3dTextureObject,				&LLToolDragAndDrop::dad3dNULL)); -	addEntry(DAD_SOUND, 		new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL,	&LLToolDragAndDrop::dad3dNULL,					&LLToolDragAndDrop::dad3dGiveInventory,			&LLToolDragAndDrop::dad3dUpdateInventory,			&LLToolDragAndDrop::dad3dNULL)); +    addEntry(DAD_MATERIAL,      new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL,                  &LLToolDragAndDrop::dad3dGiveInventory,         &LLToolDragAndDrop::dad3dMaterialObject,            &LLToolDragAndDrop::dad3dNULL)); +    addEntry(DAD_SOUND, 		new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL,	&LLToolDragAndDrop::dad3dNULL,					&LLToolDragAndDrop::dad3dGiveInventory,			&LLToolDragAndDrop::dad3dUpdateInventory,			&LLToolDragAndDrop::dad3dNULL));  	addEntry(DAD_CALLINGCARD, 	new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL,	&LLToolDragAndDrop::dad3dNULL,					&LLToolDragAndDrop::dad3dGiveInventory, 		&LLToolDragAndDrop::dad3dUpdateInventory, 			&LLToolDragAndDrop::dad3dNULL));  	addEntry(DAD_LANDMARK, 		new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, 					&LLToolDragAndDrop::dad3dGiveInventory, 		&LLToolDragAndDrop::dad3dUpdateInventory, 			&LLToolDragAndDrop::dad3dNULL));  	addEntry(DAD_SCRIPT, 		new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, 					&LLToolDragAndDrop::dad3dGiveInventory, 		&LLToolDragAndDrop::dad3dRezScript, 				&LLToolDragAndDrop::dad3dNULL)); @@ -271,6 +272,7 @@ LLToolDragAndDrop::LLDragAndDropDictionary::LLDragAndDropDictionary()  	addEntry(DAD_LINK, 			new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL,	&LLToolDragAndDrop::dad3dNULL,					&LLToolDragAndDrop::dad3dNULL,					&LLToolDragAndDrop::dad3dNULL,						&LLToolDragAndDrop::dad3dNULL));  	addEntry(DAD_MESH, 			new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL,	&LLToolDragAndDrop::dad3dNULL,					&LLToolDragAndDrop::dad3dGiveInventory,			&LLToolDragAndDrop::dad3dMeshObject,				&LLToolDragAndDrop::dad3dNULL));      addEntry(DAD_SETTINGS,      new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL,                  &LLToolDragAndDrop::dad3dGiveInventory,         &LLToolDragAndDrop::dad3dUpdateInventory,           &LLToolDragAndDrop::dad3dNULL)); +          // TODO: animation on self could play it?  edit it?  	// TODO: gesture on self could play it?  edit it?  }; @@ -1062,6 +1064,64 @@ void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj,  	hit_obj->sendTEUpdate();  } + +void LLToolDragAndDrop::dropMaterialOneFace(LLViewerObject* hit_obj, +    S32 hit_face, +    LLInventoryItem* item, +    LLToolDragAndDrop::ESource source, +    const LLUUID& src_id) +{ +    if (hit_face == -1) return; +    if (!item || item->getInventoryType() != LLInventoryType::IT_MATERIAL) +    { +        LL_WARNS() << "LLToolDragAndDrop::dropTextureOneFace no material item." << LL_ENDL; +        return; +    } +    LLUUID asset_id = item->getAssetUUID(); +    BOOL success = handleDropTextureProtections(hit_obj, item, source, src_id); +    if (!success) +    { +        return; +    } + +    hit_obj->setRenderMaterialID(hit_face, asset_id); + +    dialog_refresh_all(); + +    // send the update to the simulator +    hit_obj->sendTEUpdate(); +} + + +void LLToolDragAndDrop::dropMaterialAllFaces(LLViewerObject* hit_obj, +    LLInventoryItem* item, +    LLToolDragAndDrop::ESource source, +    const LLUUID& src_id) +{ +    if (!item || item->getInventoryType() != LLInventoryType::IT_MATERIAL) +    { +        LL_WARNS() << "LLToolDragAndDrop::dropTextureAllFaces no material item." << LL_ENDL; +        return; +    } +    LLUUID asset_id = item->getAssetUUID(); +    BOOL success = handleDropTextureProtections(hit_obj, item, source, src_id); +    if (!success) +    { +        return; +    } +     +    S32 num_faces = hit_obj->getNumTEs(); +    for (S32 face = 0; face < num_faces; face++) +    { +        // update viewer side material in anticipation of update from simulator +        hit_obj->setRenderMaterialID(face, asset_id); +        dialog_refresh_all(); +    } +    // send the update to the simulator +    hit_obj->sendTEUpdate(); +} + +  void LLToolDragAndDrop::dropMesh(LLViewerObject* hit_obj,  								 LLInventoryItem* item,  								 LLToolDragAndDrop::ESource source, @@ -1628,6 +1688,7 @@ bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_  	case DAD_MESH:  	case DAD_CATEGORY:      case DAD_SETTINGS: +    case DAD_MATERIAL:  	{  		LLInventoryObject* inv_obj = (LLInventoryObject*)cargo_data;  		if(gInventory.getCategory(inv_obj->getUUID()) || (gInventory.getItem(inv_obj->getUUID()) @@ -1982,6 +2043,17 @@ EAcceptance LLToolDragAndDrop::dad3dApplyToObject(  				dropTextureOneFace(obj, face, item, mSource, mSourceID);  			}  		} +        else if (cargo_type == DAD_MATERIAL) +        { +            if ((mask & MASK_SHIFT)) +            { +                dropMaterialAllFaces(obj, item, mSource, mSourceID); +            } +            else +            { +                dropMaterialOneFace(obj, face, item, mSource, mSourceID); +            } +        }  		else if (cargo_type == DAD_MESH)  		{  			dropMesh(obj, item, mSource, mSourceID); @@ -2010,6 +2082,12 @@ EAcceptance LLToolDragAndDrop::dad3dTextureObject(  	return dad3dApplyToObject(obj, face, mask, drop, DAD_TEXTURE);  } +EAcceptance LLToolDragAndDrop::dad3dMaterialObject( +    LLViewerObject* obj, S32 face, MASK mask, BOOL drop) +{ +    return dad3dApplyToObject(obj, face, mask, drop, DAD_MATERIAL); +} +  EAcceptance LLToolDragAndDrop::dad3dMeshObject(  	LLViewerObject* obj, S32 face, MASK mask, BOOL drop)  { diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h index 24a712029c..2f6423080e 100644 --- a/indra/newview/lltooldraganddrop.h +++ b/indra/newview/lltooldraganddrop.h @@ -168,6 +168,8 @@ protected:  							   MASK mask, BOOL drop);  	EAcceptance dad3dTextureObject(LLViewerObject* obj, S32 face,  								   MASK mask, BOOL drop); +    EAcceptance dad3dMaterialObject(LLViewerObject* obj, S32 face, +        MASK mask, BOOL drop);  	EAcceptance dad3dMeshObject(LLViewerObject* obj, S32 face,  								   MASK mask, BOOL drop);  //	EAcceptance dad3dTextureSelf(LLViewerObject* obj, S32 face, @@ -249,6 +251,14 @@ public:  									LLInventoryItem* item,  									ESource source,  									const LLUUID& src_id); +    static void dropMaterialOneFace(LLViewerObject* hit_obj, S32 hit_face, +                                    LLInventoryItem* item, +                                    ESource source, +                                    const LLUUID& src_id); +    static void dropMaterialAllFaces(LLViewerObject* hit_obj, +                                    LLInventoryItem* item, +                                    ESource source, +                                    const LLUUID& src_id);  	static void dropMesh(LLViewerObject* hit_obj,  						 LLInventoryItem* item,  						 ESource source, diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 16479e02a2..753fb014c9 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -107,6 +107,7 @@  #include "llcleanup.h"  #include "llcallstack.h"  #include "llmeshrepository.h" +#include "llgltfmateriallist.h"  #include "llgl.h"  //#define DEBUG_UPDATE_TYPE @@ -4906,6 +4907,18 @@ void LLViewerObject::updateTEMaterialTextures(U8 te)      };      LLGLTFMaterial* mat = getTE(te)->getGLTFMaterial(); +    LLUUID mat_id = getRenderMaterialID(te); +    if (mat == nullptr && mat_id.notNull()) +    { +        mat = gGLTFMaterialList.getMaterial(mat_id); +        getTE(te)->setGLTFMaterial(mat); +    } +    else if (mat_id.isNull() && mat != nullptr) +    { +        mat = nullptr; +        getTE(te)->setGLTFMaterial(nullptr); +    } +      if (mat != nullptr)      {          mGLTFAlbedoMaps[te] = fetch_texture(mat->mAlbedoId); @@ -4913,6 +4926,14 @@ void LLViewerObject::updateTEMaterialTextures(U8 te)          mGLTFMetallicRoughnessMaps[te] = fetch_texture(mat->mMetallicRoughnessId);          mGLTFEmissiveMaps[te] = fetch_texture(mat->mEmissiveId);      } +    else +    { +        mGLTFAlbedoMaps[te] = nullptr; +        mGLTFNormalMaps[te] = nullptr; +        mGLTFMetallicRoughnessMaps[te] = nullptr; +        mGLTFEmissiveMaps[te] = nullptr; +    } +  }  void LLViewerObject::refreshBakeTexture() @@ -6991,6 +7012,69 @@ LLVOAvatar* LLViewerObject::getAvatar() const  	return NULL;  } +bool LLViewerObject::hasRenderMaterialParams() const +{ +    return getParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL); +} + +void LLViewerObject::setHasRenderMaterialParams(bool has_materials) +{ +    bool had_materials = hasRenderMaterialParams(); + +    if (had_materials != has_materials) +    { +        if (has_materials) +        { +            setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, TRUE, true); +        } +        else +        { +            setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, FALSE, true); +        } +    } +} + +const LLUUID& LLViewerObject::getRenderMaterialID(U8 te) const +{ +    LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL); +    if (param_block) +    { +        return param_block->getMaterial(te); +    } + +    return LLUUID::null; +} + +void LLViewerObject::setRenderMaterialID(U8 te, const LLUUID& id) +{ +    if (id.notNull()) +    { +        getTE(te)->setGLTFMaterial(gGLTFMaterialList.getMaterial(id)); +        setHasRenderMaterialParams(true); +    } +    else +    { +        getTE(te)->setGLTFMaterial(nullptr); +    } + +    faceMappingChanged(); +    gPipeline.markTextured(mDrawable); + +    LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL); +    if (param_block) +    { +        param_block->setMaterial(te, id); + +        if (param_block->isEmpty()) +        { // might be empty if id is null +            setHasRenderMaterialParams(false); +        } +        else +        { +            parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, true); +        } +    } +}  class ObjectPhysicsProperties : public LLHTTPNode  { diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 5136a7e5ee..109c96dc9c 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -179,6 +179,13 @@ public:  	const std::string& getAttachmentItemName() const;  	virtual LLVOAvatar* getAvatar() const;  //get the avatar this object is attached to, or NULL if object is not an attachment +     +    bool hasRenderMaterialParams() const; +    void setHasRenderMaterialParams(bool has_params); + +    const LLUUID& getRenderMaterialID(U8 te) const; +    void setRenderMaterialID(U8 te, const LLUUID& id); +  	virtual BOOL	isHUDAttachment() const { return FALSE; }  	virtual BOOL	isTempAttachment() const; @@ -200,6 +207,7 @@ public:  	// Graphical stuff for objects - maybe broken out into render class later?  	virtual void updateTextures(); +    virtual void faceMappingChanged() {}  	virtual void boostTexturePriority(BOOL boost_children = TRUE);	// When you just want to boost priority of this object  	virtual LLDrawable* createDrawable(LLPipeline *pipeline); diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index e2de7ac825..7c860936a5 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -879,6 +879,7 @@ BOOL LLViewerTextEditor::handleDragAndDrop(S32 x, S32 y, MASK mask,  			case DAD_ANIMATION:  			case DAD_GESTURE:  			case DAD_MESH: +            case DAD_MATERIAL:  			{  				supported = true;  				break; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 0ae13e67cd..4fa9f05c09 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -2161,6 +2161,7 @@ void LLVOVolume::setNumTEs(const U8 num_tes)  	return ;  } +  //virtual  void LLVOVolume::changeTEImage(S32 index, LLViewerTexture* imagep)  { @@ -3500,6 +3501,11 @@ F32 LLVOVolume::getLightCutoff() const  	}  } +BOOL LLVOVolume::isReflectionProbe() const +{ +    return getParameterEntryInUse(LLNetworkData::PARAMS_REFLECTION_PROBE); +} +  void LLVOVolume::setIsReflectionProbe(BOOL is_probe)  {      BOOL was_probe = isReflectionProbe(); @@ -3570,25 +3576,6 @@ void LLVOVolume::setReflectionProbeIsDynamic(bool is_dynamic)      }  } - -BOOL LLVOVolume::isReflectionProbe() const -{ -    // HACK - make this object a Reflection Probe if a certain UUID is detected -    static LLCachedControl<std::string> reflection_probe_id(gSavedSettings, "RenderReflectionProbeTextureHackID", ""); -    LLUUID probe_id(reflection_probe_id); - -    for (U8 i = 0; i < getNumTEs(); ++i) -    { -        if (getTE(i)->getID() == probe_id) -        { -            return true; -        } -    } -    // END HACK - -    return getParameterEntryInUse(LLNetworkData::PARAMS_REFLECTION_PROBE); -} -  F32 LLVOVolume::getReflectionProbeAmbiance() const  {      const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE); @@ -5874,6 +5861,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  					continue;  				} +                // HACK -- brute force this check every time a drawable gets rebuilt +                vobj->updateTEMaterialTextures(i);  #if 0  #if LL_RELEASE_WITH_DEBUG_INFO                  const LLUUID pbr_id( "49c88210-7238-2a6b-70ac-92d4f35963cf" ); diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index f0a4fd427e..db586fd741 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -172,7 +172,7 @@ public:  				void	markForUpdate(BOOL priority) override;  				void	markForUnload()							{ LLViewerObject::markForUnload(TRUE); mVolumeChanged = TRUE; } -				void    faceMappingChanged()                    { mFaceMappingChanged=TRUE; }; +				void    faceMappingChanged() override           { mFaceMappingChanged=TRUE; }  	/*virtual*/ void	onShift(const LLVector4a &shift_vector) override; // Called when the drawable shifts @@ -284,7 +284,7 @@ public:  	F32 getLightRadius() const;  	F32 getLightFalloff(const F32 fudge_factor = 1.f) const;  	F32 getLightCutoff() const; -	 +      // Reflection Probes      void setIsReflectionProbe(BOOL is_probe);      void setReflectionProbeAmbiance(F32 ambiance); 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 df06896fa5..7d532ecd7b 100644 --- a/indra/newview/skins/default/xui/en/floater_material_editor.xml +++ b/indra/newview/skins/default/xui/en/floater_material_editor.xml @@ -10,7 +10,7 @@   title="[MATERIAL_NAME]"   width="256">    <string name="no_upload_fee_string">no upload fee</string> -  <string name="upload_fee_string">L$10 upload fee</string> +  <string name="upload_fee_string">L$[FEE] upload fee</string>    <check_box            follows="left|top"            label="Double Sided" @@ -473,6 +473,7 @@                 layout="topleft"                 left="10"                 top_pad="5" +               name="total_upload_fee"             >        Total upload fee: L$ [FEE]      </text>  | 
