summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2023-10-27 23:41:13 +0300
committerakleshchev <117672381+akleshchev@users.noreply.github.com>2023-11-06 18:29:42 +0200
commit596a63051ebabfec51e48be02bbec33ab962d915 (patch)
tree97e564e2714d2d819b547c03d15049fbdf7d19d6 /indra/newview
parentdc63dfc0dd6554f5f45b1d80bd4cb9258eefee95 (diff)
SL-20523 Local textures not updating on PBR Materials #2
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llfetchedgltfmaterial.cpp49
-rw-r--r--indra/newview/llfetchedgltfmaterial.h3
-rw-r--r--indra/newview/lllocalbitmaps.cpp55
-rw-r--r--indra/newview/lllocalbitmaps.h12
-rw-r--r--indra/newview/llmaterialeditor.cpp121
-rw-r--r--indra/newview/llmaterialeditor.h13
6 files changed, 229 insertions, 24 deletions
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<LLViewerFetchedTexture> mBaseColorTexture;
LLPointer<LLViewerFetchedTexture> 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 <ctime>
/* misc headers */
+#include "llgltfmaterial.h"
#include "llscrolllistctrl.h"
#include "lllocaltextureobject.h"
#include "llviewertexturelist.h"
@@ -131,6 +132,14 @@ LLLocalBitmap::~LLLocalBitmap()
LLLocalBitmapMgr::getInstance()->doRebake();
}
+ for (LLPointer<LLGLTFMaterial> &mat : mGLTFMaterialWithLocalTextures)
+ {
+ mat->removeLocalTextureTracking(getTrackingID(), 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<LLImageRaw> 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<void(const LLUUID& old_id,
+ typedef boost::signals2::signal<void(const LLUUID& tracking_id,
+ const LLUUID& old_id,
const LLUUID& new_id)> LLLocalTextureChangedSignal;
typedef LLLocalTextureChangedSignal::slot_type LLLocalTextureCallback;
boost::signals2::connection setChangedCallback(const LLLocalTextureCallback& cb);
+ void addGLTFMaterial(LLGLTFMaterial* mat);
private: /* self update private section */
bool decodeBitmap(LLPointer<LLImageRaw> raw);
@@ -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<LLPointer<LLGLTFMaterial> > 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 <boost::signals2::connection> mTextureChangesUpdates;
+
+ struct LocalTextureConnection
+ {
+ LLUUID mTrackingId;
+ boost::signals2::connection mConnection;
+ };
+ typedef std::map<S32, LocalTextureConnection> mat_connection_map_t;
+ mat_connection_map_t mTextureChangesUpdates;
};