diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index a53b68a50fd4de9a81866f6b019eaa3a29363fd3..bdabd657e108e2850b7cbb6932ca7a700e1f16de 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -41,6 +41,8 @@ namespace tinygltf class Model; } +class LLTextureEntry; + class LLGLTFMaterial : public LLRefCount { public: @@ -193,6 +195,11 @@ class LLGLTFMaterial : public LLRefCount // True if setBaseMaterial() was just called bool isClearedForBaseMaterial(); + // For local materials, they have to keep track of where + // they are assigned to for full updates + virtual void addTextureEntry(LLTextureEntry* te) {}; + virtual void removeTextureEntry(LLTextureEntry* te) {}; + private: template<typename T> void setFromTexture(const tinygltf::Model& model, const T& texture_info, TextureInfo texture_info_id); diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp index 49f67918f8c83f60eb7db971670d32a7abc993b7..a665db378b358dc040a30da9d8311d19a8f1ef34 100644 --- a/indra/llprimitive/lltextureentry.cpp +++ b/indra/llprimitive/lltextureentry.cpp @@ -112,7 +112,15 @@ LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs) mMaterialID = rhs.mMaterialID; + if (mGLTFMaterial) + { + mGLTFMaterial->removeTextureEntry(this); + } mGLTFMaterial = rhs.mGLTFMaterial; + if (mGLTFMaterial) + { + mGLTFMaterial->addTextureEntry(this); + } if (rhs.mGLTFMaterialOverrides.notNull()) { @@ -155,6 +163,12 @@ LLTextureEntry::~LLTextureEntry() delete mMediaEntry; mMediaEntry = NULL; } + + if (mGLTFMaterial) + { + mGLTFMaterial->removeTextureEntry(this); + mGLTFMaterial = NULL; + } } bool LLTextureEntry::operator!=(const LLTextureEntry &rhs) const @@ -524,7 +538,20 @@ void LLTextureEntry::setGLTFMaterial(LLGLTFMaterial* material, bool local_origin // NOTE: if you're hitting this assert, try to make sure calling code is using LLViewerObject::setRenderMaterialID llassert(!local_origin || getGLTFMaterialOverride() == nullptr || getGLTFMaterialOverride()->isClearedForBaseMaterial()); + if (mGLTFMaterial) + { + // Local materials have to keep track + // due to update mechanics + mGLTFMaterial->removeTextureEntry(this); + } + mGLTFMaterial = material; + + if (mGLTFMaterial) + { + mGLTFMaterial->addTextureEntry(this); + } + if (mGLTFMaterial == nullptr) { setGLTFRenderMaterial(nullptr); diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp index 80074cc65533307cea417bb8b47896c0cd10d04a..2e71b4fa87b8a730d6088932c334e835a16f4a77 100644 --- a/indra/newview/llfetchedgltfmaterial.cpp +++ b/indra/newview/llfetchedgltfmaterial.cpp @@ -46,6 +46,18 @@ LLFetchedGLTFMaterial::~LLFetchedGLTFMaterial() } +LLFetchedGLTFMaterial& LLFetchedGLTFMaterial::operator=(const LLFetchedGLTFMaterial& rhs) +{ + LLGLTFMaterial::operator =(rhs); + + mBaseColorTexture = rhs.mBaseColorTexture; + mNormalTexture = rhs.mNormalTexture; + mMetallicRoughnessTexture = rhs.mMetallicRoughnessTexture; + mEmissiveTexture = rhs.mEmissiveTexture; + + return *this; +} + void LLFetchedGLTFMaterial::bind(LLViewerTexture* media_tex) { // glTF 2.0 Specification 3.9.4. Alpha Coverage diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h index 0b51770493624367e60a8e2b7ec9cc9947e72129..166865728146f05a5b9ec4c1d8257eeeca4a7591 100644 --- a/indra/newview/llfetchedgltfmaterial.h +++ b/indra/newview/llfetchedgltfmaterial.h @@ -39,6 +39,8 @@ class LLFetchedGLTFMaterial: public LLGLTFMaterial LLFetchedGLTFMaterial(); virtual ~LLFetchedGLTFMaterial(); + LLFetchedGLTFMaterial& operator=(const LLFetchedGLTFMaterial& rhs); + // If this material is loaded, fire the given function void onMaterialComplete(std::function<void()> material_complete); diff --git a/indra/newview/lllocalgltfmaterials.cpp b/indra/newview/lllocalgltfmaterials.cpp index 996b168262b39d83700baa064e8404b061be8307..d464ea05715e3aea58cc54b7d290a3f1115cc852 100644 --- a/indra/newview/lllocalgltfmaterials.cpp +++ b/indra/newview/lllocalgltfmaterials.cpp @@ -45,6 +45,7 @@ #include "llmaterialmgr.h" #include "llnotificationsutil.h" #include "llscrolllistctrl.h" +#include "lltextureentry.h" #include "lltinygltfhelper.h" #include "llviewertexture.h" @@ -118,6 +119,15 @@ S32 LLLocalGLTFMaterial::getIndexInFile() const return mMaterialIndex; } +void LLLocalGLTFMaterial::addTextureEntry(LLTextureEntry* te) +{ + mTextureEntires.insert(te); +} +void LLLocalGLTFMaterial::removeTextureEntry(LLTextureEntry* te) +{ + mTextureEntires.erase(te); +} + /* update functions */ bool LLLocalGLTFMaterial::updateSelf() { @@ -154,6 +164,27 @@ bool LLLocalGLTFMaterial::updateSelf() gGLTFMaterialList.addMaterial(mWorldID, this); mUpdateRetries = LL_LOCAL_UPDATE_RETRIES; + + for (LLTextureEntry* entry : mTextureEntires) + { + // Normally a change in applied material id is supposed to + // drop overrides thus reset material, but local materials + // currently reuse their existing asset id, and purpose is + // to preview how material will work in-world, overrides + // included, so do an override to render update instead. + LLGLTFMaterial* override_mat = entry->getGLTFMaterialOverride(); + if (override_mat) + { + // do not create a new material, reuse existing pointer + LLFetchedGLTFMaterial* render_mat = (LLFetchedGLTFMaterial*)entry->getGLTFRenderMaterial(); + if (render_mat) + { + *render_mat = *this; + render_mat->applyOverride(*override_mat); + } + } + } + updated = true; } diff --git a/indra/newview/lllocalgltfmaterials.h b/indra/newview/lllocalgltfmaterials.h index 6919b9b4b25d25f386ad99b8549c985571d96d7d..1442b83a404d8887420288e2c08cc196495fec47 100644 --- a/indra/newview/lllocalgltfmaterials.h +++ b/indra/newview/lllocalgltfmaterials.h @@ -34,6 +34,7 @@ class LLScrollListCtrl; class LLGLTFMaterial; class LLViewerObject; +class LLTextureEntry; class LLLocalGLTFMaterial : public LLFetchedGLTFMaterial { @@ -48,6 +49,9 @@ class LLLocalGLTFMaterial : public LLFetchedGLTFMaterial LLUUID getWorldID() const; S32 getIndexInFile() const; + void addTextureEntry(LLTextureEntry* te) override; + void removeTextureEntry(LLTextureEntry* te) override; + public: bool updateSelf(); @@ -77,6 +81,7 @@ class LLLocalGLTFMaterial : public LLFetchedGLTFMaterial ELinkStatus mLinkStatus; S32 mUpdateRetries; S32 mMaterialIndex; // Single file can have more than one + std::set<LLTextureEntry*> mTextureEntires; }; class LLLocalGLTFMaterialTimer : public LLEventTimer diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index cb1694821d12dec8a82a36abf7d98f2ba0846b6a..a3a825c199dd63cea01a4e34974526a3c4673351 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -5368,8 +5368,10 @@ S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_ma LLFetchedGLTFMaterial* src_mat = (LLFetchedGLTFMaterial*) tep->getGLTFMaterial(); + // if override mat exists, we must also have a source mat if (!src_mat) - { // we can get into this state if an override has arrived before the viewer has + { + // we can get into this state if an override has arrived before the viewer has // received or handled an update, return TEM_CHANGE_NONE to signal to LLGLTFMaterialList that it // should queue the update for later return retval; @@ -5383,10 +5385,7 @@ S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_ma tep->setGLTFMaterialOverride(override_mat); - // if override mat exists, we must also have a source mat - llassert(override_mat ? bool(src_mat) : true); - - if (override_mat && src_mat) + if (override_mat) { LLFetchedGLTFMaterial* render_mat = new LLFetchedGLTFMaterial(*src_mat); render_mat->applyOverride(*override_mat); 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 1c58ea69778062307e00810e1cbbcc85501535c1..a6a401f43ec106167785b48a862b31d3a736e20a 100644 --- a/indra/newview/skins/default/xui/en/floater_material_editor.xml +++ b/indra/newview/skins/default/xui/en/floater_material_editor.xml @@ -29,7 +29,6 @@ color="DkGray2" opaque="true" tab_stop="true" - border="false" reserve_scroll_corner="false"> <panel name="panel_material"