summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcosmic-linden <111533034+cosmic-linden@users.noreply.github.com>2023-01-11 10:36:35 -0800
committerGitHub <noreply@github.com>2023-01-11 10:36:35 -0800
commit7e1f4e4cc7588131e12b3fc7542e10d066aad93f (patch)
treed1abc294fe0a7508d6d3b9d0b6661694b11719d9
parentb4f53334141b179bdb1762636ce313f14d9e2b10 (diff)
parent693925ef23ef41e3927a9654a7f423d0e24ce19a (diff)
Merge pull request #48 from secondlife/SL-18820
Sl 18820: Build floater should preserve GLTF transforms when changing the PBR material
-rw-r--r--indra/llprimitive/llgltfmaterial.cpp45
-rw-r--r--indra/llprimitive/llgltfmaterial.h11
-rw-r--r--indra/llprimitive/lltextureentry.cpp29
-rw-r--r--indra/llprimitive/lltextureentry.h6
-rw-r--r--indra/newview/llgltfmateriallist.cpp29
-rw-r--r--indra/newview/llgltfmateriallist.h7
-rw-r--r--indra/newview/llpanelface.cpp4
-rw-r--r--indra/newview/llselectmgr.cpp21
-rw-r--r--indra/newview/llviewerobject.cpp40
-rw-r--r--indra/newview/llviewerobject.h2
10 files changed, 151 insertions, 43 deletions
diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp
index c98fd7d1ee..a8dad89292 100644
--- a/indra/llprimitive/llgltfmaterial.cpp
+++ b/indra/llprimitive/llgltfmaterial.cpp
@@ -98,6 +98,29 @@ LLGLTFMaterial& LLGLTFMaterial::operator=(const LLGLTFMaterial& rhs)
return *this;
}
+bool LLGLTFMaterial::operator==(const LLGLTFMaterial& rhs) const
+{
+ return mBaseColorId == rhs.mBaseColorId &&
+ mNormalId == rhs.mNormalId &&
+ mMetallicRoughnessId == rhs.mMetallicRoughnessId &&
+ mEmissiveId == rhs.mEmissiveId &&
+
+ mBaseColor == rhs.mBaseColor &&
+ mEmissiveColor == rhs.mEmissiveColor &&
+
+ mMetallicFactor == rhs.mMetallicFactor &&
+ mRoughnessFactor == rhs.mRoughnessFactor &&
+ mAlphaCutoff == rhs.mAlphaCutoff &&
+
+ mDoubleSided == rhs.mDoubleSided &&
+ mAlphaMode == rhs.mAlphaMode &&
+
+ mTextureTransform == rhs.mTextureTransform &&
+
+ mOverrideDoubleSided == rhs.mOverrideDoubleSided &&
+ mOverrideAlphaMode == rhs.mOverrideAlphaMode;
+}
+
bool LLGLTFMaterial::fromJSON(const std::string& json, std::string& warn_msg, std::string& error_msg)
{
LL_PROFILE_ZONE_SCOPED;
@@ -365,6 +388,28 @@ void LLGLTFMaterial::writeToTexture(tinygltf::Model& model, T& texture_info, Tex
texture_info.extensions[GLTF_FILE_EXTENSION_TRANSFORM] = tinygltf::Value(transform_map);
}
+bool LLGLTFMaterial::setBaseMaterial()
+{
+ const LLGLTFMaterial old_override = *this;
+ *this = sDefault;
+ setBaseMaterial(old_override);
+ return *this != old_override;
+}
+
+bool LLGLTFMaterial::isClearedForBaseMaterial()
+{
+ LLGLTFMaterial cleared_override = sDefault;
+ cleared_override.setBaseMaterial(*this);
+ return *this == cleared_override;
+}
+
+// For material overrides only. Copies transforms from the old override.
+void LLGLTFMaterial::setBaseMaterial(const LLGLTFMaterial& old_override_mat)
+{
+ mTextureTransform = old_override_mat.mTextureTransform;
+}
+
+
// static
void LLGLTFMaterial::hackOverrideUUID(LLUUID& id)
{
diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h
index aa49a58f0c..dec7b696f8 100644
--- a/indra/llprimitive/llgltfmaterial.h
+++ b/indra/llprimitive/llgltfmaterial.h
@@ -71,6 +71,8 @@ public:
LLGLTFMaterial(const LLGLTFMaterial& rhs);
LLGLTFMaterial& operator=(const LLGLTFMaterial& rhs);
+ bool operator==(const LLGLTFMaterial& rhs) const;
+ bool operator!=(const LLGLTFMaterial& rhs) const { return !(*this == rhs); }
LLUUID mBaseColorId;
LLUUID mNormalId;
@@ -101,7 +103,6 @@ public:
md5.finalize();
LLUUID id;
md5.raw_digest(id.mData);
- // *TODO: Hash the overrides
return id;
}
@@ -181,6 +182,12 @@ public:
void applyOverride(const LLGLTFMaterial& override_mat);
+ // For material overrides only. Clears most properties to
+ // default/fallthrough, but preserves the transforms.
+ bool setBaseMaterial();
+ // True if setBaseMaterial() was just called
+ bool isClearedForBaseMaterial();
+
private:
template<typename T>
@@ -188,5 +195,7 @@ private:
template<typename T>
void writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, const LLUUID& texture_id) const;
+
+ void setBaseMaterial(const LLGLTFMaterial& old_override_mat);
};
diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp
index a0d5793dcc..49f67918f8 100644
--- a/indra/llprimitive/lltextureentry.cpp
+++ b/indra/llprimitive/lltextureentry.cpp
@@ -514,15 +514,15 @@ S32 LLTextureEntry::setBumpShiny(U8 bump_shiny)
return TEM_CHANGE_NONE;
}
-void LLTextureEntry::setGLTFMaterial(LLGLTFMaterial* material)
+void LLTextureEntry::setGLTFMaterial(LLGLTFMaterial* material, bool local_origin)
{
if (material != getGLTFMaterial())
{
// assert on precondtion:
- // whether or not mGLTFMaterial is null, any existing override should have been nulled out
+ // whether or not mGLTFMaterial is null, any existing override should have been cleared
// before calling setGLTFMaterial
// NOTE: if you're hitting this assert, try to make sure calling code is using LLViewerObject::setRenderMaterialID
- llassert(getGLTFMaterialOverride() == nullptr);
+ llassert(!local_origin || getGLTFMaterialOverride() == nullptr || getGLTFMaterialOverride()->isClearedForBaseMaterial());
mGLTFMaterial = material;
if (mGLTFMaterial == nullptr)
@@ -538,6 +538,27 @@ void LLTextureEntry::setGLTFMaterialOverride(LLGLTFMaterial* mat)
mGLTFMaterialOverrides = mat;
}
+S32 LLTextureEntry::setBaseMaterial()
+{
+ S32 changed = TEM_CHANGE_NONE;
+
+ if (mGLTFMaterialOverrides)
+ {
+ if (mGLTFMaterialOverrides->setBaseMaterial())
+ {
+ changed = TEM_CHANGE_TEXTURE;
+ }
+
+ if (LLGLTFMaterial::sDefault == *mGLTFMaterialOverrides)
+ {
+ mGLTFMaterialOverrides = nullptr;
+ changed = TEM_CHANGE_TEXTURE;
+ }
+ }
+
+ return changed;
+}
+
LLGLTFMaterial* LLTextureEntry::getGLTFRenderMaterial() const
{
if (mGLTFRenderMaterial.notNull())
@@ -545,7 +566,7 @@ LLGLTFMaterial* LLTextureEntry::getGLTFRenderMaterial() const
return mGLTFRenderMaterial;
}
- llassert(getGLTFMaterialOverride() == nullptr);
+ llassert(getGLTFMaterialOverride() == nullptr || getGLTFMaterialOverride()->isClearedForBaseMaterial());
return getGLTFMaterial();
}
diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h
index d94e14bd73..9a81181f3a 100644
--- a/indra/llprimitive/lltextureentry.h
+++ b/indra/llprimitive/lltextureentry.h
@@ -195,12 +195,16 @@ public:
enum { MF_NONE = 0x0, MF_HAS_MEDIA = 0x1 };
// GLTF asset
- void setGLTFMaterial(LLGLTFMaterial* material);
+ void setGLTFMaterial(LLGLTFMaterial* material, bool local_origin = true);
LLGLTFMaterial* getGLTFMaterial() const { return mGLTFMaterial; }
// GLTF override
LLGLTFMaterial* getGLTFMaterialOverride() const { return mGLTFMaterialOverrides; }
void setGLTFMaterialOverride(LLGLTFMaterial* mat);
+ // Clear most overrides so the render material better matches the material
+ // ID (preserve transforms). If the overrides become passthrough, set the
+ // overrides to nullptr.
+ S32 setBaseMaterial();
// GLTF render material
// nuanced behavior here -- if there is no render material, fall back to getGLTFMaterial, but ONLY for the getter, not the setter
diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp
index 4aea0fcbcc..9399342a61 100644
--- a/indra/newview/llgltfmateriallist.cpp
+++ b/indra/newview/llgltfmateriallist.cpp
@@ -404,9 +404,19 @@ void LLGLTFMaterialList::queueModify(const LLUUID& id, S32 side, const LLGLTFMat
}
}
-void LLGLTFMaterialList::queueApply(const LLUUID& object_id, S32 side, const LLUUID& asset_id)
+void LLGLTFMaterialList::queueApply(const LLViewerObject* obj, S32 side, const LLUUID& asset_id)
{
- sApplyQueue.push_back({ object_id, side, asset_id});
+ const LLGLTFMaterial* material_override = obj->getTE(side)->getGLTFMaterialOverride();
+ if (material_override)
+ {
+ LLGLTFMaterial* cleared_override = new LLGLTFMaterial(*material_override);
+ cleared_override->setBaseMaterial();
+ sApplyQueue.push_back({ obj->getID(), side, asset_id, cleared_override });
+ }
+ else
+ {
+ sApplyQueue.push_back({ obj->getID(), side, asset_id, nullptr });
+ }
}
void LLGLTFMaterialList::queueUpdate(const LLSD& data)
@@ -436,6 +446,11 @@ void LLGLTFMaterialList::flushUpdates(void(*done_callback)(bool))
{
data[i]["gltf_json"] = e.override_data.asJSON();
}
+ else
+ {
+ // Clear all overrides
+ data[i]["gltf_json"] = "";
+ }
llassert(is_valid_update(data[i]));
++i;
@@ -447,7 +462,15 @@ void LLGLTFMaterialList::flushUpdates(void(*done_callback)(bool))
data[i]["object_id"] = e.object_id;
data[i]["side"] = e.side;
data[i]["asset_id"] = e.asset_id;
- data[i]["gltf_json"] = ""; // null out any existing overrides when applying a material asset
+ if (e.override_data)
+ {
+ data[i]["gltf_json"] = e.override_data->asJSON();
+ }
+ else
+ {
+ // Clear all overrides
+ data[i]["gltf_json"] = "";
+ }
llassert(is_valid_update(data[i]));
++i;
diff --git a/indra/newview/llgltfmateriallist.h b/indra/newview/llgltfmateriallist.h
index abbb755599..70540e5e01 100644
--- a/indra/newview/llgltfmateriallist.h
+++ b/indra/newview/llgltfmateriallist.h
@@ -59,7 +59,7 @@ public:
// side - TexureEntry index to modify, or -1 for all sides
// mat - material to apply as override, or nullptr to remove existing overrides and revert to asset
//
- // NOTE: do not use to revert to asset when applying a new asset id, use queueApplyMaterialAsset below
+ // NOTE: do not use to revert to asset when applying a new asset id, use queueApply below
static void queueModify(const LLUUID& id, S32 side, const LLGLTFMaterial* mat);
// Queue an application of a material asset we want to send to the simulator. Call "flushUpdates" to flush pending updates.
@@ -67,8 +67,8 @@ public:
// side - TextureEntry index to apply material to, or -1 for all sides
// asset_id - ID of material asset to apply, or LLUUID::null to disassociate current material asset
//
- // NOTE: implicitly removes any override data if present
- static void queueApply(const LLUUID& object_id, S32 side, const LLUUID& asset_id);
+ // NOTE: Implicitly clears most override data if present
+ static void queueApply(const LLViewerObject* obj, S32 side, const LLUUID& asset_id);
// flush pending material updates to the simulator
// Automatically called once per frame, but may be called explicitly
@@ -136,6 +136,7 @@ protected:
LLUUID object_id;
S32 side = -1;
LLUUID asset_id;
+ LLPointer<LLGLTFMaterial> override_data;
};
typedef std::list<ApplyMaterialAssetData> apply_queue_t;
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 0b18bdc6e6..cf02f3c4e4 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -4527,8 +4527,8 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te)
tep->setGLTFRenderMaterial(nullptr);
tep->setGLTFMaterialOverride(nullptr);
- // blank out any override data on the server
- LLGLTFMaterialList::queueApply(objectp->getID(), te, LLUUID::null);
+ // blank out most override data on the server
+ LLGLTFMaterialList::queueApply(objectp, te, LLUUID::null);
}
// Texture map
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 61f9d3d6d0..2b6578c272 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -1806,11 +1806,9 @@ void LLObjectSelection::applyNoCopyPbrMaterialToTEs(LLViewerInventoryItem* item)
}
// apply texture for the selected faces
+ // blank out most override data on the server
//add(LLStatViewer::EDIT_TEXTURE, 1);
- object->setRenderMaterialID(te, asset_id, false /*will be sent later*/);
-
- // blank out any override data on the server
- LLGLTFMaterialList::queueApply(object->getID(), te, asset_id);
+ object->setRenderMaterialID(te, asset_id);
}
}
}
@@ -1949,10 +1947,8 @@ void LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id)
objectp->setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, TRUE, false /*prevent an update*/);
}
- objectp->setRenderMaterialID(te, asset_id, false /*prevent an update to prevent a race condition*/);
-
- // blank out any override data on the server
- LLGLTFMaterialList::queueApply(objectp->getID(), te, asset_id);
+ // Blank out most override data on the object and send to server
+ objectp->setRenderMaterialID(te, asset_id);
return true;
}
@@ -2223,17 +2219,12 @@ void LLSelectMgr::selectionRevertGLTFMaterials()
&& asset_id.notNull())
{
// Restore overrides
- LLSD overrides;
- overrides["object_id"] = objectp->getID();
- overrides["side"] = te;
-
- overrides["gltf_json"] = nodep->mSavedGLTFOverrideMaterials[te]->asJSON();
- LLGLTFMaterialList::queueUpdate(overrides);
+ LLGLTFMaterialList::queueModify(objectp->getID(), te, nodep->mSavedGLTFOverrideMaterials[te]);
}
else
{
//blank override out
- LLGLTFMaterialList::queueApply(objectp->getID(), te, asset_id);
+ LLGLTFMaterialList::queueApply(objectp, te, asset_id);
}
}
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index dd7f679846..2bd0de4d6c 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -7163,11 +7163,11 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat
{
// implementation is delicate
- // if update is bound for server, should always null out GLTFRenderMaterial and GLTFMaterialOverride even if ids haven't changed
+ // if update is bound for server, should always null out GLTFRenderMaterial and clear GLTFMaterialOverride even if ids haven't changed
// (the case where ids haven't changed indicates the user has reapplied the original material, in which case overrides should be dropped)
- // otherwise, should only null out where ids have changed
+ // otherwise, should only null out the render material where ids or overrides have changed
// (the case where ids have changed but overrides are still present is from unsynchronized updates from the simulator)
-
+
S32 start_idx = 0;
S32 end_idx = getNumTEs();
@@ -7180,6 +7180,13 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat
start_idx = llmax(start_idx, 0);
end_idx = llmin(end_idx, (S32) getNumTEs());
+ LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
+ if (!param_block && id.notNull())
+ { // block doesn't exist, but it will need to
+ param_block = (LLRenderMaterialParams*)createNewParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL)->data;
+ }
+
+
// update local state
for (S32 te = start_idx; te < end_idx; ++te)
{
@@ -7192,17 +7199,27 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat
new_material = gGLTFMaterialList.getMaterial(id);
}
- bool material_changed = tep->getGLTFMaterial() != new_material;
+ bool material_changed = !param_block || id != param_block->getMaterial(te);
+
+ if (update_server)
+ {
+ // Clear most overrides so the render material better matches the material
+ // ID (preserve transforms). If overrides become passthrough, set the overrides
+ // to nullptr.
+ if (tep->setBaseMaterial())
+ {
+ material_changed = true;
+ }
+ }
if (update_server || material_changed)
{
tep->setGLTFRenderMaterial(nullptr);
- tep->setGLTFMaterialOverride(nullptr);
}
if (new_material != tep->getGLTFMaterial())
{
- tep->setGLTFMaterial(new_material);
+ tep->setGLTFMaterial(new_material, !update_server);
}
}
@@ -7215,17 +7232,14 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat
// update via ModifyMaterialParams cap (server will echo back changes)
for (S32 te = start_idx; te < end_idx; ++te)
{
- LLGLTFMaterialList::queueApply(getID(), te, id);
+ // This sends a cleared version of this object's current material
+ // override, but the override should already be cleared due to
+ // calling setBaseMaterial above.
+ LLGLTFMaterialList::queueApply(this, te, id);
}
}
// predictively update LLRenderMaterialParams (don't wait for server)
- LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
- if (!param_block && id.notNull())
- { // block doesn't exist, but it will need to
- param_block = (LLRenderMaterialParams*)createNewParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL)->data;
- }
-
if (param_block)
{ // update existing parameter block
for (S32 te = start_idx; te < end_idx; ++te)
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 8c4afdcba4..71d7a7ebbb 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -188,7 +188,7 @@ public:
// set the RenderMaterialID for the given TextureEntry
// te - TextureEntry index to set, or -1 for all TEs
// id - asset id of material asset
- // update_server - if true, will send updates to server
+ // update_server - if true, will send updates to server and clear most overrides
void setRenderMaterialID(S32 te, const LLUUID& id, bool update_server = true);
void setRenderMaterialIDs(const LLUUID& id);