From dc63dfc0dd6554f5f45b1d80bd4cb9258eefee95 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 25 Oct 2023 23:38:12 +0300 Subject: SL-20523 Local textures not updating on PBR Materials #1 Update editor in which texture changed to local --- indra/llprimitive/llgltfmaterial.h | 6 +++ indra/newview/llfloaterchangeitemthumbnail.cpp | 2 +- indra/newview/lllocalbitmaps.cpp | 48 ++++++++++++----- indra/newview/lllocalbitmaps.h | 28 ++++++---- indra/newview/llmaterialeditor.cpp | 75 ++++++++++++++++++++++++++ indra/newview/llmaterialeditor.h | 2 + indra/newview/llpanelprofile.cpp | 4 +- indra/newview/lltexturectrl.cpp | 27 ++++++---- indra/newview/lltexturectrl.h | 12 ++++- 9 files changed, 168 insertions(+), 36 deletions(-) diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index 822a0aab22..548e2c52f4 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -222,6 +222,10 @@ public: virtual void addTextureEntry(LLTextureEntry* te) {}; virtual void removeTextureEntry(LLTextureEntry* te) {}; + // For local textures so that editor will know to track changes + void setHasLocalTextures(bool val) { mHasLocalTextures = val; } + bool hasLocalTextures() { return mHasLocalTextures; } + protected: static LLVector2 vec2FromJson(const std::map& object, const char* key, const LLVector2& default_value); static F32 floatFromJson(const std::map& object, const char* key, const F32 default_value); @@ -238,4 +242,6 @@ protected: void writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, bool force_write = false) const; template static void writeToTexture(tinygltf::Model& model, T& texture_info, const LLUUID& texture_id, const TextureTransform& transform, bool force_write = false); + + bool mHasLocalTextures; }; 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/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index 257208470e..6f1e4c9419 100644 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -142,27 +142,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 +273,11 @@ bool LLLocalBitmap::updateSelf(EUpdateType optional_firstupdate) return updated; } +boost::signals2::connection LLLocalBitmap::setChangedCallback(const LLLocalTextureCallback& cb) +{ + return mChangedSignal.connect(cb); +} + bool LLLocalBitmap::decodeBitmap(LLPointer rawimg) { bool decode_successful = false; @@ -340,7 +345,7 @@ bool LLLocalBitmap::decodeBitmap(LLPointer 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 +355,8 @@ void LLLocalBitmap::replaceIDs(LLUUID old_id, LLUUID new_id) return; } + mChangedSignal(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 +388,9 @@ 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); + + // Go over any local material + } // this function sorts the faces from a getFaceList[getNumFaces] into a list of objects @@ -1020,11 +1030,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 +1046,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 +1059,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 +1075,20 @@ 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) + { + unit->setChangedCallback(cb); + } + } + + return boost::signals2::connection(); +} + void LLLocalBitmapMgr::feedScrollList(LLScrollListCtrl* ctrl) { if (ctrl) diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h index bb026ed3aa..f36fd6d320 100644 --- a/indra/newview/lllocalbitmaps.h +++ b/indra/newview/lllocalbitmaps.h @@ -44,11 +44,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,9 +59,14 @@ class LLLocalBitmap bool updateSelf(EUpdateType = UT_REGUPDATE); + typedef boost::signals2::signal LLLocalTextureChangedSignal; + typedef LLLocalTextureChangedSignal::slot_type LLLocalTextureCallback; + boost::signals2::connection setChangedCallback(const LLLocalTextureCallback& cb); + private: /* self update private section */ bool decodeBitmap(LLPointer raw); - void replaceIDs(LLUUID old_id, LLUUID new_id); + void replaceIDs(const LLUUID &old_id, LLUUID new_id); std::vector 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); @@ -93,6 +98,7 @@ class LLLocalBitmap EExtension mExtension; ELinkStatus mLinkStatus; S32 mUpdateRetries; + LLLocalTextureChangedSignal mChangedSignal; }; @@ -120,10 +126,11 @@ 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 feedScrollList(LLScrollListCtrl* ctrl); void doUpdates(); void setNeedsRebake(); @@ -134,6 +141,7 @@ private: LLLocalBitmapTimer mTimer; bool mNeedsRebake; typedef std::list::iterator local_list_iter; + typedef std::list::const_iterator local_list_citer; }; #endif diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 7a65231a2d..63d86cda61 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -532,6 +532,11 @@ void LLMaterialEditor::onClose(bool app_quitting) mSelectionUpdateSlot.disconnect(); } + for (boost::signals2::connection& cn : mTextureChangesUpdates) + { + cn.disconnect(); + } + LLPreview::onClose(app_quitting); } @@ -861,6 +866,47 @@ void LLMaterialEditor::setEnableEditing(bool can_modify) mNormalTextureCtrl->setEnabled(can_modify); } +void LLMaterialEditor::replaceTexture(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) @@ -911,6 +957,20 @@ void LLMaterialEditor::onCommitTexture(LLUICtrl* ctrl, const LLSD& data, S32 dir // the texture that is not in use childSetValue(upload_fee_ctrl_name, getString("no_upload_fee_string")); } + + LLTextureCtrl* tex_ctrl = (LLTextureCtrl*)ctrl; + if (tex_ctrl->isImageLocal()) + { + // Theoretically LLSD should be smart enough to not need this, but for extra safety + LLSD key = llsd_clone(getKey()); + // Subscribe material editor to local texture updates + mTextureChangesUpdates.push_back( + LLLocalBitmapMgr::getInstance()->setOnChangedCallback(tex_ctrl->getLocalTrackingID(), + [this](const LLUUID &old_id, const LLUUID& new_id) + { + replaceTexture(old_id, new_id); + })); + } } markChangesUnsaved(dirty_flag); @@ -923,6 +983,17 @@ 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()) + { + mat->setHasLocalTextures(true); + // Todo: subscrive material for an update + // tex_ctrl->getLocalTrackingID(); + } +} + void LLMaterialEditor::onSelectCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag) { mUnsavedChanges |= dirty_flag; @@ -958,21 +1029,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 diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index 1c40fcc348..4af68adce2 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -219,6 +219,7 @@ class LLMaterialEditor : public LLPreview, public LLVOInventoryListener void setCanSave(bool value); void setEnableEditing(bool can_modify); + void replaceTexture(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); @@ -306,5 +307,6 @@ private: static bool mOverrideInProgress; static bool mSelectionNeedsUpdate; boost::signals2::connection mSelectionUpdateSlot; + std::list 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 10667b02d9..3988bceb4e 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -846,6 +846,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) @@ -886,16 +887,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 @@ -912,13 +913,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); } } @@ -972,7 +973,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(); @@ -1177,7 +1178,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); } } } @@ -1804,7 +1805,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) { @@ -1928,7 +1929,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(); @@ -1951,16 +1952,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; } @@ -2018,6 +2026,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 mFloaterHandle; @@ -272,7 +280,7 @@ private: ////////////////////////////////////////////////////////////////////////////////////////// // LLFloaterTexturePicker -typedef boost::function floater_commit_callback; +typedef boost::function floater_commit_callback; typedef boost::function floater_close_callback; typedef boost::function set_image_asset_id_callback; typedef boost::function texture)> set_on_update_image_stats_callback; -- cgit v1.2.3 From 596a63051ebabfec51e48be02bbec33ab962d915 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 27 Oct 2023 23:41:13 +0300 Subject: SL-20523 Local textures not updating on PBR Materials #2 --- indra/llprimitive/llgltfmaterial.cpp | 46 ++++++++++++ indra/llprimitive/llgltfmaterial.h | 12 ++-- indra/newview/llfetchedgltfmaterial.cpp | 49 +++++++++++++ indra/newview/llfetchedgltfmaterial.h | 3 + indra/newview/lllocalbitmaps.cpp | 55 ++++++++++++++- indra/newview/lllocalbitmaps.h | 12 +++- indra/newview/llmaterialeditor.cpp | 121 +++++++++++++++++++++++++++----- indra/newview/llmaterialeditor.h | 13 +++- 8 files changed, 283 insertions(+), 28 deletions(-) diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index f42c11ee21..6afd83904f 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -89,6 +89,11 @@ LLGLTFMaterial& LLGLTFMaterial::operator=(const LLGLTFMaterial& rhs) mOverrideDoubleSided = rhs.mOverrideDoubleSided; mOverrideAlphaMode = rhs.mOverrideAlphaMode; + mLocalTextureIds = rhs.mLocalTextureIds; + mLocalTextureTrackingIds = rhs.mLocalTextureTrackingIds; + + updateTextureTracking(); + return *this; } @@ -765,3 +770,44 @@ LLUUID LLGLTFMaterial::getHash() const return hash; } +void LLGLTFMaterial::addLocalTextureTracking(const LLUUID& tracking_id, const LLUUID& tex_id) +{ + mLocalTextureTrackingIds.insert(tracking_id); + mLocalTextureIds.insert(tex_id); +} + +void LLGLTFMaterial::removeLocalTextureTracking(const LLUUID& tracking_id, const LLUUID& tex_id) +{ + mLocalTextureTrackingIds.erase(tracking_id); + mLocalTextureIds.erase(tex_id); +} + +bool LLGLTFMaterial::replaceLocalTexture(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; + } + } + + mLocalTextureIds.erase(old_id); + if (res) + { + mLocalTextureIds.insert(new_id); + } + + return res; +} + +void LLGLTFMaterial::updateTextureTracking() +{ + if (mLocalTextureTrackingIds.size() > 0) + { + LL_WARNS() << "copied a material with local textures, but tracking not implemented" << LL_ENDL; + } +} diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index 548e2c52f4..d45ada1561 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -223,8 +223,14 @@ public: virtual void removeTextureEntry(LLTextureEntry* te) {}; // For local textures so that editor will know to track changes - void setHasLocalTextures(bool val) { mHasLocalTextures = val; } - bool hasLocalTextures() { return mHasLocalTextures; } + void addLocalTextureTracking(const LLUUID& tracking_id, const LLUUID &tex_id); + void removeLocalTextureTracking(const LLUUID& tracking_id, const LLUUID& tex_id); + bool hasLocalTextures() { return !mLocalTextureIds.empty(); } + virtual bool replaceLocalTexture(const LLUUID &old_id, const LLUUID& new_id); + virtual void updateTextureTracking(); + + uuid_set_t mLocalTextureIds; + uuid_set_t mLocalTextureTrackingIds; protected: static LLVector2 vec2FromJson(const std::map& object, const char* key, const LLVector2& default_value); @@ -242,6 +248,4 @@ protected: void writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, bool force_write = false) const; template static void writeToTexture(tinygltf::Model& model, T& texture_info, const LLUUID& texture_id, const TextureTransform& transform, bool force_write = false); - - bool mHasLocalTextures; }; diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp index fc9d42bfb6..71a961ce49 100644 --- a/indra/newview/llfetchedgltfmaterial.cpp +++ b/indra/newview/llfetchedgltfmaterial.cpp @@ -144,6 +144,55 @@ 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& 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; + } + return res; +} + +void LLFetchedGLTFMaterial::updateTextureTracking() +{ + for (const LLUUID& id : mLocalTextureTrackingIds) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(id, this); + } +} + void LLFetchedGLTFMaterial::materialBegin() { llassert(!mFetching); diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h index 1668657281..02426bf088 100644 --- a/indra/newview/llfetchedgltfmaterial.h +++ b/indra/newview/llfetchedgltfmaterial.h @@ -50,6 +50,9 @@ public: bool isFetching() const { return mFetching; } + virtual bool replaceLocalTexture(const LLUUID& old_id, const LLUUID& new_id) override; + virtual void updateTextureTracking() override; + // Textures used for fetching/rendering LLPointer mBaseColorTexture; LLPointer mNormalTexture; diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index 6f1e4c9419..88de575f91 100644 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -46,6 +46,7 @@ #include /* 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 &mat : mGLTFMaterialWithLocalTextures) + { + mat->removeLocalTextureTracking(getTrackingID(), getWorldID()); + } + + mChangedSignal(getTrackingID(), getWorldID(), LLUUID()); + mChangedSignal.disconnect_all_slots(); + // delete self from gimagelist LLViewerFetchedTexture* image = gTextureList.findImage(mWorldID, TEX_LIST_STANDARD); gTextureList.deleteImage(image); @@ -278,6 +287,17 @@ boost::signals2::connection LLLocalBitmap::setChangedCallback(const LLLocalTextu return mChangedSignal.connect(cb); } +void LLLocalBitmap::addGLTFMaterial(LLGLTFMaterial* mat) +{ + if (mat + // dupplicate prevention + && mat->mLocalTextureTrackingIds.find(getTrackingID()) == mat->mLocalTextureTrackingIds.end()) + { + mat->addLocalTextureTracking(getTrackingID(), getWorldID()); + mGLTFMaterialWithLocalTextures.push_back(mat); + } +} + bool LLLocalBitmap::decodeBitmap(LLPointer rawimg) { bool decode_successful = false; @@ -355,7 +375,7 @@ void LLLocalBitmap::replaceIDs(const LLUUID& old_id, LLUUID new_id) return; } - mChangedSignal(old_id, new_id); + 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. @@ -389,8 +409,7 @@ void LLLocalBitmap::replaceIDs(const LLUUID& old_id, LLUUID new_id) updateUserLayers(old_id, new_id, LLWearableType::WT_UNDERPANTS); updateUserLayers(old_id, new_id, LLWearableType::WT_UNDERSHIRT); - // Go over any local material - + updateGLTFMaterials(old_id, new_id); } // this function sorts the faces from a getFaceList[getNumFaces] into a list of objects @@ -588,6 +607,24 @@ 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 + for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != mGLTFMaterialWithLocalTextures.end();) + { + if ((*it)->replaceLocalTexture(old_id, new_id)) + { + ++it; + } + else + { + // matching id not found, no longer in use + (*it)->removeLocalTextureTracking(getTrackingID(), new_id); + it = mGLTFMaterialWithLocalTextures.erase(it); + } + } +} + LLAvatarAppearanceDefines::ETextureIndex LLLocalBitmap::getTexIndex( LLWearableType::EType type, LLAvatarAppearanceDefines::EBakedTextureIndex baked_texind) { @@ -1089,6 +1126,18 @@ boost::signals2::connection LLLocalBitmapMgr::setOnChangedCallback(const LLUUID 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 f36fd6d320..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 { @@ -59,10 +60,12 @@ class LLLocalBitmap bool updateSelf(EUpdateType = UT_REGUPDATE); - typedef boost::signals2::signal 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 raw); @@ -71,6 +74,7 @@ class LLLocalBitmap 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 */ @@ -100,6 +104,11 @@ class LLLocalBitmap S32 mUpdateRetries; LLLocalTextureChangedSignal mChangedSignal; + // Store a list of accosiated materials + // Might be a better idea to hold this in LLGLTFMaterialList + typedef std::vector > mat_list_t; + mat_list_t mGLTFMaterialWithLocalTextures; + }; class LLLocalBitmapTimer : public LLEventTimer @@ -130,6 +139,7 @@ public: 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(); diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 63d86cda61..b8e34b7409 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -363,6 +363,15 @@ LLMaterialEditor::LLMaterialEditor(const LLSD& key) } } +LLMaterialEditor::~LLMaterialEditor() +{ + for (mat_connection_map_t::value_type cn : mTextureChangesUpdates) + { + cn.second.mConnection.disconnect(); + } + mTextureChangesUpdates.clear(); +} + void LLMaterialEditor::setObjectID(const LLUUID& object_id) { LLPreview::setObjectID(object_id); @@ -532,11 +541,6 @@ void LLMaterialEditor::onClose(bool app_quitting) mSelectionUpdateSlot.disconnect(); } - for (boost::signals2::connection& cn : mTextureChangesUpdates) - { - cn.disconnect(); - } - LLPreview::onClose(app_quitting); } @@ -866,7 +870,27 @@ void LLMaterialEditor::setEnableEditing(bool can_modify) mNormalTextureCtrl->setEnabled(can_modify); } -void LLMaterialEditor::replaceTexture(const LLUUID& old_id, const LLUUID& new_id) +void LLMaterialEditor::subscribeToLocalTexture(S32 dirty_flag, const LLUUID& tracking_id) +{ + LocalTextureConnection info; + info.mTrackingId = tracking_id; + info.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); + } + }); + mTextureChangesUpdates[dirty_flag] = info; +} + +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 @@ -958,18 +982,17 @@ void LLMaterialEditor::onCommitTexture(LLUICtrl* ctrl, const LLSD& data, S32 dir childSetValue(upload_fee_ctrl_name, getString("no_upload_fee_string")); } + // unsubcribe potential old callabck + mat_connection_map_t::iterator found = mTextureChangesUpdates.find(dirty_flag); + if (found != mTextureChangesUpdates.end()) + { + found->second.mConnection.disconnect(); + } + LLTextureCtrl* tex_ctrl = (LLTextureCtrl*)ctrl; if (tex_ctrl->isImageLocal()) { - // Theoretically LLSD should be smart enough to not need this, but for extra safety - LLSD key = llsd_clone(getKey()); - // Subscribe material editor to local texture updates - mTextureChangesUpdates.push_back( - LLLocalBitmapMgr::getInstance()->setOnChangedCallback(tex_ctrl->getLocalTrackingID(), - [this](const LLUUID &old_id, const LLUUID& new_id) - { - replaceTexture(old_id, new_id); - })); + subscribeToLocalTexture(dirty_flag, tex_ctrl->getLocalTrackingID()); } } @@ -988,9 +1011,8 @@ void update_local_texture(LLUICtrl* ctrl, LLGLTFMaterial* mat) LLTextureCtrl* tex_ctrl = (LLTextureCtrl*)ctrl; if (tex_ctrl->isImageLocal()) { - mat->setHasLocalTextures(true); - // Todo: subscrive material for an update - // tex_ctrl->getLocalTrackingID(); + // subscrive material to updates of local textures + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tex_ctrl->getLocalTrackingID(), mat); } } @@ -1465,6 +1487,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); + } + } + } } } @@ -1479,6 +1515,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); + } + } } } @@ -1512,6 +1558,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) @@ -2975,6 +3032,34 @@ void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat) setDoubleSided(mat->mDoubleSided); setAlphaMode(mat->getAlphaMode()); setAlphaCutoff(mat->mAlphaCutoff); + + + for (mat_connection_map_t::value_type cn : mTextureChangesUpdates) + { + cn.second.mConnection.disconnect(); + } + mTextureChangesUpdates.clear(); + + for (const LLUUID& tracking_id : mat->mLocalTextureTrackingIds) + { + LLUUID world_id = LLLocalBitmapMgr::getInstance()->getWorldID(tracking_id); + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]) + { + subscribeToLocalTexture(MATERIAL_BASE_COLOR_TEX_DIRTY, tracking_id); + } + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]) + { + subscribeToLocalTexture(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY, tracking_id); + } + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]) + { + subscribeToLocalTexture(MATERIAL_EMISIVE_TEX_DIRTY, tracking_id); + } + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]) + { + subscribeToLocalTexture(MATERIAL_NORMAL_TEX_DIRTY, tracking_id); + } + } } bool LLMaterialEditor::setFromSelection() diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index 4af68adce2..fd8b259a1a 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); @@ -219,7 +220,8 @@ class LLMaterialEditor : public LLPreview, public LLVOInventoryListener void setCanSave(bool value); void setEnableEditing(bool can_modify); - void replaceTexture(const LLUUID& old_id, const LLUUID& new_id); // Local texture support + 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); @@ -307,6 +309,13 @@ private: static bool mOverrideInProgress; static bool mSelectionNeedsUpdate; boost::signals2::connection mSelectionUpdateSlot; - std::list mTextureChangesUpdates; + + struct LocalTextureConnection + { + LLUUID mTrackingId; + boost::signals2::connection mConnection; + }; + typedef std::map mat_connection_map_t; + mat_connection_map_t mTextureChangesUpdates; }; -- cgit v1.2.3 From 3a5b678eba5d86acccb1a1f233f862d292258fac Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 30 Oct 2023 23:56:33 +0200 Subject: SL-20523 Local textures not updating on PBR Materials #3 --- indra/llprimitive/llgltfmaterial.cpp | 9 ++++++ indra/llprimitive/llgltfmaterial.h | 5 ++-- indra/newview/lllocalbitmaps.cpp | 26 +++++++++++++++- indra/newview/llmaterialeditor.cpp | 58 +++++++++++++++++++----------------- 4 files changed, 68 insertions(+), 30 deletions(-) diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index 6afd83904f..e590b14656 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -770,6 +770,15 @@ LLUUID LLGLTFMaterial::getHash() const return hash; } +void LLGLTFMaterial::addTextureEntry(LLTextureEntry* te) +{ + mTextureEntires.insert(te); +} +void LLGLTFMaterial::removeTextureEntry(LLTextureEntry* te) +{ + mTextureEntires.erase(te); +} + void LLGLTFMaterial::addLocalTextureTracking(const LLUUID& tracking_id, const LLUUID& tex_id) { mLocalTextureTrackingIds.insert(tracking_id); diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index d45ada1561..2a9ef3ffe0 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -219,8 +219,8 @@ public: // 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) {}; + 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); @@ -231,6 +231,7 @@ public: uuid_set_t mLocalTextureIds; uuid_set_t mLocalTextureTrackingIds; + std::set mTextureEntires; protected: static LLVector2 vec2FromJson(const std::map& object, const char* key, const LLVector2& default_value); diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index 88de575f91..6775685a6a 100644 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -614,6 +614,30 @@ void LLLocalBitmap::updateGLTFMaterials(LLUUID old_id, LLUUID new_id) { if ((*it)->replaceLocalTexture(old_id, new_id)) { + for (LLTextureEntry* entry : (*it)->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(entry->getGLTFRenderMaterial()) != nullptr); + LLFetchedGLTFMaterial *fetched_mat = dynamic_cast((*it).get()); + if (fetched_mat) + { + *render_mat = *fetched_mat; + } + render_mat->applyOverride(*override_mat); + } + } + } ++it; } else @@ -1119,7 +1143,7 @@ boost::signals2::connection LLLocalBitmapMgr::setOnChangedCallback(const LLUUID LLLocalBitmap* unit = *iter; if (unit->getTrackingID() == tracking_id) { - unit->setChangedCallback(cb); + return unit->setChangedCallback(cb); } } diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index b8e34b7409..836ea5c869 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -365,11 +365,6 @@ LLMaterialEditor::LLMaterialEditor(const LLSD& key) LLMaterialEditor::~LLMaterialEditor() { - for (mat_connection_map_t::value_type cn : mTextureChangesUpdates) - { - cn.second.mConnection.disconnect(); - } - mTextureChangesUpdates.clear(); } void LLMaterialEditor::setObjectID(const LLUUID& object_id) @@ -540,6 +535,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); } @@ -872,22 +872,24 @@ void LLMaterialEditor::setEnableEditing(bool can_modify) void LLMaterialEditor::subscribeToLocalTexture(S32 dirty_flag, const LLUUID& tracking_id) { - LocalTextureConnection info; - info.mTrackingId = tracking_id; - info.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); - } - }); - mTextureChangesUpdates[dirty_flag] = info; + 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); + } + }); + } } void LLMaterialEditor::replaceLocalTexture(const LLUUID& old_id, const LLUUID& new_id) @@ -981,19 +983,21 @@ void LLMaterialEditor::onCommitTexture(LLUICtrl* ctrl, const LLSD& data, S32 dir // the texture that is not in use childSetValue(upload_fee_ctrl_name, getString("no_upload_fee_string")); } + } + 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(); } - - LLTextureCtrl* tex_ctrl = (LLTextureCtrl*)ctrl; - if (tex_ctrl->isImageLocal()) - { - subscribeToLocalTexture(dirty_flag, tex_ctrl->getLocalTrackingID()); - } } markChangesUnsaved(dirty_flag); -- cgit v1.2.3 From 52c60ab3fdb8617471eccd9df52cc126e0243e76 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 2 Nov 2023 00:33:39 +0200 Subject: SL-20523 Local textures not updating on PBR Materials #4 --- indra/llprimitive/llgltfmaterial.cpp | 27 ++++---- indra/llprimitive/llgltfmaterial.h | 12 ++-- indra/newview/llfetchedgltfmaterial.cpp | 23 ++++++- indra/newview/llfetchedgltfmaterial.h | 3 +- indra/newview/lllocalbitmaps.cpp | 23 ++++--- indra/newview/llmaterialeditor.cpp | 115 ++++++++++++++++++++++++++++---- indra/newview/llmaterialeditor.h | 1 + indra/newview/llviewerobject.cpp | 8 +++ 8 files changed, 167 insertions(+), 45 deletions(-) diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index e590b14656..3945be3254 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -89,8 +89,7 @@ LLGLTFMaterial& LLGLTFMaterial::operator=(const LLGLTFMaterial& rhs) mOverrideDoubleSided = rhs.mOverrideDoubleSided; mOverrideAlphaMode = rhs.mOverrideAlphaMode; - mLocalTextureIds = rhs.mLocalTextureIds; - mLocalTextureTrackingIds = rhs.mLocalTextureTrackingIds; + mTrackingIdToLocalTexture = rhs.mTrackingIdToLocalTexture; updateTextureTracking(); @@ -606,6 +605,8 @@ 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()); } void LLGLTFMaterial::getOverrideLLSD(const LLGLTFMaterial& override_mat, LLSD& data) @@ -781,17 +782,15 @@ void LLGLTFMaterial::removeTextureEntry(LLTextureEntry* te) void LLGLTFMaterial::addLocalTextureTracking(const LLUUID& tracking_id, const LLUUID& tex_id) { - mLocalTextureTrackingIds.insert(tracking_id); - mLocalTextureIds.insert(tex_id); + mTrackingIdToLocalTexture[tracking_id] = tex_id; } -void LLGLTFMaterial::removeLocalTextureTracking(const LLUUID& tracking_id, const LLUUID& tex_id) +void LLGLTFMaterial::removeLocalTextureTracking(const LLUUID& tracking_id) { - mLocalTextureTrackingIds.erase(tracking_id); - mLocalTextureIds.erase(tex_id); + mTrackingIdToLocalTexture.erase(tracking_id); } -bool LLGLTFMaterial::replaceLocalTexture(const LLUUID& old_id, const LLUUID& new_id) +bool LLGLTFMaterial::replaceLocalTexture(const LLUUID& tracking_id, const LLUUID& old_id, const LLUUID& new_id) { bool res = false; @@ -804,10 +803,13 @@ bool LLGLTFMaterial::replaceLocalTexture(const LLUUID& old_id, const LLUUID& new } } - mLocalTextureIds.erase(old_id); if (res) { - mLocalTextureIds.insert(new_id); + mTrackingIdToLocalTexture[tracking_id] = new_id; + } + else + { + mTrackingIdToLocalTexture.erase(tracking_id); } return res; @@ -815,8 +817,5 @@ bool LLGLTFMaterial::replaceLocalTexture(const LLUUID& old_id, const LLUUID& new void LLGLTFMaterial::updateTextureTracking() { - if (mLocalTextureTrackingIds.size() > 0) - { - LL_WARNS() << "copied a material with local textures, but tracking not implemented" << LL_ENDL; - } + // setTEGLTFMaterialOverride is responsible for tracking } diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index 2a9ef3ffe0..7b38663307 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); @@ -224,13 +224,13 @@ public: // 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, const LLUUID& tex_id); - bool hasLocalTextures() { return !mLocalTextureIds.empty(); } - virtual bool replaceLocalTexture(const LLUUID &old_id, const LLUUID& new_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(); - uuid_set_t mLocalTextureIds; - uuid_set_t mLocalTextureTrackingIds; + typedef std::map local_tex_map_t; + local_tex_map_t mTrackingIdToLocalTexture; std::set mTextureEntires; protected: diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp index 71a961ce49..c61b25f0a2 100644 --- a/indra/newview/llfetchedgltfmaterial.cpp +++ b/indra/newview/llfetchedgltfmaterial.cpp @@ -155,7 +155,14 @@ LLViewerFetchedTexture* fetch_texture(const LLUUID& id) return img; }; -bool LLFetchedGLTFMaterial::replaceLocalTexture(const LLUUID& old_id, const LLUUID& new_id) +void LLFetchedGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat) +{ + LLGLTFMaterial::applyOverride(override_mat); + + updateTextureTracking(); +} + +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) @@ -182,14 +189,24 @@ bool LLFetchedGLTFMaterial::replaceLocalTexture(const LLUUID& old_id, const LLUU mEmissiveTexture = fetch_texture(new_id); res = true; } + + if (res) + { + mTrackingIdToLocalTexture[tracking_id] = new_id; + } + else + { + mTrackingIdToLocalTexture.erase(tracking_id); + } + return res; } void LLFetchedGLTFMaterial::updateTextureTracking() { - for (const LLUUID& id : mLocalTextureTrackingIds) + for (local_tex_map_t::value_type val : mTrackingIdToLocalTexture) { - LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(id, this); + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.first, this); } } diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h index 02426bf088..d778966c22 100644 --- a/indra/newview/llfetchedgltfmaterial.h +++ b/indra/newview/llfetchedgltfmaterial.h @@ -50,7 +50,8 @@ public: bool isFetching() const { return mFetching; } - virtual bool replaceLocalTexture(const LLUUID& old_id, const LLUUID& new_id) override; + void applyOverride(const LLGLTFMaterial& override_mat) 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 diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index 6775685a6a..cd5b2e262b 100644 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -134,7 +134,7 @@ LLLocalBitmap::~LLLocalBitmap() for (LLPointer &mat : mGLTFMaterialWithLocalTextures) { - mat->removeLocalTextureTracking(getTrackingID(), getWorldID()); + mat->removeLocalTextureTracking(getTrackingID()); } mChangedSignal(getTrackingID(), getWorldID(), LLUUID()); @@ -289,12 +289,17 @@ boost::signals2::connection LLLocalBitmap::setChangedCallback(const LLLocalTextu void LLLocalBitmap::addGLTFMaterial(LLGLTFMaterial* mat) { - if (mat - // dupplicate prevention - && mat->mLocalTextureTrackingIds.find(getTrackingID()) == mat->mLocalTextureTrackingIds.end()) + if (!mat) { - mat->addLocalTextureTracking(getTrackingID(), getWorldID()); - mGLTFMaterialWithLocalTextures.push_back(mat); + return; + } + for (mat_list_t::value_type ptr : mGLTFMaterialWithLocalTextures) + { + if (ptr.get() != mat) + { + mat->addLocalTextureTracking(getTrackingID(), getWorldID()); + mGLTFMaterialWithLocalTextures.push_back(mat); + } } } @@ -612,7 +617,7 @@ void LLLocalBitmap::updateGLTFMaterials(LLUUID old_id, LLUUID new_id) // Might be a better idea to hold this in LLGLTFMaterialList for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != mGLTFMaterialWithLocalTextures.end();) { - if ((*it)->replaceLocalTexture(old_id, new_id)) + if ((*it)->replaceLocalTexture(mTrackingID, old_id, new_id)) { for (LLTextureEntry* entry : (*it)->mTextureEntires) { @@ -642,8 +647,8 @@ void LLLocalBitmap::updateGLTFMaterials(LLUUID old_id, LLUUID new_id) } else { - // matching id not found, no longer in use - (*it)->removeLocalTextureTracking(getTrackingID(), new_id); + // Matching id not found, no longer in use + // material would clean itself, remove from the list it = mGLTFMaterialWithLocalTextures.erase(it); } } diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 836ea5c869..1b606b0311 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -892,6 +892,16 @@ void LLMaterialEditor::subscribeToLocalTexture(S32 dirty_flag, const LLUUID& tra } } +LLUUID LLMaterialEditor::getLocalTextureTrackingIdFromFlag(U32 flag) +{ + mat_connection_map_t::iterator found = mTextureChangesUpdates.find(flag); + if (found != mTextureChangesUpdates.end()) + { + return found->second.mTrackingId; + } + return LLUUID(); +} + void LLMaterialEditor::replaceLocalTexture(const LLUUID& old_id, const LLUUID& new_id) { // todo: might be a good idea to set mBaseColorTextureUploadId here @@ -2827,28 +2837,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) @@ -2881,10 +2921,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) @@ -3044,24 +3094,65 @@ void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat) } mTextureChangesUpdates.clear(); - for (const LLUUID& tracking_id : mat->mLocalTextureTrackingIds) + if (mat->hasLocalTextures()) { - LLUUID world_id = LLLocalBitmapMgr::getInstance()->getWorldID(tracking_id); - if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]) - { - subscribeToLocalTexture(MATERIAL_BASE_COLOR_TEX_DIRTY, tracking_id); - } - if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]) + for (mat_connection_map_t::value_type cn : mTextureChangesUpdates) { - subscribeToLocalTexture(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY, tracking_id); + cn.second.mConnection.disconnect(); } - if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]) + mTextureChangesUpdates.clear(); + + for (LLGLTFMaterial::local_tex_map_t::value_type val : mat->mTrackingIdToLocalTexture) { - subscribeToLocalTexture(MATERIAL_EMISIVE_TEX_DIRTY, tracking_id); + 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); + } } - if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]) + } + else + { + for (mat_connection_map_t::value_type cn : mTextureChangesUpdates) { - subscribeToLocalTexture(MATERIAL_NORMAL_TEX_DIRTY, tracking_id); + 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); + continue; + } + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); + continue; + } + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); + continue; + } + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); + continue; + } + cn.second.mConnection.disconnect(); } } } diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index fd8b259a1a..e6939098e0 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -231,6 +231,7 @@ class LLMaterialEditor : public LLPreview, public LLVOInventoryListener U32 getUnsavedChangesFlags() { return mUnsavedChanges; } U32 getRevertedChangesFlags() { return mRevertedChanges; } + LLUUID getLocalTextureTrackingIdFromFlag(U32 flag); static bool capabilitiesAvailable(); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 3b5b986725..8228775596 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -5482,6 +5482,14 @@ S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_ma } } + if (retval == TEM_CHANGE_TEXTURE) + { + for (LLGLTFMaterial::local_tex_map_t::value_type val : override_mat->mTrackingIdToLocalTexture) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.first, override_mat); + } + } + return retval; } -- cgit v1.2.3 From 0d8893822d8975194313e940914afc8945754a21 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 2 Nov 2023 23:49:55 +0200 Subject: SL-20523 Local textures not updating on PBR Materials #5 --- indra/llprimitive/llgltfmaterial.cpp | 12 +-- indra/llprimitive/llgltfmaterial.h | 6 +- indra/newview/llfetchedgltfmaterial.cpp | 19 +++-- indra/newview/llfetchedgltfmaterial.h | 5 +- indra/newview/lllocalbitmaps.cpp | 69 +++++++++++------ indra/newview/lllocalgltfmaterials.cpp | 9 --- indra/newview/lllocalgltfmaterials.h | 4 - indra/newview/llmaterialeditor.cpp | 130 +++++++++++++++++++++----------- indra/newview/llmaterialeditor.h | 1 + indra/newview/llviewerobject.cpp | 13 ++-- 10 files changed, 158 insertions(+), 110 deletions(-) diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index 3945be3254..390110b0ec 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -607,6 +607,8 @@ void LLGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat) } mTrackingIdToLocalTexture.insert(override_mat.mTrackingIdToLocalTexture.begin(), override_mat.mTrackingIdToLocalTexture.begin()); + + updateTextureTracking(); } void LLGLTFMaterial::getOverrideLLSD(const LLGLTFMaterial& override_mat, LLSD& data) @@ -771,15 +773,6 @@ LLUUID LLGLTFMaterial::getHash() const return hash; } -void LLGLTFMaterial::addTextureEntry(LLTextureEntry* te) -{ - mTextureEntires.insert(te); -} -void LLGLTFMaterial::removeTextureEntry(LLTextureEntry* te) -{ - mTextureEntires.erase(te); -} - void LLGLTFMaterial::addLocalTextureTracking(const LLUUID& tracking_id, const LLUUID& tex_id) { mTrackingIdToLocalTexture[tracking_id] = tex_id; @@ -818,4 +811,5 @@ bool LLGLTFMaterial::replaceLocalTexture(const LLUUID& tracking_id, const LLUUID 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 7b38663307..02f62fb08c 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -219,8 +219,8 @@ public: // 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); + 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); @@ -229,9 +229,9 @@ public: 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 local_tex_map_t; local_tex_map_t mTrackingIdToLocalTexture; - std::set mTextureEntires; protected: static LLVector2 vec2FromJson(const std::map& object, const char* key, const LLVector2& default_value); diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp index c61b25f0a2..a47b52fddc 100644 --- a/indra/newview/llfetchedgltfmaterial.cpp +++ b/indra/newview/llfetchedgltfmaterial.cpp @@ -155,13 +155,6 @@ LLViewerFetchedTexture* fetch_texture(const LLUUID& id) return img; }; -void LLFetchedGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat) -{ - LLGLTFMaterial::applyOverride(override_mat); - - updateTextureTracking(); -} - bool LLFetchedGLTFMaterial::replaceLocalTexture(const LLUUID& tracking_id, const LLUUID& old_id, const LLUUID& new_id) { bool res = false; @@ -202,9 +195,19 @@ bool LLFetchedGLTFMaterial::replaceLocalTexture(const LLUUID& tracking_id, const 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) + for (local_tex_map_t::value_type &val : mTrackingIdToLocalTexture) { LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.first, this); } diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h index d778966c22..2559aa46cc 100644 --- a/indra/newview/llfetchedgltfmaterial.h +++ b/indra/newview/llfetchedgltfmaterial.h @@ -50,7 +50,8 @@ public: bool isFetching() const { return mFetching; } - void applyOverride(const LLGLTFMaterial& override_mat) override; + 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; @@ -60,6 +61,8 @@ public: LLPointer mMetallicRoughnessTexture; LLPointer mEmissiveTexture; + std::set mTextureEntires; + protected: // Lifetime management diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index cd5b2e262b..4121df4bac 100644 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -293,14 +293,28 @@ void LLLocalBitmap::addGLTFMaterial(LLGLTFMaterial* mat) { return; } - for (mat_list_t::value_type ptr : mGLTFMaterialWithLocalTextures) + + mat_list_t::iterator end = mGLTFMaterialWithLocalTextures.end(); + for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != end;) { - if (ptr.get() != mat) + if (it->get() == mat) + { + return; + } + + if ((*it)->getNumRefs() == 1) + { + it = mGLTFMaterialWithLocalTextures.erase(it); + end = mGLTFMaterialWithLocalTextures.end(); + } + else { - mat->addLocalTextureTracking(getTrackingID(), getWorldID()); - mGLTFMaterialWithLocalTextures.push_back(mat); + it++; } } + + mat->addLocalTextureTracking(getTrackingID(), getWorldID()); + mGLTFMaterialWithLocalTextures.push_back(mat); } bool LLLocalBitmap::decodeBitmap(LLPointer rawimg) @@ -615,31 +629,41 @@ 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 - for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != mGLTFMaterialWithLocalTextures.end();) + mat_list_t::iterator end = mGLTFMaterialWithLocalTextures.end(); + for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != end;) { - if ((*it)->replaceLocalTexture(mTrackingID, old_id, new_id)) + 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)) { - for (LLTextureEntry* entry : (*it)->mTextureEntires) + LLFetchedGLTFMaterial* fetched_mat = dynamic_cast((*it).get()); + if (fetched_mat) { - // 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) + for (LLTextureEntry* entry : fetched_mat->mTextureEntires) { - // do not create a new material, reuse existing pointer - LLFetchedGLTFMaterial* render_mat = (LLFetchedGLTFMaterial*)entry->getGLTFRenderMaterial(); - if (render_mat) + // 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) { - llassert(dynamic_cast(entry->getGLTFRenderMaterial()) != nullptr); - LLFetchedGLTFMaterial *fetched_mat = dynamic_cast((*it).get()); - if (fetched_mat) + // do not create a new material, reuse existing pointer + LLFetchedGLTFMaterial* render_mat = (LLFetchedGLTFMaterial*)entry->getGLTFRenderMaterial(); + if (render_mat) { - *render_mat = *fetched_mat; + llassert(dynamic_cast(entry->getGLTFRenderMaterial()) != nullptr); + { + *render_mat = *fetched_mat; + } + render_mat->applyOverride(*override_mat); } - render_mat->applyOverride(*override_mat); } } } @@ -650,6 +674,7 @@ void LLLocalBitmap::updateGLTFMaterials(LLUUID old_id, LLUUID new_id) // Matching id not found, no longer in use // material would clean itself, remove from the list it = mGLTFMaterialWithLocalTextures.erase(it); + end = mGLTFMaterialWithLocalTextures.end(); } } } 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 mTextureEntires; }; class LLLocalGLTFMaterialTimer : public LLEventTimer diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 1b606b0311..7d1ac32282 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -343,6 +343,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 ///---------------------------------------------------------------------------- @@ -535,7 +568,7 @@ void LLMaterialEditor::onClose(bool app_quitting) { mSelectionUpdateSlot.disconnect(); } - for (mat_connection_map_t::value_type cn : mTextureChangesUpdates) + for (mat_connection_map_t::value_type &cn : mTextureChangesUpdates) { cn.second.mConnection.disconnect(); } @@ -902,6 +935,45 @@ LLUUID LLMaterialEditor::getLocalTextureTrackingIdFromFlag(U32 flag) 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 @@ -1509,7 +1581,7 @@ void LLMaterialEditor::finishInventoryUpload(LLUUID itemId, LLUUID newAssetId, L { // 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) + for (mat_connection_map_t::value_type &val : me->mTextureChangesUpdates) { LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.second.mTrackingId, mat); } @@ -1534,7 +1606,7 @@ void LLMaterialEditor::finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID { // 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) + for (mat_connection_map_t::value_type &val : me->mTextureChangesUpdates) { LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.second.mTrackingId, mat); } @@ -1578,7 +1650,7 @@ void LLMaterialEditor::finishSaveAs( { // 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) + for (mat_connection_map_t::value_type &val : me->mTextureChangesUpdates) { LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.second.mTrackingId, mat); } @@ -3087,22 +3159,9 @@ void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat) setAlphaMode(mat->getAlphaMode()); setAlphaCutoff(mat->mAlphaCutoff); - - for (mat_connection_map_t::value_type cn : mTextureChangesUpdates) - { - cn.second.mConnection.disconnect(); - } - mTextureChangesUpdates.clear(); - if (mat->hasLocalTextures()) { - for (mat_connection_map_t::value_type cn : mTextureChangesUpdates) - { - cn.second.mConnection.disconnect(); - } - mTextureChangesUpdates.clear(); - - for (LLGLTFMaterial::local_tex_map_t::value_type val : mat->mTrackingIdToLocalTexture) + for (LLGLTFMaterial::local_tex_map_t::value_type &val : mat->mTrackingIdToLocalTexture) { LLUUID world_id = LLLocalBitmapMgr::getInstance()->getWorldID(val.first); if (val.second != world_id) @@ -3127,34 +3186,6 @@ void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat) } } } - else - { - 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); - continue; - } - if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]) - { - LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); - continue; - } - if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]) - { - LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); - continue; - } - if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]) - { - LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); - continue; - } - cn.second.mConnection.disconnect(); - } - } } bool LLMaterialEditor::setFromSelection() @@ -3173,6 +3204,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 { @@ -3195,6 +3228,11 @@ 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 + 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 e6939098e0..95a4c4572d 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -232,6 +232,7 @@ 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(); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 8228775596..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)) { @@ -5482,14 +5487,6 @@ S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_ma } } - if (retval == TEM_CHANGE_TEXTURE) - { - for (LLGLTFMaterial::local_tex_map_t::value_type val : override_mat->mTrackingIdToLocalTexture) - { - LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.first, override_mat); - } - } - return retval; } -- cgit v1.2.3 From cc089d88ad5ab9088a5036e1d6f301d87cb3b127 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 3 Nov 2023 21:07:46 +0200 Subject: SL-20523 Ensure override gets updated before render material --- indra/llprimitive/llgltfmaterial.cpp | 4 +++ indra/newview/llfetchedgltfmaterial.cpp | 8 +++++ indra/newview/lllocalbitmaps.cpp | 60 +++++++++++++++++++-------------- indra/newview/llmaterialeditor.cpp | 4 +++ 4 files changed, 50 insertions(+), 26 deletions(-) diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index 390110b0ec..d2c911a189 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -794,6 +794,10 @@ bool LLGLTFMaterial::replaceLocalTexture(const LLUUID& tracking_id, const LLUUID mTextureId[i] = new_id; res = true; } + else if (mTextureId[i] == new_id) + { + res = true; + } } if (res) diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp index a47b52fddc..1a47293523 100644 --- a/indra/newview/llfetchedgltfmaterial.cpp +++ b/indra/newview/llfetchedgltfmaterial.cpp @@ -183,6 +183,14 @@ bool LLFetchedGLTFMaterial::replaceLocalTexture(const LLUUID& tracking_id, const 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; diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index 4121df4bac..5a5fb7474c 100644 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -641,41 +641,49 @@ void LLLocalBitmap::updateGLTFMaterials(LLUUID old_id, LLUUID new_id) } else if ((*it)->replaceLocalTexture(mTrackingID, old_id, new_id)) { - LLFetchedGLTFMaterial* fetched_mat = dynamic_cast((*it).get()); - if (fetched_mat) + 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((*it).get()); + if (fetched_mat) + { + for (LLTextureEntry* entry : fetched_mat->mTextureEntires) { - 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) { - // 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) { - // do not create a new material, reuse existing pointer - LLFetchedGLTFMaterial* render_mat = (LLFetchedGLTFMaterial*)entry->getGLTFRenderMaterial(); - if (render_mat) + llassert(dynamic_cast(entry->getGLTFRenderMaterial()) != nullptr); { - llassert(dynamic_cast(entry->getGLTFRenderMaterial()) != nullptr); - { - *render_mat = *fetched_mat; - } - render_mat->applyOverride(*override_mat); + *render_mat = *fetched_mat; } + render_mat->applyOverride(*override_mat); } } } - ++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(); } + ++it; } } diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 7d1ac32282..11a528314e 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -3231,6 +3231,10 @@ bool LLMaterialEditor::setFromSelection() // 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); } -- cgit v1.2.3 From afa45530f745af8c9d595948ac957b12664cca2c Mon Sep 17 00:00:00 2001 From: Brad Linden Date: Fri, 3 Nov 2023 13:09:54 -0700 Subject: SL-19968 disabled pump_idle_network for now due to it causing several failures during login also added suggested continue statements, and removed obsolete LLInventoryItem::fromLLSD deserialization codepath. --- indra/llinventory/llinventory.cpp | 173 ++++--------------------------------- indra/newview/llinventorymodel.cpp | 15 ++-- 2 files changed, 26 insertions(+), 162 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: - asset_id - acc0ec86 - 17f2 - 4b92 - ab41 - 6718b1f755f7 - perms - 8 - service - 3 - version - 1 - */ - } - 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(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(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) version 1 */ - } + 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(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(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/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 74a5442586..8583cca103 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -3342,7 +3342,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 parser = new LLSDNotationParser(); while (std::getline(file, line)) @@ -3408,12 +3408,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(); -- cgit v1.2.3 From 843866d193a0fb5ea882408c8862335ab9c5539b Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Mon, 13 Nov 2023 13:12:48 -0600 Subject: Drtvwr 596 11/8/2023 (#501) * SL-20570 Fix for lossy (and square) normal maps when importing GLTF materials. * SL-20582 Fix for overriding to alpha mode blend not working. Incidental decruft of dead code (thanks, Rye!) --- indra/llprimitive/llgltfmaterial.cpp | 1 + indra/llprimitive/llprimitive.cpp | 36 ------------------------------------ indra/llprimitive/llprimitive.h | 5 +---- indra/newview/llmaterialeditor.cpp | 14 +++----------- 4 files changed, 5 insertions(+), 51 deletions(-) diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index d2c911a189..ae165f7fa4 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -723,6 +723,7 @@ void LLGLTFMaterial::applyOverrideLLSD(const LLSD& data) if (am.isInteger()) { mAlphaMode = (AlphaMode) am.asInteger(); + mOverrideAlphaMode = true; } const LLSD& ac = data["ac"]; diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 350d84ae6c..904747af2d 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -2376,42 +2376,6 @@ void LLRenderMaterialParams::copy(const LLNetworkData& data) mEntries = param.mEntries; } -LLSD LLRenderMaterialParams::asLLSD() const -{ - 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.isArray()) - { - 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(U8 te, const LLUUID& id) { diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index d2adfa4a3d..0b7dbd703a 100644 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -382,10 +382,7 @@ public: 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(U8 te_idx, const LLUUID& id); const LLUUID& getMaterial(U8 te_idx) const; diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 11a528314e..a5437f7a88 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1840,17 +1840,9 @@ static void pack_textures( if (normal_img) { - normal_j2c = LLViewerTextureList::convertToUploadFile(normal_img); - - LLPointer test; - test = LLViewerTextureList::convertToUploadFile(normal_img, 1024, true); - - S32 lossy_bytes = normal_j2c->getDataSize(); - S32 lossless_bytes = test->getDataSize(); - - LL_DEBUGS("MaterialEditor") << llformat("Lossless vs Lossy: (%d/%d) = %.2f", lossless_bytes, lossy_bytes, (F32)lossless_bytes / lossy_bytes) << LL_ENDL; - - normal_j2c = test; + // create a losslessly compressed version of the normal map + normal_j2c = LLViewerTextureList::convertToUploadFile(normal_img, 1024, false, true); + LL_DEBUGS("MaterialEditor") << "Normal: " << normal_j2c->getDataSize() << LL_ENDL; } if (mr_img) -- cgit v1.2.3