SL-20523 Local textures not updating on PBR Materials #4

master
Andrey Kleshchev 2023-11-02 00:33:39 +02:00 committed by akleshchev
parent 3a5b678eba
commit 52c60ab3fd
8 changed files with 167 additions and 45 deletions

View File

@ -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
}

View File

@ -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<LLUUID, LLUUID> local_tex_map_t;
local_tex_map_t mTrackingIdToLocalTexture;
std::set<LLTextureEntry*> mTextureEntires;
protected:

View File

@ -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);
}
}

View File

@ -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

View File

@ -134,7 +134,7 @@ LLLocalBitmap::~LLLocalBitmap()
for (LLPointer<LLGLTFMaterial> &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);
}
}

View File

@ -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])
for (mat_connection_map_t::value_type cn : mTextureChangesUpdates)
{
subscribeToLocalTexture(MATERIAL_BASE_COLOR_TEX_DIRTY, tracking_id);
cn.second.mConnection.disconnect();
}
if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS])
mTextureChangesUpdates.clear();
for (LLGLTFMaterial::local_tex_map_t::value_type val : mat->mTrackingIdToLocalTexture)
{
subscribeToLocalTexture(MATERIAL_METALLIC_ROUGHTNESS_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_EMISSIVE])
}
else
{
for (mat_connection_map_t::value_type cn : mTextureChangesUpdates)
{
subscribeToLocalTexture(MATERIAL_EMISIVE_TEX_DIRTY, tracking_id);
}
if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL])
{
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();
}
}
}

View File

@ -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();

View File

@ -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;
}