diff options
| author | RunitaiLinden <davep@lindenlab.com> | 2023-11-15 10:32:18 -0600 | 
|---|---|---|
| committer | RunitaiLinden <davep@lindenlab.com> | 2023-11-15 10:32:18 -0600 | 
| commit | 361efcb9267f2c91f88198081bbe6ac2264766fd (patch) | |
| tree | 1b91985a7aa1bd48137fd493d6ce9444a7afb21b | |
| parent | 0edb7cad6bdeaf02cbd89d1f2dd38c47d6078c03 (diff) | |
| parent | 843866d193a0fb5ea882408c8862335ab9c5539b (diff) | |
Merge remote-tracking branch 'remotes/origin/DRTVWR-559' into DRTVWR-596
| -rw-r--r-- | indra/llinventory/llinventory.cpp | 173 | ||||
| -rw-r--r-- | indra/llprimitive/llgltfmaterial.cpp | 52 | ||||
| -rw-r--r-- | indra/llprimitive/llgltfmaterial.h | 13 | ||||
| -rw-r--r-- | indra/newview/llfetchedgltfmaterial.cpp | 77 | ||||
| -rw-r--r-- | indra/newview/llfetchedgltfmaterial.h | 7 | ||||
| -rw-r--r-- | indra/newview/llfloaterchangeitemthumbnail.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llinventorymodel.cpp | 15 | ||||
| -rw-r--r-- | indra/newview/lllocalbitmaps.cpp | 159 | ||||
| -rw-r--r-- | indra/newview/lllocalbitmaps.h | 38 | ||||
| -rw-r--r-- | indra/newview/lllocalgltfmaterials.cpp | 9 | ||||
| -rw-r--r-- | indra/newview/lllocalgltfmaterials.h | 4 | ||||
| -rw-r--r-- | indra/newview/llmaterialeditor.cpp | 297 | ||||
| -rw-r--r-- | indra/newview/llmaterialeditor.h | 13 | ||||
| -rw-r--r-- | indra/newview/llpanelprofile.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/lltexturectrl.cpp | 27 | ||||
| -rw-r--r-- | indra/newview/lltexturectrl.h | 12 | ||||
| -rw-r--r-- | indra/newview/llviewerobject.cpp | 5 | 
17 files changed, 695 insertions, 212 deletions
| diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp index 2de5af94a3..55bcc7c5b2 100644 --- a/indra/llinventory/llinventory.cpp +++ b/indra/llinventory/llinventory.cpp @@ -905,155 +905,7 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)  		mAssetUUID.setNull();  	} -#if 0  // old implementation.  makes a LOT of temporary copies and LLSD::safe(impl) calls -	std::string w; - -	w = INV_ITEM_ID_LABEL; -	if (sd.has(w)) -	{ -		mUUID = sd[w]; -	} -	w = INV_PARENT_ID_LABEL; -	if (sd.has(w)) -	{ -		mParentUUID = sd[w]; -	} -    mThumbnailUUID.setNull(); -    w = INV_THUMBNAIL_LABEL; -    if (sd.has(w)) -    { -        const LLSD &thumbnail_map = sd[w]; -        w = INV_ASSET_ID_LABEL; -        if (thumbnail_map.has(w)) -        { -            mThumbnailUUID = thumbnail_map[w]; -        } -        /* Example: -            <key> asset_id </key> -            <uuid> acc0ec86 - 17f2 - 4b92 - ab41 - 6718b1f755f7 </uuid> -            <key> perms </key> -            <integer> 8 </integer> -            <key>service</key> -            <integer> 3 </integer> -            <key>version</key> -            <integer> 1 </key> -        */ -    } -    else -    { -        w = INV_THUMBNAIL_ID_LABEL; -        if (sd.has(w)) -        { -            mThumbnailUUID = sd[w].asUUID(); -        } -    } -	w = INV_PERMISSIONS_LABEL; -	if (sd.has(w)) -	{ -		mPermissions = ll_permissions_from_sd(sd[w]); -	} -	w = INV_SALE_INFO_LABEL; -	if (sd.has(w)) -	{ -		// Sale info used to contain next owner perm. It is now in -		// the permissions. Thus, we read that out, and fix legacy -		// objects. It's possible this op would fail, but it -		// should pick up the vast majority of the tasks. -		BOOL has_perm_mask = FALSE; -		U32 perm_mask = 0; -		if (!mSaleInfo.fromLLSD(sd[w], has_perm_mask, perm_mask)) -		{ -			goto fail; -		} -		if (has_perm_mask) -		{ -			if(perm_mask == PERM_NONE) -			{ -				perm_mask = mPermissions.getMaskOwner(); -			} -			// fair use fix. -			if(!(perm_mask & PERM_COPY)) -			{ -				perm_mask |= PERM_TRANSFER; -			} -			mPermissions.setMaskNext(perm_mask); -		} -	} -	w = INV_SHADOW_ID_LABEL; -	if (sd.has(w)) -	{ -		mAssetUUID = sd[w]; -		LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES); -		cipher.decrypt(mAssetUUID.mData, UUID_BYTES); -	} -	w = INV_ASSET_ID_LABEL; -	if (sd.has(w)) -	{ -		mAssetUUID = sd[w]; -	} -	w = INV_LINKED_ID_LABEL; -	if (sd.has(w)) -	{ -		mAssetUUID = sd[w]; -	} -	w = INV_ASSET_TYPE_LABEL; -	if (sd.has(w)) -	{ -		if (sd[w].isString()) -		{ -			mType = LLAssetType::lookup(sd[w].asString().c_str()); -		} -		else if (sd[w].isInteger()) -		{ -			S8 type = (U8)sd[w].asInteger(); -			mType = static_cast<LLAssetType::EType>(type); -		} -	} -	w = INV_INVENTORY_TYPE_LABEL; -	if (sd.has(w)) -	{ -		if (sd[w].isString()) -		{ -			mInventoryType = LLInventoryType::lookup(sd[w].asString().c_str()); -		} -		else if (sd[w].isInteger()) -		{ -			S8 type = (U8)sd[w].asInteger(); -			mInventoryType = static_cast<LLInventoryType::EType>(type); -		} -	} -	w = INV_FLAGS_LABEL; -	if (sd.has(w)) -	{ -		if (sd[w].isBinary()) -		{ -			mFlags = ll_U32_from_sd(sd[w]); -		} -		else if(sd[w].isInteger()) -		{ -			mFlags = sd[w].asInteger(); -		} -	} -	w = INV_NAME_LABEL; -	if (sd.has(w)) -	{ -		mName = sd[w].asString(); -		LLStringUtil::replaceNonstandardASCII(mName, ' '); -		LLStringUtil::replaceChar(mName, '|', ' '); -	} -	w = INV_DESC_LABEL; -	if (sd.has(w)) -	{ -		mDescription = sd[w].asString(); -		LLStringUtil::replaceNonstandardASCII(mDescription, ' '); -	} -	w = INV_CREATION_DATE_LABEL; -	if (sd.has(w)) -	{ -		mCreationDate = sd[w].asInteger(); -	} -#else  // if 0 - new implementation follows - +    // TODO - figure out if this should be moved into the noclobber fields above      mThumbnailUUID.setNull();      // iterate as map to avoid making unnecessary temp copies of everything @@ -1064,11 +916,13 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)          if (i->first == INV_ITEM_ID_LABEL)          {              mUUID = i->second; +            continue;          }          if (i->first == INV_PARENT_ID_LABEL)          {              mParentUUID = i->second; +            continue;          }          if (i->first == INV_THUMBNAIL_LABEL) @@ -1089,16 +943,19 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)                  <key>version</key>                  <integer> 1 </key>              */ -        } +          continue; +      }          if (i->first == INV_THUMBNAIL_ID_LABEL)          {              mThumbnailUUID = i->second.asUUID(); +            continue;          }          if (i->first == INV_PERMISSIONS_LABEL)          {              mPermissions = ll_permissions_from_sd(i->second); +            continue;          }          if (i->first == INV_SALE_INFO_LABEL) @@ -1111,7 +968,7 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)              U32  perm_mask     = 0;              if (!mSaleInfo.fromLLSD(i->second, has_perm_mask, perm_mask))              { -                goto fail; +                return false;              }              if (has_perm_mask)              { @@ -1126,6 +983,7 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)                  }                  mPermissions.setMaskNext(perm_mask);              } +            continue;          }          if (i->first == INV_SHADOW_ID_LABEL) @@ -1133,16 +991,19 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)              mAssetUUID = i->second;              LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES);              cipher.decrypt(mAssetUUID.mData, UUID_BYTES); +            continue;          }          if (i->first == INV_ASSET_ID_LABEL)          {              mAssetUUID = i->second; +            continue;          }          if (i->first == INV_LINKED_ID_LABEL)          {              mAssetUUID = i->second; +            continue;          }          if (i->first == INV_ASSET_TYPE_LABEL) @@ -1157,6 +1018,7 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)                  S8 type = (U8) label.asInteger();                  mType   = static_cast<LLAssetType::EType>(type);              } +            continue;          }          if (i->first == INV_INVENTORY_TYPE_LABEL) @@ -1171,6 +1033,7 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)                  S8 type        = (U8) label.asInteger();                  mInventoryType = static_cast<LLInventoryType::EType>(type);              } +            continue;          }          if (i->first == INV_FLAGS_LABEL) @@ -1184,6 +1047,7 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)              {                  mFlags = label.asInteger();              } +            continue;          }          if (i->first == INV_NAME_LABEL) @@ -1191,20 +1055,22 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)              mName = i->second.asString();              LLStringUtil::replaceNonstandardASCII(mName, ' ');              LLStringUtil::replaceChar(mName, '|', ' '); +            continue;          }          if (i->first == INV_DESC_LABEL)          {              mDescription = i->second.asString();              LLStringUtil::replaceNonstandardASCII(mDescription, ' '); +            continue;          }          if (i->first == INV_CREATION_DATE_LABEL)          {              mCreationDate = i->second.asInteger(); +            continue;          }      } -#endif // new version  	// Need to convert 1.0 simstate files to a useful inventory type  	// and potentially deal with bad inventory tyes eg, a landmark @@ -1219,9 +1085,6 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)  	mPermissions.initMasks(mInventoryType);  	return true; -fail: -	return false; -  }  ///---------------------------------------------------------------------------- diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index 9945c230a2..237636bd0b 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -89,6 +89,10 @@ LLGLTFMaterial& LLGLTFMaterial::operator=(const LLGLTFMaterial& rhs)      mOverrideDoubleSided = rhs.mOverrideDoubleSided;      mOverrideAlphaMode = rhs.mOverrideAlphaMode; +    mTrackingIdToLocalTexture = rhs.mTrackingIdToLocalTexture; + +    updateTextureTracking(); +      return *this;  } @@ -601,6 +605,10 @@ void LLGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat)              mTextureTransform[i].mRotation = override_mat.mTextureTransform[i].mRotation;          }      } + +    mTrackingIdToLocalTexture.insert(override_mat.mTrackingIdToLocalTexture.begin(), override_mat.mTrackingIdToLocalTexture.begin()); + +    updateTextureTracking();  }  void LLGLTFMaterial::getOverrideLLSD(const LLGLTFMaterial& override_mat, LLSD& data) @@ -791,3 +799,47 @@ LLUUID LLGLTFMaterial::getHash() const      return hash;  } +void LLGLTFMaterial::addLocalTextureTracking(const LLUUID& tracking_id, const LLUUID& tex_id) +{ +    mTrackingIdToLocalTexture[tracking_id] = tex_id; +} + +void LLGLTFMaterial::removeLocalTextureTracking(const LLUUID& tracking_id) +{ +    mTrackingIdToLocalTexture.erase(tracking_id); +} + +bool LLGLTFMaterial::replaceLocalTexture(const LLUUID& tracking_id, const LLUUID& old_id, const LLUUID& new_id) +{ +    bool res = false; + +    for (int i = 0; i < GLTF_TEXTURE_INFO_COUNT; ++i) +    { +        if (mTextureId[i] == old_id) +        { +            mTextureId[i] = new_id; +            res = true; +        } +        else if (mTextureId[i] == new_id) +        { +            res = true; +        } +    } + +    if (res) +    { +        mTrackingIdToLocalTexture[tracking_id] = new_id; +    } +    else +    { +        mTrackingIdToLocalTexture.erase(tracking_id); +    } + +    return res; +} + +void LLGLTFMaterial::updateTextureTracking() +{ +    // setTEGLTFMaterialOverride is responsible for tracking +    // for material overrides editor will set it +} diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index 822a0aab22..02f62fb08c 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -196,7 +196,7 @@ public:      // write to given tinygltf::Model      void writeToModel(tinygltf::Model& model, S32 mat_index) const; -    void applyOverride(const LLGLTFMaterial& override_mat); +    virtual void applyOverride(const LLGLTFMaterial& override_mat);      // apply the given LLSD override data      void applyOverrideLLSD(const LLSD& data); @@ -222,6 +222,17 @@ public:      virtual void addTextureEntry(LLTextureEntry* te) {};      virtual void removeTextureEntry(LLTextureEntry* te) {}; +    // For local textures so that editor will know to track changes +    void addLocalTextureTracking(const LLUUID& tracking_id, const LLUUID &tex_id); +    void removeLocalTextureTracking(const LLUUID& tracking_id); +    bool hasLocalTextures() { return !mTrackingIdToLocalTexture.empty(); } +    virtual bool replaceLocalTexture(const LLUUID& tracking_id, const LLUUID &old_id, const LLUUID& new_id); +    virtual void updateTextureTracking(); + +    // These fields are local to viewer and are a part of local bitmap support +    typedef std::map<LLUUID, LLUUID> local_tex_map_t; +    local_tex_map_t mTrackingIdToLocalTexture; +  protected:      static LLVector2 vec2FromJson(const std::map<std::string, tinygltf::Value>& object, const char* key, const LLVector2& default_value);      static F32 floatFromJson(const std::map<std::string, tinygltf::Value>& object, const char* key, const F32 default_value); diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp index b6d62d1d12..46b9dffae9 100644 --- a/indra/newview/llfetchedgltfmaterial.cpp +++ b/indra/newview/llfetchedgltfmaterial.cpp @@ -146,6 +146,83 @@ void LLFetchedGLTFMaterial::bind(LLViewerTexture* media_tex)  } +LLViewerFetchedTexture* fetch_texture(const LLUUID& id) +{ +    LLViewerFetchedTexture* img = nullptr; +    if (id.notNull()) +    { +        img = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); +        img->addTextureStats(64.f * 64.f, TRUE); +    } +    return img; +}; + +bool LLFetchedGLTFMaterial::replaceLocalTexture(const LLUUID& tracking_id, const LLUUID& old_id, const LLUUID& new_id) +{ +    bool res = false; +    if (mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] == old_id) +    { +        mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] = new_id; +        mBaseColorTexture = fetch_texture(new_id); +        res = true; +    } +    if (mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] == old_id) +    { +        mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] = new_id; +        mNormalTexture = fetch_texture(new_id); +        res = true; +    } +    if (mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] == old_id) +    { +        mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] = new_id; +        mMetallicRoughnessTexture = fetch_texture(new_id); +        res = true; +    } +    if (mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] == old_id) +    { +        mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] = new_id; +        mEmissiveTexture = fetch_texture(new_id); +        res = true; +    } + +    for (int i = 0; i < GLTF_TEXTURE_INFO_COUNT; ++i) +    { +        if (mTextureId[i] == new_id) +        { +            res = true; +        } +    } + +    if (res) +    { +        mTrackingIdToLocalTexture[tracking_id] = new_id; +    } +    else +    { +        mTrackingIdToLocalTexture.erase(tracking_id); +    } + +    return res; +} + +void LLFetchedGLTFMaterial::addTextureEntry(LLTextureEntry* te) +{ +    mTextureEntires.insert(te); +} + +void LLFetchedGLTFMaterial::removeTextureEntry(LLTextureEntry* te) +{ +    mTextureEntires.erase(te); +} + +void LLFetchedGLTFMaterial::updateTextureTracking() +{ +    for (local_tex_map_t::value_type &val : mTrackingIdToLocalTexture) +    { +        LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.first, this); +    } +} +  void LLFetchedGLTFMaterial::materialBegin()  {      llassert(!mFetching); diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h index eb9639723a..a9e539633d 100644 --- a/indra/newview/llfetchedgltfmaterial.h +++ b/indra/newview/llfetchedgltfmaterial.h @@ -52,12 +52,19 @@ public:      LLPointer<LLViewerFetchedTexture> getUITexture(); +    void addTextureEntry(LLTextureEntry* te) override; +    void removeTextureEntry(LLTextureEntry* te) override; +    virtual bool replaceLocalTexture(const LLUUID& tracking_id, const LLUUID& old_id, const LLUUID& new_id) override; +    virtual void updateTextureTracking() override; +      // Textures used for fetching/rendering      LLPointer<LLViewerFetchedTexture> mBaseColorTexture;      LLPointer<LLViewerFetchedTexture> mNormalTexture;      LLPointer<LLViewerFetchedTexture> mMetallicRoughnessTexture;      LLPointer<LLViewerFetchedTexture> mEmissiveTexture; +    std::set<LLTextureEntry*> mTextureEntires; +      // Texture used for previewing the material in the UI      LLPointer<LLViewerFetchedTexture> mPreviewTexture; diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index f54240f6f4..0301627c15 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -760,7 +760,7 @@ void LLFloaterChangeItemThumbnail::showTexturePicker(const LLUUID &thumbnail_id)          {              //texture_floaterp->setTextureSelectedCallback();              //texture_floaterp->setOnUpdateImageStatsCallback(); -            texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLPickerSource, const LLUUID&, const LLUUID&) +            texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLPickerSource, const LLUUID&, const LLUUID&, const LLUUID&)              {                  if (op == LLTextureCtrl::TEXTURE_SELECT)                  { diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index ca13b9eb03..05aa2e423f 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -3346,7 +3346,7 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,  	is_cache_obsolete = true; // Obsolete until proven current -	U64 lines_count = 0U; +	//U64 lines_count = 0U;  	std::string line;  	LLPointer<LLSDParser> parser = new LLSDNotationParser();  	while (std::getline(file, line))  @@ -3412,12 +3412,13 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,  			}	  		} -		static constexpr U64 BATCH_SIZE = 512U; -		if ((++lines_count % BATCH_SIZE) == 0) -		{ -			// SL-19968 - make sure message system code gets a chance to run every so often -			pump_idle_startup_network(); -		} +//      TODO(brad) - figure out how to reenable this without breaking everything else +//		static constexpr U64 BATCH_SIZE = 512U; +//		if ((++lines_count % BATCH_SIZE) == 0) +//		{ +//			// SL-19968 - make sure message system code gets a chance to run every so often +//			pump_idle_startup_network(); +//		}  	}  	file.close(); diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index 257208470e..5a5fb7474c 100644 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -46,6 +46,7 @@  #include <ctime>  /* misc headers */ +#include "llgltfmaterial.h"  #include "llscrolllistctrl.h"  #include "lllocaltextureobject.h"  #include "llviewertexturelist.h" @@ -131,6 +132,14 @@ LLLocalBitmap::~LLLocalBitmap()  		LLLocalBitmapMgr::getInstance()->doRebake();  	} +    for (LLPointer<LLGLTFMaterial> &mat : mGLTFMaterialWithLocalTextures) +    { +        mat->removeLocalTextureTracking(getTrackingID()); +    } + +    mChangedSignal(getTrackingID(), getWorldID(), LLUUID()); +    mChangedSignal.disconnect_all_slots(); +  	// delete self from gimagelist  	LLViewerFetchedTexture* image = gTextureList.findImage(mWorldID, TEX_LIST_STANDARD);  	gTextureList.deleteImage(image); @@ -142,27 +151,27 @@ LLLocalBitmap::~LLLocalBitmap()  }  /* accessors */ -std::string LLLocalBitmap::getFilename() +std::string LLLocalBitmap::getFilename() const  {  	return mFilename;  } -std::string LLLocalBitmap::getShortName() +std::string LLLocalBitmap::getShortName() const  {  	return mShortName;  } -LLUUID LLLocalBitmap::getTrackingID() +LLUUID LLLocalBitmap::getTrackingID() const  {  	return mTrackingID;  } -LLUUID LLLocalBitmap::getWorldID() +LLUUID LLLocalBitmap::getWorldID() const  {  	return mWorldID;  } -bool LLLocalBitmap::getValid() +bool LLLocalBitmap::getValid() const  {  	return mValid;  } @@ -273,6 +282,41 @@ bool LLLocalBitmap::updateSelf(EUpdateType optional_firstupdate)  	return updated;  } +boost::signals2::connection LLLocalBitmap::setChangedCallback(const LLLocalTextureCallback& cb) +{ +    return mChangedSignal.connect(cb); +} + +void LLLocalBitmap::addGLTFMaterial(LLGLTFMaterial* mat) +{ +    if (!mat) +    { +        return; +    } + +    mat_list_t::iterator end = mGLTFMaterialWithLocalTextures.end(); +    for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != end;) +    { +        if (it->get() == mat) +        { +            return; +        } + +        if ((*it)->getNumRefs() == 1) +        { +            it = mGLTFMaterialWithLocalTextures.erase(it); +            end = mGLTFMaterialWithLocalTextures.end(); +        } +        else +        { +            it++; +        } +    } + +    mat->addLocalTextureTracking(getTrackingID(), getWorldID()); +    mGLTFMaterialWithLocalTextures.push_back(mat); +} +  bool LLLocalBitmap::decodeBitmap(LLPointer<LLImageRaw> rawimg)  {  	bool decode_successful = false; @@ -340,7 +384,7 @@ bool LLLocalBitmap::decodeBitmap(LLPointer<LLImageRaw> rawimg)  	return decode_successful;  } -void LLLocalBitmap::replaceIDs(LLUUID old_id, LLUUID new_id) +void LLLocalBitmap::replaceIDs(const LLUUID& old_id, LLUUID new_id)  {  	// checking for misuse.  	if (old_id == new_id) @@ -350,6 +394,8 @@ void LLLocalBitmap::replaceIDs(LLUUID old_id, LLUUID new_id)  		return;  	} +    mChangedSignal(getTrackingID(), old_id, new_id); +  	// processing updates per channel; makes the process scalable.  	// the only actual difference is in SetTE* call i.e. SetTETexture, SetTENormal, etc.  	updateUserPrims(old_id, new_id, LLRender::DIFFUSE_MAP); @@ -381,6 +427,8 @@ void LLLocalBitmap::replaceIDs(LLUUID old_id, LLUUID new_id)  	updateUserLayers(old_id, new_id, LLWearableType::WT_UNIVERSAL);  	updateUserLayers(old_id, new_id, LLWearableType::WT_UNDERPANTS);  	updateUserLayers(old_id, new_id, LLWearableType::WT_UNDERSHIRT); + +    updateGLTFMaterials(old_id, new_id);  }  // this function sorts the faces from a getFaceList[getNumFaces] into a list of objects @@ -578,6 +626,67 @@ void LLLocalBitmap::updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableTyp  	}  } +void LLLocalBitmap::updateGLTFMaterials(LLUUID old_id, LLUUID new_id) +{ +    // Might be a better idea to hold this in LLGLTFMaterialList +    mat_list_t::iterator end = mGLTFMaterialWithLocalTextures.end(); +    for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != end;) +    { +        if ((*it)->getNumRefs() == 1) +        { +            // render and override materials are often recreated, +            // clean up any remains +            it = mGLTFMaterialWithLocalTextures.erase(it); +            end = mGLTFMaterialWithLocalTextures.end(); +        } +        else if ((*it)->replaceLocalTexture(mTrackingID, old_id, new_id)) +        { +            it++; +        } +        else +        { +            // Matching id not found, no longer in use +            // material would clean itself, remove from the list +            it = mGLTFMaterialWithLocalTextures.erase(it); +            end = mGLTFMaterialWithLocalTextures.end(); +        } +    } + +    // Render material consists of base and override materials, make sure replaceLocalTexture +    // gets called for base and override before applyOverride +    end = mGLTFMaterialWithLocalTextures.end(); +    for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != end;) +    { +        LLFetchedGLTFMaterial* fetched_mat = dynamic_cast<LLFetchedGLTFMaterial*>((*it).get()); +        if (fetched_mat) +        { +            for (LLTextureEntry* entry : fetched_mat->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) +                    { +                        llassert(dynamic_cast<LLFetchedGLTFMaterial*>(entry->getGLTFRenderMaterial()) != nullptr); +                        { +                            *render_mat = *fetched_mat; +                        } +                        render_mat->applyOverride(*override_mat); +                    } +                } +            } +        } +        ++it; +    } +} +  LLAvatarAppearanceDefines::ETextureIndex LLLocalBitmap::getTexIndex(  	LLWearableType::EType type, LLAvatarAppearanceDefines::EBakedTextureIndex baked_texind)  { @@ -1020,11 +1129,11 @@ void LLLocalBitmapMgr::delUnit(LLUUID tracking_id)  	}  } -LLUUID LLLocalBitmapMgr::getWorldID(LLUUID tracking_id) +LLUUID LLLocalBitmapMgr::getWorldID(const LLUUID &tracking_id) const  {  	LLUUID world_id = LLUUID::null; -	for (local_list_iter iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++) +	for (local_list_citer iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++)  	{  		LLLocalBitmap* unit = *iter;  		if (unit->getTrackingID() == tracking_id) @@ -1036,9 +1145,9 @@ LLUUID LLLocalBitmapMgr::getWorldID(LLUUID tracking_id)  	return world_id;  } -bool LLLocalBitmapMgr::isLocal(const LLUUID world_id) +bool LLLocalBitmapMgr::isLocal(const LLUUID &world_id) const  { -    for (local_list_iter iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++) +    for (local_list_citer iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++)      {          LLLocalBitmap* unit = *iter;          if (unit->getWorldID() == world_id) @@ -1049,11 +1158,11 @@ bool LLLocalBitmapMgr::isLocal(const LLUUID world_id)      return false;  } -std::string LLLocalBitmapMgr::getFilename(LLUUID tracking_id) +std::string LLLocalBitmapMgr::getFilename(const LLUUID &tracking_id) const  {  	std::string filename = ""; -	for (local_list_iter iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++) +	for (local_list_citer iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++)  	{  		LLLocalBitmap* unit = *iter;  		if (unit->getTrackingID() == tracking_id) @@ -1065,6 +1174,32 @@ std::string LLLocalBitmapMgr::getFilename(LLUUID tracking_id)  	return filename;  } +boost::signals2::connection LLLocalBitmapMgr::setOnChangedCallback(const LLUUID tracking_id, const LLLocalBitmap::LLLocalTextureCallback &cb) +{ +    for (local_list_iter iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++) +    { +        LLLocalBitmap* unit = *iter; +        if (unit->getTrackingID() == tracking_id) +        { +            return unit->setChangedCallback(cb); +        } +    } + +    return boost::signals2::connection(); +} + +void LLLocalBitmapMgr::associateGLTFMaterial(const LLUUID tracking_id, LLGLTFMaterial* mat) +{ +    for (local_list_iter iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++) +    { +        LLLocalBitmap* unit = *iter; +        if (unit->getTrackingID() == tracking_id) +        { +            unit->addGLTFMaterial(mat); +        } +    } +} +  void LLLocalBitmapMgr::feedScrollList(LLScrollListCtrl* ctrl)  {  	if (ctrl) diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h index bb026ed3aa..1fdf9dccbf 100644 --- a/indra/newview/lllocalbitmaps.h +++ b/indra/newview/lllocalbitmaps.h @@ -36,6 +36,7 @@  class LLScrollListCtrl;  class LLImageRaw;  class LLViewerObject; +class LLGLTFMaterial;  class LLLocalBitmap  { @@ -44,11 +45,11 @@ class LLLocalBitmap  		~LLLocalBitmap();  	public: /* accessors */ -		std::string	getFilename(); -		std::string	getShortName(); -		LLUUID		getTrackingID(); -		LLUUID		getWorldID(); -		bool		getValid(); +		std::string	getFilename() const; +		std::string	getShortName() const; +		LLUUID		getTrackingID() const; +		LLUUID		getWorldID() const; +		bool		getValid() const;  	public: /* self update public section */  		enum EUpdateType @@ -59,13 +60,21 @@ class LLLocalBitmap  		bool updateSelf(EUpdateType = UT_REGUPDATE); +        typedef boost::signals2::signal<void(const LLUUID& tracking_id, +                                             const LLUUID& old_id, +                                             const LLUUID& new_id)> LLLocalTextureChangedSignal; +        typedef LLLocalTextureChangedSignal::slot_type LLLocalTextureCallback; +        boost::signals2::connection setChangedCallback(const LLLocalTextureCallback& cb); +        void addGLTFMaterial(LLGLTFMaterial* mat); +  	private: /* self update private section */  		bool decodeBitmap(LLPointer<LLImageRaw> raw); -		void replaceIDs(LLUUID old_id, LLUUID new_id); +        void replaceIDs(const LLUUID &old_id, LLUUID new_id);  		std::vector<LLViewerObject*> prepUpdateObjects(LLUUID old_id, U32 channel);  		void updateUserPrims(LLUUID old_id, LLUUID new_id, U32 channel);  		void updateUserVolumes(LLUUID old_id, LLUUID new_id, U32 channel);  		void updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableType::EType type); +        void updateGLTFMaterials(LLUUID old_id, LLUUID new_id);  		LLAvatarAppearanceDefines::ETextureIndex getTexIndex(LLWearableType::EType type, LLAvatarAppearanceDefines::EBakedTextureIndex baked_texind);  	private: /* private enums */ @@ -93,6 +102,12 @@ class LLLocalBitmap  		EExtension  mExtension;  		ELinkStatus mLinkStatus;  		S32         mUpdateRetries; +        LLLocalTextureChangedSignal	mChangedSignal; + +        // Store a list of accosiated materials +        // Might be a better idea to hold this in LLGLTFMaterialList +        typedef std::vector<LLPointer<LLGLTFMaterial> > mat_list_t; +        mat_list_t mGLTFMaterialWithLocalTextures;  }; @@ -120,10 +135,12 @@ public:  	void         delUnit(LLUUID tracking_id);  	bool 		checkTextureDimensions(std::string filename); -	LLUUID       getWorldID(LLUUID tracking_id); -    bool         isLocal(LLUUID world_id); -	std::string  getFilename(LLUUID tracking_id); -     +	LLUUID       getWorldID(const LLUUID &tracking_id) const; +    bool         isLocal(const LLUUID& world_id) const; +	std::string  getFilename(const LLUUID &tracking_id) const; +    boost::signals2::connection setOnChangedCallback(const LLUUID tracking_id, const LLLocalBitmap::LLLocalTextureCallback& cb); +    void associateGLTFMaterial(const LLUUID tracking_id, LLGLTFMaterial* mat); +  	void         feedScrollList(LLScrollListCtrl* ctrl);  	void         doUpdates();  	void         setNeedsRebake(); @@ -134,6 +151,7 @@ private:  	LLLocalBitmapTimer           mTimer;  	bool                         mNeedsRebake;  	typedef std::list<LLLocalBitmap*>::iterator local_list_iter; +    typedef std::list<LLLocalBitmap*>::const_iterator local_list_citer;  };  #endif diff --git a/indra/newview/lllocalgltfmaterials.cpp b/indra/newview/lllocalgltfmaterials.cpp index b7fdead3f9..61e0163798 100644 --- a/indra/newview/lllocalgltfmaterials.cpp +++ b/indra/newview/lllocalgltfmaterials.cpp @@ -119,15 +119,6 @@ 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()  { diff --git a/indra/newview/lllocalgltfmaterials.h b/indra/newview/lllocalgltfmaterials.h index 1442b83a40..13b7577e96 100644 --- a/indra/newview/lllocalgltfmaterials.h +++ b/indra/newview/lllocalgltfmaterials.h @@ -49,9 +49,6 @@ public: /* accessors */      LLUUID		getWorldID() const;      S32			getIndexInFile() const; -    void addTextureEntry(LLTextureEntry* te) override; -    void removeTextureEntry(LLTextureEntry* te) override; -  public:      bool updateSelf(); @@ -81,7 +78,6 @@ private: /* members */      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/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 8f016b9125..70e21cae73 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -344,6 +344,39 @@ bool LLSelectedTEGetMatData::apply(LLViewerObject* objectp, S32 te_index)      return false;  } +class LLSelectedTEUpdateOverrides: public LLSelectedNodeFunctor +{ +public: +    LLSelectedTEUpdateOverrides(LLMaterialEditor* me) : mEditor(me) {} + +    virtual bool apply(LLSelectNode* nodep); + +    LLMaterialEditor* mEditor; +}; + +bool LLSelectedTEUpdateOverrides::apply(LLSelectNode* nodep) +{ +    LLViewerObject* objectp = nodep->getObject(); +    if (!objectp) +    { +        return false; +    } +    S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); // avatars have TEs but no faces +    for (S32 te_index = 0; te_index < num_tes; ++te_index) +    { + +        LLTextureEntry* tep = objectp->getTE(te_index); +        LLGLTFMaterial* override_mat = tep->getGLTFMaterialOverride(); +        if (mEditor->updateMaterialLocalSubscription(override_mat)) +        { +            LLGLTFMaterial* render_mat = tep->getGLTFRenderMaterial(); +            mEditor->updateMaterialLocalSubscription(render_mat); +        } +    } + +    return true; +} +  ///----------------------------------------------------------------------------  /// Class LLMaterialEditor  ///---------------------------------------------------------------------------- @@ -364,6 +397,10 @@ LLMaterialEditor::LLMaterialEditor(const LLSD& key)      }  } +LLMaterialEditor::~LLMaterialEditor() +{ +} +  void LLMaterialEditor::setObjectID(const LLUUID& object_id)  {      LLPreview::setObjectID(object_id); @@ -532,6 +569,11 @@ void LLMaterialEditor::onClose(bool app_quitting)      {          mSelectionUpdateSlot.disconnect();      } +    for (mat_connection_map_t::value_type &cn : mTextureChangesUpdates) +    { +        cn.second.mConnection.disconnect(); +    } +    mTextureChangesUpdates.clear();      LLPreview::onClose(app_quitting);  } @@ -862,6 +904,118 @@ void LLMaterialEditor::setEnableEditing(bool can_modify)      mNormalTextureCtrl->setEnabled(can_modify);  } +void LLMaterialEditor::subscribeToLocalTexture(S32 dirty_flag, const LLUUID& tracking_id) +{ +    if (mTextureChangesUpdates[dirty_flag].mTrackingId != tracking_id) +    { +        mTextureChangesUpdates[dirty_flag].mConnection.disconnect(); +        mTextureChangesUpdates[dirty_flag].mTrackingId = tracking_id; +        mTextureChangesUpdates[dirty_flag].mConnection = LLLocalBitmapMgr::getInstance()->setOnChangedCallback(tracking_id, +                                                                                                               [this, dirty_flag](const LLUUID& tracking_id, const LLUUID& old_id, const LLUUID& new_id) +                                                                                                               { +                                                                                                                   if (new_id.isNull()) +                                                                                                                   { +                                                                                                                       mTextureChangesUpdates[dirty_flag].mConnection.disconnect(); +                                                                                                                       //mTextureChangesUpdates.erase(dirty_flag); +                                                                                                                   } +                                                                                                                   else +                                                                                                                   { +                                                                                                                       replaceLocalTexture(old_id, new_id); +                                                                                                                   } +                                                                                                               }); +    } +} + +LLUUID LLMaterialEditor::getLocalTextureTrackingIdFromFlag(U32 flag) +{ +    mat_connection_map_t::iterator found = mTextureChangesUpdates.find(flag); +    if (found != mTextureChangesUpdates.end()) +    { +        return found->second.mTrackingId; +    } +    return LLUUID(); +} + +bool LLMaterialEditor::updateMaterialLocalSubscription(LLGLTFMaterial* mat) +{ +    if (!mat) +    { +        return false; +    } + +    bool res = false; +    for (mat_connection_map_t::value_type& cn : mTextureChangesUpdates) +    { +        LLUUID world_id = LLLocalBitmapMgr::getInstance()->getWorldID(cn.second.mTrackingId); +        if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]) +        { +            LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); +            res = true; +            continue; +        } +        if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]) +        { +            LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); +            res = true; +            continue; +        } +        if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]) +        { +            LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); +            res = true; +            continue; +        } +        if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]) +        { +            LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); +            res = true; +            continue; +        } +    } +    return res; +} + +void LLMaterialEditor::replaceLocalTexture(const LLUUID& old_id, const LLUUID& new_id) +{ +    // todo: might be a good idea to set mBaseColorTextureUploadId here +    // and when texturectrl picks a local texture +    if (getBaseColorId() == old_id) +    { +        mBaseColorTextureCtrl->setValue(new_id); +    } +    if (mBaseColorTextureCtrl->getDefaultImageAssetID() == old_id) +    { +        mBaseColorTextureCtrl->setDefaultImageAssetID(new_id); +    } + +    if (getMetallicRoughnessId() == old_id) +    { +        mMetallicTextureCtrl->setValue(new_id); +    } +    if (mMetallicTextureCtrl->getDefaultImageAssetID() == old_id) +    { +        mMetallicTextureCtrl->setDefaultImageAssetID(new_id); +    } + +    if (getEmissiveId() == old_id) +    { +        mEmissiveTextureCtrl->setValue(new_id); +    } +    if (mEmissiveTextureCtrl->getDefaultImageAssetID() == old_id) +    { +        mEmissiveTextureCtrl->setDefaultImageAssetID(new_id); +    } + +    if (getNormalId() == old_id) +    { +        mNormalTextureCtrl->setValue(new_id); +    } +    if (mNormalTextureCtrl->getDefaultImageAssetID() == old_id) +    { +        mNormalTextureCtrl->setDefaultImageAssetID(new_id); +    } +} +  void LLMaterialEditor::onCommitTexture(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag)  {      if (!mIsOverride) @@ -914,6 +1068,21 @@ void LLMaterialEditor::onCommitTexture(LLUICtrl* ctrl, const LLSD& data, S32 dir          }      } +    LLTextureCtrl* tex_ctrl = (LLTextureCtrl*)ctrl; +    if (tex_ctrl->isImageLocal()) +    { +        subscribeToLocalTexture(dirty_flag, tex_ctrl->getLocalTrackingID()); +    } +    else +    { +        // unsubcribe potential old callabck +        mat_connection_map_t::iterator found = mTextureChangesUpdates.find(dirty_flag); +        if (found != mTextureChangesUpdates.end()) +        { +            found->second.mConnection.disconnect(); +        } +    } +      markChangesUnsaved(dirty_flag);      applyToSelection();  } @@ -924,6 +1093,16 @@ void LLMaterialEditor::onCancelCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_      applyToSelection();  } +void update_local_texture(LLUICtrl* ctrl, LLGLTFMaterial* mat) +{ +    LLTextureCtrl* tex_ctrl = (LLTextureCtrl*)ctrl; +    if (tex_ctrl->isImageLocal()) +    { +        // subscrive material to updates of local textures +        LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tex_ctrl->getLocalTrackingID(), mat); +    } +} +  void LLMaterialEditor::onSelectCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag)  {      mUnsavedChanges |= dirty_flag; @@ -959,21 +1138,25 @@ void LLMaterialEditor::onSelectCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_                      case MATERIAL_BASE_COLOR_TEX_DIRTY:                      {                          nodep->mSavedGLTFOverrideMaterials[te]->setBaseColorId(mCtrl->getValue().asUUID(), true); +                        update_local_texture(mCtrl, nodep->mSavedGLTFOverrideMaterials[te].get());                          break;                      }                      case MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY:                      {                          nodep->mSavedGLTFOverrideMaterials[te]->setOcclusionRoughnessMetallicId(mCtrl->getValue().asUUID(), true); +                        update_local_texture(mCtrl, nodep->mSavedGLTFOverrideMaterials[te].get());                          break;                      }                      case MATERIAL_EMISIVE_TEX_DIRTY:                      {                          nodep->mSavedGLTFOverrideMaterials[te]->setEmissiveId(mCtrl->getValue().asUUID(), true); +                        update_local_texture(mCtrl, nodep->mSavedGLTFOverrideMaterials[te].get());                          break;                      }                      case MATERIAL_NORMAL_TEX_DIRTY:                      {                          nodep->mSavedGLTFOverrideMaterials[te]->setNormalId(mCtrl->getValue().asUUID(), true); +                        update_local_texture(mCtrl, nodep->mSavedGLTFOverrideMaterials[te].get());                          break;                      }                      // Colors @@ -1403,6 +1586,20 @@ void LLMaterialEditor::finishInventoryUpload(LLUUID itemId, LLUUID newAssetId, L          {              me->refreshFromInventory(itemId);          } + +        if (me && !me->mTextureChangesUpdates.empty()) +        { +            const LLInventoryItem* item = me->getItem(); +            if (item) +            { +                // local materials were assigned, force load material and init tracking +                LLGLTFMaterial* mat = gGLTFMaterialList.getMaterial(item->getAssetUUID()); +                for (mat_connection_map_t::value_type &val : me->mTextureChangesUpdates) +                { +                    LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.second.mTrackingId, mat); +                } +            } +        }      }  } @@ -1417,6 +1614,16 @@ void LLMaterialEditor::finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID          me->setAssetId(newAssetId);          me->refreshFromInventory();          me->setEnabled(true); + +        if (me && !me->mTextureChangesUpdates.empty()) +        { +            // local materials were assigned, force load material and init tracking +            LLGLTFMaterial* mat = gGLTFMaterialList.getMaterial(newAssetId); +            for (mat_connection_map_t::value_type &val : me->mTextureChangesUpdates) +            { +                LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.second.mTrackingId, mat); +            } +        }      }  } @@ -1450,6 +1657,17 @@ void LLMaterialEditor::finishSaveAs(              {                  me->loadAsset();                  me->setEnabled(true); + +                // Local texure support +                if (!me->mTextureChangesUpdates.empty()) +                { +                    // local materials were assigned, force load material and init tracking +                    LLGLTFMaterial* mat = gGLTFMaterialList.getMaterial(item->getAssetUUID()); +                    for (mat_connection_map_t::value_type &val : me->mTextureChangesUpdates) +                    { +                        LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.second.mTrackingId, mat); +                    } +                }              }          }          else if(has_unsaved_changes) @@ -2727,28 +2945,58 @@ public:              if (changed_flags & MATERIAL_BASE_COLOR_TEX_DIRTY)              {                  material->setBaseColorId(mEditor->getBaseColorId(), true); +                LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_BASE_COLOR_TEX_DIRTY); +                if (tracking_id.notNull()) +                { +                    LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material); +                }              }              else if ((reverted_flags & MATERIAL_BASE_COLOR_TEX_DIRTY) && revert_mat.notNull())              {                  material->setBaseColorId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR], false); +                LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_BASE_COLOR_TEX_DIRTY); +                if (tracking_id.notNull()) +                { +                    LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material); +                }              }              if (changed_flags & MATERIAL_NORMAL_TEX_DIRTY)              {                  material->setNormalId(mEditor->getNormalId(), true); +                LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_NORMAL_TEX_DIRTY); +                if (tracking_id.notNull()) +                { +                    LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material); +                }              }              else if ((reverted_flags & MATERIAL_NORMAL_TEX_DIRTY) && revert_mat.notNull())              {                  material->setNormalId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL], false); +                LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_NORMAL_TEX_DIRTY); +                if (tracking_id.notNull()) +                { +                    LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material); +                }              }              if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY)              {                  material->setOcclusionRoughnessMetallicId(mEditor->getMetallicRoughnessId(), true); +                LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY); +                if (tracking_id.notNull()) +                { +                    LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material); +                }              }              else if ((reverted_flags & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) && revert_mat.notNull())              {                  material->setOcclusionRoughnessMetallicId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS], false); +                LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY); +                if (tracking_id.notNull()) +                { +                    LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material); +                }              }              if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY) @@ -2781,10 +3029,20 @@ public:              if (changed_flags & MATERIAL_EMISIVE_TEX_DIRTY)              {                  material->setEmissiveId(mEditor->getEmissiveId(), true); +                LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_EMISIVE_TEX_DIRTY); +                if (tracking_id.notNull()) +                { +                    LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material); +                }              }              else if ((reverted_flags & MATERIAL_EMISIVE_TEX_DIRTY) && revert_mat.notNull())              {                  material->setEmissiveId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE], false); +                LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_EMISIVE_TEX_DIRTY); +                if (tracking_id.notNull()) +                { +                    LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material); +                }              }              if (changed_flags & MATERIAL_DOUBLE_SIDED_DIRTY) @@ -2936,6 +3194,34 @@ void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat)      setDoubleSided(mat->mDoubleSided);      setAlphaMode(mat->getAlphaMode());      setAlphaCutoff(mat->mAlphaCutoff); + +    if (mat->hasLocalTextures()) +    { +        for (LLGLTFMaterial::local_tex_map_t::value_type &val : mat->mTrackingIdToLocalTexture) +        { +            LLUUID world_id = LLLocalBitmapMgr::getInstance()->getWorldID(val.first); +            if (val.second != world_id) +            { +                LL_WARNS() << "world id mismatch" << LL_ENDL; +            } +            if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]) +            { +                subscribeToLocalTexture(MATERIAL_BASE_COLOR_TEX_DIRTY, val.first); +            } +            if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]) +            { +                subscribeToLocalTexture(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY, val.first); +            } +            if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]) +            { +                subscribeToLocalTexture(MATERIAL_EMISIVE_TEX_DIRTY, val.first); +            } +            if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]) +            { +                subscribeToLocalTexture(MATERIAL_NORMAL_TEX_DIRTY, val.first); +            } +        } +    }  }  bool LLMaterialEditor::setFromSelection() @@ -2954,6 +3240,8 @@ bool LLMaterialEditor::setFromSelection()          const LLViewerInventoryItem* item = selected_object->getInventoryItemByAsset(func.mMaterialId);          const bool allow_modify = !item || canModify(selected_object, item);          setEnableEditing(allow_modify); + +        // todo: apply local texture data to all materials in selection      }      else      { @@ -2976,6 +3264,15 @@ bool LLMaterialEditor::setFromSelection()          // Memorize selection data for filtering further updates          mOverrideObjectId = func.mObjectId;          mOverrideObjectTE = func.mObjectTE; + +        // Ovverdired might have been updated, +        // refresh state of local textures in overrides +        //  +        // Todo: this probably shouldn't be here, but in localbitmap, +        // subscried to all material overrides if we want copied +        // objects to get properly updated as well +        LLSelectedTEUpdateOverrides local_tex_func(this); +        selected_objects->applyToNodes(&local_tex_func);      }      return func.mMaterial.notNull(); diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index 2e25a9ca3d..4e0350b4cc 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -87,6 +87,7 @@ protected:  class LLMaterialEditor : public LLPreview, public LLVOInventoryListener  { public:  	LLMaterialEditor(const LLSD& key); +    ~LLMaterialEditor();      bool setFromGltfModel(const tinygltf::Model& model, S32 index, bool set_textures = false); @@ -218,6 +219,8 @@ class LLMaterialEditor : public LLPreview, public LLVOInventoryListener      void setCanSave(bool value);      void setEnableEditing(bool can_modify); +    void subscribeToLocalTexture(S32 dirty_flag, const LLUUID& tracking_id); +    void replaceLocalTexture(const LLUUID& old_id, const LLUUID& new_id); // Local texture support      void onCommitTexture(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag);      void onCancelCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag);      void onSelectCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag); @@ -227,6 +230,8 @@ class LLMaterialEditor : public LLPreview, public LLVOInventoryListener      U32 getUnsavedChangesFlags() { return mUnsavedChanges; }      U32 getRevertedChangesFlags() { return mRevertedChanges; } +    LLUUID getLocalTextureTrackingIdFromFlag(U32 flag); +    bool updateMaterialLocalSubscription(LLGLTFMaterial* mat);      static bool capabilitiesAvailable(); @@ -305,5 +310,13 @@ private:      static bool mOverrideInProgress;      static bool mSelectionNeedsUpdate;      boost::signals2::connection mSelectionUpdateSlot; + +    struct LocalTextureConnection +    { +        LLUUID mTrackingId; +        boost::signals2::connection mConnection; +    }; +    typedef std::map<S32, LocalTextureConnection> mat_connection_map_t; +    mat_connection_map_t mTextureChangesUpdates;  }; diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 1a4546875d..c2c9139c19 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -1959,7 +1959,7 @@ void LLPanelProfileSecondLife::onShowTexturePicker()              mFloaterTexturePickerHandle = texture_floaterp->getHandle(); -            texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLPickerSource source, const LLUUID& asset_id, const LLUUID&) +            texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLPickerSource source, const LLUUID& asset_id, const LLUUID&, const LLUUID&)              {                  if (op == LLTextureCtrl::TEXTURE_SELECT)                  { @@ -2285,7 +2285,7 @@ void LLPanelProfileFirstLife::onChangePhoto()              mFloaterTexturePickerHandle = texture_floaterp->getHandle(); -            texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLPickerSource source, const LLUUID& asset_id, const LLUUID&) +            texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLPickerSource source, const LLUUID& asset_id, const LLUUID&, const LLUUID&)              {                  if (op == LLTextureCtrl::TEXTURE_SELECT)                  { diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 50e2f5e1d9..f302426a43 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -856,6 +856,7 @@ void LLFloaterTexturePicker::commitCallback(LLTextureCtrl::ETexturePickOp op)      }      LLUUID asset_id = mImageAssetID;      LLUUID inventory_id; +    LLUUID tracking_id;      LLPickerSource mode = (LLPickerSource)mModeSelector->getValue().asInteger();      switch (mode) @@ -896,16 +897,16 @@ void LLFloaterTexturePicker::commitCallback(LLTextureCtrl::ETexturePickOp op)                  if (!mLocalScrollCtrl->getAllSelected().empty())                  {                      LLSD data = mLocalScrollCtrl->getFirstSelected()->getValue(); -                    LLUUID temp_id = data["id"]; +                    tracking_id = data["id"];                      S32 asset_type = data["type"].asInteger();                      if (LLAssetType::AT_MATERIAL == asset_type)                      { -                        asset_id = LLLocalGLTFMaterialMgr::getInstance()->getWorldID(temp_id); +                        asset_id = LLLocalGLTFMaterialMgr::getInstance()->getWorldID(tracking_id);                      }                      else                      { -                        asset_id = LLLocalBitmapMgr::getInstance()->getWorldID(temp_id); +                        asset_id = LLLocalBitmapMgr::getInstance()->getWorldID(tracking_id);                      }                  }                  else @@ -922,13 +923,13 @@ void LLFloaterTexturePicker::commitCallback(LLTextureCtrl::ETexturePickOp op)              break;      } -    mOnFloaterCommitCallback(op, mode, asset_id, inventory_id); +    mOnFloaterCommitCallback(op, mode, asset_id, inventory_id, tracking_id);  }  void LLFloaterTexturePicker::commitCancel()  {  	if (!mNoCopyTextureSelected && mOnFloaterCommitCallback && mCanApply)  	{ -		mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CANCEL, PICKER_UNKNOWN, mOriginalImageAssetID, LLUUID::null); +		mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CANCEL, PICKER_UNKNOWN, mOriginalImageAssetID, LLUUID::null, LLUUID::null);  	}  } @@ -982,7 +983,7 @@ void LLFloaterTexturePicker::onBtnCancel(void* userdata)  	self->setImageID( self->mOriginalImageAssetID );  	if (self->mOnFloaterCommitCallback)  	{ -		self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CANCEL, PICKER_UNKNOWN, self->mOriginalImageAssetID, LLUUID::null); +		self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CANCEL, PICKER_UNKNOWN, self->mOriginalImageAssetID, LLUUID::null, LLUUID::null);  	}  	self->mViewModel->resetDirty();  	self->closeFloater(); @@ -1187,7 +1188,7 @@ void LLFloaterTexturePicker::onLocalScrollCommit(LLUICtrl* ctrl, void* userdata)  		{  			if (self->mOnFloaterCommitCallback)  			{ -				self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CHANGE, PICKER_LOCAL, inworld_id, LLUUID::null); +				self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CHANGE, PICKER_LOCAL, inworld_id, LLUUID::null, tracking_id);  			}  		}  	} @@ -1814,7 +1815,7 @@ void LLTextureCtrl::showPicker(BOOL take_focus)  		}  		if (texture_floaterp)  		{ -			texture_floaterp->setOnFloaterCommitCallback(boost::bind(&LLTextureCtrl::onFloaterCommit, this, _1, _2, _3, _4)); +			texture_floaterp->setOnFloaterCommitCallback(boost::bind(&LLTextureCtrl::onFloaterCommit, this, _1, _2, _3, _4, _5));  		}  		if (texture_floaterp)  		{ @@ -1938,7 +1939,7 @@ void LLTextureCtrl::onFloaterClose()  	mFloaterHandle.markDead();  } -void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLPickerSource source, const LLUUID& asset_id, const LLUUID& inv_id) +void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLPickerSource source, const LLUUID& asset_id, const LLUUID& inv_id, const LLUUID& tracking_id)  {      LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get(); @@ -1961,16 +1962,23 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLPickerSource source, co                  case PICKER_INVENTORY:                      mImageItemID = inv_id;                      mImageAssetID = asset_id; +                    mLocalTrackingID.setNull();                      break;                  case PICKER_BAKE: +                    mImageItemID = LLUUID::null; +                    mImageAssetID = asset_id; +                    mLocalTrackingID.setNull(); +                    break;                  case PICKER_LOCAL:                      mImageItemID = LLUUID::null;                      mImageAssetID = asset_id; +                    mLocalTrackingID = tracking_id;                      break;                  case PICKER_UNKNOWN:                  default:                      mImageItemID = floaterp->findItemID(asset_id, FALSE);                      mImageAssetID = asset_id; +                    mLocalTrackingID.setNull();                      break;              } @@ -2028,6 +2036,7 @@ void LLTextureCtrl::setImageAssetID( const LLUUID& asset_id )  	{  		mImageItemID.setNull();  		mImageAssetID = asset_id; +        mLocalTrackingID.setNull();  		LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();  		if( floaterp && getEnabled() )  		{ diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index 180c4fa4b8..c47df5accb 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -200,7 +200,11 @@ public:  	void			closeDependentFloater();  	void			onFloaterClose(); -	void			onFloaterCommit(ETexturePickOp op, LLPickerSource source, const LLUUID& local_id, const LLUUID& inv_id); +    void			onFloaterCommit(ETexturePickOp op, +                                    LLPickerSource source, +                                    const LLUUID& local_id, +                                    const LLUUID& inv_id, +                                    const LLUUID& tracking_id);  	// This call is returned when a drag is detected. Your callback  	// should return TRUE if the drag is acceptable. @@ -230,6 +234,9 @@ public:      void setInventoryPickType(EPickInventoryType type);      EPickInventoryType getInventoryPickType() { return mInventoryPickType; }; +    bool isImageLocal() { return mLocalTrackingID.notNull(); } +    LLUUID getLocalTrackingID() { return mLocalTrackingID; } +  private:  	BOOL allowDrop(LLInventoryItem* item, EDragAndDropType cargo_type, std::string& tooltip_msg);  	BOOL doDrop(LLInventoryItem* item); @@ -247,6 +254,7 @@ private:  	LLUUID					 	mImageAssetID;  	LLUUID					 	mDefaultImageAssetID;  	LLUUID					 	mBlankImageAssetID; +    LLUUID						mLocalTrackingID;  	LLUIImagePtr				mFallbackImage;  	std::string					mDefaultImageName;  	LLHandle<LLFloater>			mFloaterHandle; @@ -272,7 +280,7 @@ private:  //////////////////////////////////////////////////////////////////////////////////////////  // LLFloaterTexturePicker -typedef boost::function<void(LLTextureCtrl::ETexturePickOp op, LLPickerSource source, const LLUUID& asset_id, const LLUUID& inventory_id)> floater_commit_callback; +typedef boost::function<void(LLTextureCtrl::ETexturePickOp op, LLPickerSource source, const LLUUID& asset_id, const LLUUID& inventory_id, const LLUUID& tracking_id)> floater_commit_callback;  typedef boost::function<void()> floater_close_callback;  typedef boost::function<void(const LLUUID& asset_id)> set_image_asset_id_callback;  typedef boost::function<void(LLPointer<LLViewerTexture> texture)> set_on_update_image_stats_callback; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 3b5b986725..2bcd0858d3 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -5475,6 +5475,11 @@ S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_ma              tep->setGLTFRenderMaterial(render_mat);              retval = TEM_CHANGE_TEXTURE; +            for (LLGLTFMaterial::local_tex_map_t::value_type &val : override_mat->mTrackingIdToLocalTexture) +            { +                LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.first, override_mat); +            } +          }          else if (tep->setGLTFRenderMaterial(nullptr))          { | 
