From d6841c07983a46ff805ed23a7318efbf9cca3b24 Mon Sep 17 00:00:00 2001
From: Cosmic Linden <cosmic@lindenlab.com>
Date: Thu, 9 Feb 2023 15:04:46 -0800
Subject: SL-19080: Update GLTF Material asset upload to v1.1, with stricter
 GLTF compliance and removal of unsupported features

---
 indra/newview/llgltfmateriallist.cpp |   4 +-
 indra/newview/llmaterialeditor.cpp   | 209 +++++++++--------------------------
 indra/newview/llmaterialeditor.h     |   9 +-
 indra/newview/lltinygltfhelper.cpp   |  16 +--
 indra/newview/llviewermenufile.cpp   |   8 +-
 indra/newview/llviewerobject.cpp     |   8 +-
 6 files changed, 73 insertions(+), 181 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp
index bc094ac838..4051521ad4 100644
--- a/indra/newview/llgltfmateriallist.cpp
+++ b/indra/newview/llgltfmateriallist.cpp
@@ -564,9 +564,9 @@ void LLGLTFMaterialList::onAssetLoadComplete(const LLUUID& id, LLAssetType::ETyp
 
                 if (LLSDSerialize::deserialize(asset, str, buffer.size()))
                 {
-                    if (asset.has("version") && asset["version"] == "1.0")
+                    if (asset.has("version") && LLGLTFMaterial::isAcceptedVersion(asset["version"].asString()))
                     {
-                        if (asset.has("type") && asset["type"].asString() == "GLTF 2.0")
+                        if (asset.has("type") && asset["type"].asString() == LLGLTFMaterial::ASSET_TYPE)
                         {
                             if (asset.has("data") && asset["data"].isString())
                             {
diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp
index 5628327ebe..173f5620c6 100644
--- a/indra/newview/llmaterialeditor.cpp
+++ b/indra/newview/llmaterialeditor.cpp
@@ -277,10 +277,10 @@ bool LLSelectedTEGetMatData::apply(LLViewerObject* objectp, S32 te_index)
             llassert(mat.notNull()); // by this point shouldn't be null
             if (mat.notNull())
             {
-                tex_color_id = mat->mBaseColorId;
-                tex_metal_id = mat->mMetallicRoughnessId;
-                tex_emissive_id = mat->mEmissiveId;
-                tex_normal_id = mat->mNormalId;
+                tex_color_id = mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR];
+                tex_metal_id = mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS];
+                tex_emissive_id = mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE];
+                tex_normal_id = mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL];
             }
             if (mFirst)
             {
@@ -949,7 +949,7 @@ void LLMaterialEditor::onSelectCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_
                     }
                     case MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY:
                     {
-                        nodep->mSavedGLTFOverrideMaterials[te]->setMetallicRoughnessId(mCtrl->getValue().asUUID(), true);
+                        nodep->mSavedGLTFOverrideMaterials[te]->setOcclusionRoughnessMetallicId(mCtrl->getValue().asUUID(), true);
                         break;
                     }
                     case MATERIAL_EMISIVE_TEX_DIRTY:
@@ -991,30 +991,6 @@ void LLMaterialEditor::onSelectCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_
     LLSelectMgr::getInstance()->getSelection()->applyToNodes(&func);
 }
 
-static void write_color(const LLColor4& color, std::vector<double>& c)
-{
-    for (int i = 0; i < c.size(); ++i) // NOTE -- use c.size because some gltf colors are 3-component
-    {
-        c[i] = color.mV[i];
-    }
-}
-
-static U32 write_texture(const LLUUID& id, tinygltf::Model& model)
-{
-    tinygltf::Image image;
-    image.uri = id.asString();
-    model.images.push_back(image);
-    U32 image_idx = model.images.size() - 1;
-
-    tinygltf::Texture texture;
-    texture.source = image_idx;
-    model.textures.push_back(texture);
-    U32 texture_idx = model.textures.size() - 1;
-
-    return texture_idx;
-}
-
-
 void LLMaterialEditor::onClickSave()
 {
     if (!capabilitiesAvailable())
@@ -1034,109 +1010,14 @@ void LLMaterialEditor::onClickSave()
     saveIfNeeded();
 }
 
-
-std::string LLMaterialEditor::getGLTFJson(bool prettyprint)
-{
-    tinygltf::Model model;
-    getGLTFModel(model);
-
-    std::ostringstream str;
-
-    tinygltf::TinyGLTF gltf;
-    
-    gltf.WriteGltfSceneToStream(&model, str, prettyprint, false);
-
-    std::string dump = str.str();
-
-    return dump;
-}
-
-void LLMaterialEditor::getGLBData(std::vector<U8>& data)
-{
-    tinygltf::Model model;
-    getGLTFModel(model);
-
-    std::ostringstream str;
-
-    tinygltf::TinyGLTF gltf;
-
-    gltf.WriteGltfSceneToStream(&model, str, false, true);
-
-    std::string dump = str.str();
-
-    data.resize(dump.length());
-
-    memcpy(&data[0], dump.c_str(), dump.length());
-}
-
-void LLMaterialEditor::getGLTFModel(tinygltf::Model& model)
-{
-    model.materials.resize(1);
-    tinygltf::PbrMetallicRoughness& pbrMaterial = model.materials[0].pbrMetallicRoughness;
-
-    // write base color
-    LLColor4 base_color = getBaseColor();
-    base_color.mV[3] = getTransparency();
-    write_color(base_color, pbrMaterial.baseColorFactor);
-
-    model.materials[0].alphaCutoff = getAlphaCutoff();
-    model.materials[0].alphaMode = getAlphaMode();
-
-    LLUUID base_color_id = getBaseColorId();
-
-    if (base_color_id.notNull())
-    {
-        U32 texture_idx = write_texture(base_color_id, model);
-
-        pbrMaterial.baseColorTexture.index = texture_idx;
-    }
-
-    // write metallic/roughness
-    F32 metalness = getMetalnessFactor();
-    F32 roughness = getRoughnessFactor();
-
-    pbrMaterial.metallicFactor = metalness;
-    pbrMaterial.roughnessFactor = roughness;
-
-    LLUUID mr_id = getMetallicRoughnessId();
-    if (mr_id.notNull())
-    {
-        U32 texture_idx = write_texture(mr_id, model);
-        pbrMaterial.metallicRoughnessTexture.index = texture_idx;
-    }
-
-    //write emissive
-    LLColor4 emissive_color = getEmissiveColor();
-    model.materials[0].emissiveFactor.resize(3);
-    write_color(emissive_color, model.materials[0].emissiveFactor);
-
-    LLUUID emissive_id = getEmissiveId();
-    if (emissive_id.notNull())
-    {
-        U32 idx = write_texture(emissive_id, model);
-        model.materials[0].emissiveTexture.index = idx;
-    }
-
-    //write normal
-    LLUUID normal_id = getNormalId();
-    if (normal_id.notNull())
-    {
-        U32 idx = write_texture(normal_id, model);
-        model.materials[0].normalTexture.index = idx;
-    }
-
-    //write doublesided
-    model.materials[0].doubleSided = getDoubleSided();
-
-    model.asset.version = "2.0";
-}
-
 std::string LLMaterialEditor::getEncodedAsset()
 {
     LLSD asset;
-    asset["version"] = "1.0";
-    asset["type"] = "GLTF 2.0";
-    asset["data"] = getGLTFJson(false);
+    asset["version"] = LLGLTFMaterial::ASSET_VERSION;
+    asset["type"] = LLGLTFMaterial::ASSET_TYPE;
+    LLGLTFMaterial mat;
+    getGLTFMaterial(&mat);
+    asset["data"] = mat.asJSON();
 
     std::ostringstream str;
     LLSDSerialize::serialize(asset, str, LLSDSerialize::LLSD_BINARY);
@@ -1151,9 +1032,9 @@ bool LLMaterialEditor::decodeAsset(const std::vector<char>& buffer)
     std::istrstream str(&buffer[0], buffer.size());
     if (LLSDSerialize::deserialize(asset, str, buffer.size()))
     {
-        if (asset.has("version") && asset["version"] == "1.0")
+        if (asset.has("version") && LLGLTFMaterial::isAcceptedVersion(asset["version"].asString()))
         {
-            if (asset.has("type") && asset["type"] == "GLTF 2.0")
+            if (asset.has("type") && asset["type"] == LLGLTFMaterial::ASSET_TYPE)
             {
                 if (asset.has("data") && asset["data"].isString())
                 {
@@ -1169,6 +1050,12 @@ bool LLMaterialEditor::decodeAsset(const std::vector<char>& buffer)
                     if (loader.LoadASCIIFromString(&model_in, &error_msg, &warn_msg, data.c_str(), data.length(), ""))
                     {
                         // assets are only supposed to have one item
+                        // *NOTE: This duplicates some functionality from
+                        // LLGLTFMaterial::fromJSON, but currently does the job
+                        // better for the material editor use case.
+                        // However, LLGLTFMaterial::asJSON should always be
+                        // used when uploading materials, to ensure the
+                        // asset is valid.
                         return setFromGltfModel(model_in, 0, true);
                     }
                     else
@@ -1977,7 +1864,9 @@ void LLMaterialEditor::saveMaterialAs(const LLGLTFMaterial* render_material, con
         {
             // don't use override material here, it has 'hacked ids'
             // and values, use end result, apply it on top of local.
-            me->setBaseColor(render_material->mBaseColor);
+            const LLColor4& base_color = render_material->mBaseColor;
+            me->setBaseColor(LLColor3(base_color));
+            me->setTransparency(base_color[VW]);
             me->setMetalnessFactor(render_material->mMetallicFactor);
             me->setRoughnessFactor(render_material->mRoughnessFactor);
             me->setEmissiveColor(render_material->mEmissiveColor);
@@ -1988,24 +1877,24 @@ void LLMaterialEditor::saveMaterialAs(const LLGLTFMaterial* render_material, con
             // most things like colors we can apply without verifying
             // but texture ids are going to be different from both, base and override
             // so only apply override id if there is actually a difference
-            if (local_material->mBaseColorId != render_material->mBaseColorId)
+            if (local_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] != render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR])
             {
-                me->setBaseColorId(render_material->mBaseColorId);
+                me->setBaseColorId(render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]);
                 me->childSetValue("base_color_upload_fee", me->getString("no_upload_fee_string"));
             }
-            if (local_material->mNormalId != render_material->mNormalId)
+            if (local_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] != render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL])
             {
-                me->setNormalId(render_material->mNormalId);
+                me->setNormalId(render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]);
                 me->childSetValue("normal_upload_fee", me->getString("no_upload_fee_string"));
             }
-            if (local_material->mMetallicRoughnessId != render_material->mMetallicRoughnessId)
+            if (local_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] != render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS])
             {
-                me->setMetallicRoughnessId(render_material->mMetallicRoughnessId);
+                me->setMetallicRoughnessId(render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]);
                 me->childSetValue("metallic_upload_fee", me->getString("no_upload_fee_string"));
             }
-            if (local_material->mEmissiveId != render_material->mEmissiveId)
+            if (local_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] != render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE])
             {
-                me->setEmissiveId(render_material->mEmissiveId);
+                me->setEmissiveId(render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]);
                 me->childSetValue("emissive_upload_fee", me->getString("no_upload_fee_string"));
             }
 
@@ -2019,7 +1908,11 @@ void LLMaterialEditor::saveMaterialAs(const LLGLTFMaterial* render_material, con
     LLSD payload;
     if (render_material)
     {
-        payload["data"] = render_material->asJSON();
+        // Make a copy of the render material with unsupported transforms removed
+        LLGLTFMaterial asset_material = *render_material;
+        asset_material.sanitizeAssetMaterial();
+        // Serialize the sanitized render material
+        payload["data"] = asset_material.asJSON();
     }
     else
     {
@@ -2042,8 +1935,9 @@ void LLMaterialEditor::onSaveObjectsMaterialAsMsgCallback(const LLSD& notificati
     if (0 == option)
     {
         LLSD asset;
-        asset["version"] = "1.0";
-        asset["type"] = "GLTF 2.0";
+        asset["version"] = LLGLTFMaterial::ASSET_VERSION;
+        asset["type"] = LLGLTFMaterial::ASSET_TYPE;
+        // This is the string serialized from LLGLTFMaterial::asJSON
         asset["data"] = notification["payload"]["data"];
 
         std::ostringstream str;
@@ -2586,7 +2480,7 @@ public:
             }
             else if ((reverted_flags & MATERIAL_BASE_COLOR_TEX_DIRTY) && revert_mat.notNull())
             {
-                material->setBaseColorId(revert_mat->mBaseColorId, false);
+                material->setBaseColorId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR], false);
             }
 
             if (changed_flags & MATERIAL_NORMAL_TEX_DIRTY)
@@ -2595,16 +2489,16 @@ public:
             }
             else if ((reverted_flags & MATERIAL_NORMAL_TEX_DIRTY) && revert_mat.notNull())
             {
-                material->setNormalId(revert_mat->mNormalId, false);
+                material->setNormalId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL], false);
             }
 
             if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY)
             {
-                material->setMetallicRoughnessId(mEditor->getMetallicRoughnessId(), true);
+                material->setOcclusionRoughnessMetallicId(mEditor->getMetallicRoughnessId(), true);
             }
             else if ((reverted_flags & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) && revert_mat.notNull())
             {
-                material->setMetallicRoughnessId(revert_mat->mMetallicRoughnessId, false);
+                material->setOcclusionRoughnessMetallicId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS], false);
             }
 
             if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY)
@@ -2640,7 +2534,7 @@ public:
             }
             else if ((reverted_flags & MATERIAL_EMISIVE_TEX_DIRTY) && revert_mat.notNull())
             {
-                material->setEmissiveId(revert_mat->mEmissiveId, false);
+                material->setEmissiveId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE], false);
             }
 
             if (changed_flags & MATERIAL_DOUBLE_SIDED_DIRTY)
@@ -2753,20 +2647,23 @@ void LLMaterialEditor::applyToSelection()
     }
 }
 
+// Get a dump of the json representation of the current state of the editor UI
+// in GLTF format, excluding transforms as they are not supported in material
+// assets. (See also LLGLTFMaterial::sanitizeAssetMaterial())
 void LLMaterialEditor::getGLTFMaterial(LLGLTFMaterial* mat)
 {
     mat->mBaseColor = getBaseColor();
     mat->mBaseColor.mV[3] = getTransparency();
-    mat->mBaseColorId = getBaseColorId();
+    mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] = getBaseColorId();
 
-    mat->mNormalId = getNormalId();
+    mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] = getNormalId();
 
-    mat->mMetallicRoughnessId = getMetallicRoughnessId();
+    mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] = getMetallicRoughnessId();
     mat->mMetallicFactor = getMetalnessFactor();
     mat->mRoughnessFactor = getRoughnessFactor();
 
     mat->mEmissiveColor = getEmissiveColor();
-    mat->mEmissiveId = getEmissiveId();
+    mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] = getEmissiveId();
 
     mat->mDoubleSided = getDoubleSided();
     mat->setAlphaMode(getAlphaMode());
@@ -2776,15 +2673,15 @@ void LLMaterialEditor::getGLTFMaterial(LLGLTFMaterial* mat)
 void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat)
 {
     setBaseColor(mat->mBaseColor);
-    setBaseColorId(mat->mBaseColorId);
-    setNormalId(mat->mNormalId);
+    setBaseColorId(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]);
+    setNormalId(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]);
 
-    setMetallicRoughnessId(mat->mMetallicRoughnessId);
+    setMetallicRoughnessId(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]);
     setMetalnessFactor(mat->mMetallicFactor);
     setRoughnessFactor(mat->mRoughnessFactor);
 
     setEmissiveColor(mat->mEmissiveColor);
-    setEmissiveId(mat->mEmissiveId);
+    setEmissiveId(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]);
 
     setDoubleSided(mat->mDoubleSided);
     setAlphaMode(mat->getAlphaMode());
diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h
index 74c776031e..0401190773 100644
--- a/indra/newview/llmaterialeditor.h
+++ b/indra/newview/llmaterialeditor.h
@@ -84,8 +84,7 @@ protected:
 };
 
 class LLMaterialEditor : public LLPreview, public LLVOInventoryListener
-{
-public:
+{ public:
 	LLMaterialEditor(const LLSD& key);
 
     bool setFromGltfModel(const tinygltf::Model& model, S32 index, bool set_textures = false);
@@ -98,6 +97,7 @@ public:
     // for live preview, apply current material to currently selected object
     void applyToSelection();
 
+    // get a dump of the json representation of the current state of the editor UI as a material object
     void getGLTFMaterial(LLGLTFMaterial* mat);
 
     void loadAsset() override;
@@ -131,11 +131,6 @@ public:
 
     void onClickSave();
 
-    // get a dump of the json representation of the current state of the editor UI in GLTF format
-    std::string getGLTFJson(bool prettyprint = true);
-
-    void getGLBData(std::vector<U8>& data);
-
     void getGLTFModel(tinygltf::Model& model);
 
     std::string getEncodedAsset();
diff --git a/indra/newview/lltinygltfhelper.cpp b/indra/newview/lltinygltfhelper.cpp
index 611911014a..1a8e868d11 100644
--- a/indra/newview/lltinygltfhelper.cpp
+++ b/indra/newview/lltinygltfhelper.cpp
@@ -309,48 +309,48 @@ bool LLTinyGLTFHelper::getMaterialFromFile(
     if (base_color_tex)
     {
         base_color_tex->addTextureStats(64.f * 64.f, TRUE);
-        material->mBaseColorId = base_color_tex->getID();
+        material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] = base_color_tex->getID();
         material->mBaseColorTexture = base_color_tex;
     }
     else
     {
-        material->mBaseColorId = LLUUID::null;
+        material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] = LLUUID::null;
         material->mBaseColorTexture = nullptr;
     }
 
     if (normal_tex)
     {
         normal_tex->addTextureStats(64.f * 64.f, TRUE);
-        material->mNormalId = normal_tex->getID();
+        material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] = normal_tex->getID();
         material->mNormalTexture = normal_tex;
     }
     else
     {
-        material->mNormalId = LLUUID::null;
+        material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] = LLUUID::null;
         material->mNormalTexture = nullptr;
     }
 
     if (mr_tex)
     {
         mr_tex->addTextureStats(64.f * 64.f, TRUE);
-        material->mMetallicRoughnessId = mr_tex->getID();
+        material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] = mr_tex->getID();
         material->mMetallicRoughnessTexture = mr_tex;
     }
     else
     {
-        material->mMetallicRoughnessId = LLUUID::null;
+        material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] = LLUUID::null;
         material->mMetallicRoughnessTexture = nullptr;
     }
 
     if (emissive_tex)
     {
         emissive_tex->addTextureStats(64.f * 64.f, TRUE);
-        material->mEmissiveId = emissive_tex->getID();
+        material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] = emissive_tex->getID();
         material->mEmissiveTexture = emissive_tex;
     }
     else
     {
-        material->mEmissiveId = LLUUID::null;
+        material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] = LLUUID::null;
         material->mEmissiveTexture = nullptr;
     }
 
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index 84b0010545..9743f00ab8 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -543,19 +543,19 @@ bool get_bulk_upload_expected_cost(const std::vector<std::string>& filenames, S3
                     // Todo: make it account for possibility of same texture in different
                     // materials and even in scope of same material
                     S32 texture_count = 0;
-                    if (material->mBaseColorId.notNull())
+                    if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR].notNull())
                     {
                         texture_count++;
                     }
-                    if (material->mMetallicRoughnessId.notNull())
+                    if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].notNull())
                     {
                         texture_count++;
                     }
-                    if (material->mNormalId.notNull())
+                    if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL].notNull())
                     {
                         texture_count++;
                     }
-                    if (material->mEmissiveId.notNull())
+                    if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE].notNull())
                     {
                         texture_count++;
                     }
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 5a365c79ea..88d5d50845 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -4993,10 +4993,10 @@ void LLViewerObject::updateTEMaterialTextures(U8 te)
 
     if (mat != nullptr)
     {
-        mat->mBaseColorTexture = fetch_texture(mat->mBaseColorId);
-        mat->mNormalTexture = fetch_texture(mat->mNormalId);
-        mat->mMetallicRoughnessTexture = fetch_texture(mat->mMetallicRoughnessId);
-        mat->mEmissiveTexture= fetch_texture(mat->mEmissiveId);
+        mat->mBaseColorTexture = fetch_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]);
+        mat->mNormalTexture = fetch_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]);
+        mat->mMetallicRoughnessTexture = fetch_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]);
+        mat->mEmissiveTexture= fetch_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]);
     }
 }
 
-- 
cgit v1.2.3


From 917932549fe40f02bf393f22ec1af12aa2245264 Mon Sep 17 00:00:00 2001
From: Cosmic Linden <cosmic@lindenlab.com>
Date: Tue, 14 Feb 2023 13:52:33 -0800
Subject: SL-19002: Stop sending material IDs from client via material params
 and just call queueApply/queueModify

---
 indra/newview/llpanelface.cpp    | 29 ++---------------
 indra/newview/llselectmgr.cpp    | 68 +++-------------------------------------
 indra/newview/llviewerobject.cpp | 35 +++++++++------------
 3 files changed, 22 insertions(+), 110 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index cb09ec9fbf..54256ae646 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -3823,34 +3823,12 @@ private:
 
 struct LLPanelFaceUpdateFunctor : public LLSelectedObjectFunctor
 {
-    LLPanelFaceUpdateFunctor(bool update_media, bool update_pbr)
+    LLPanelFaceUpdateFunctor(bool update_media)
         : mUpdateMedia(update_media)
-        , mUpdatePbr(update_pbr)
     {}
 
     virtual bool apply(LLViewerObject* object)
     {
-        if (mUpdatePbr)
-        {
-            // setRenderMaterialId is supposed to create it
-            LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)object->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
-            if (param_block)
-            {
-                if (param_block->isEmpty())
-                {
-                    object->setHasRenderMaterialParams(false);
-                }
-                else if (object->hasRenderMaterialParams())
-                {
-                    object->parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, true);
-                }
-                else
-                {
-                    object->setHasRenderMaterialParams(true);
-                }
-            }
-        }
-
         object->sendTEUpdate();
 
         if (mUpdateMedia)
@@ -3865,7 +3843,6 @@ struct LLPanelFaceUpdateFunctor : public LLSelectedObjectFunctor
     }
 private:
     bool mUpdateMedia;
-    bool mUpdatePbr;
 };
 
 struct LLPanelFaceNavigateHomeFunctor : public LLSelectedTEFunctor
@@ -4001,7 +3978,7 @@ void LLPanelFace::onPasteColor()
     LLPanelFacePasteTexFunctor paste_func(this, PASTE_COLOR);
     selected_objects->applyToTEs(&paste_func);
 
-    LLPanelFaceUpdateFunctor sendfunc(false, false);
+    LLPanelFaceUpdateFunctor sendfunc(false);
     selected_objects->applyToObjects(&sendfunc);
 }
 
@@ -4362,7 +4339,7 @@ void LLPanelFace::onPasteTexture()
     LLPanelFacePasteTexFunctor paste_func(this, PASTE_TEXTURE);
     selected_objects->applyToTEs(&paste_func);
 
-    LLPanelFaceUpdateFunctor sendfunc(true, true);
+    LLPanelFaceUpdateFunctor sendfunc(true);
     selected_objects->applyToObjects(&sendfunc);
 
     LLGLTFMaterialList::flushUpdates();
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 02e85d7470..55cf6795fe 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -1941,12 +1941,6 @@ void LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id)
                 asset_id = mItem->getAssetUUID();
             }
 
-            if (asset_id.notNull() && !objectp->hasRenderMaterialParams())
-            {
-                // make sure param section exists
-                objectp->setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, TRUE, false /*prevent an update*/);
-            }
-
             // Blank out most override data on the object and send to server
             objectp->setRenderMaterialID(te, asset_id);
 
@@ -1975,25 +1969,6 @@ void LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id)
                 return false;
             }
 
-            LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)object->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
-            if (param_block)
-            {
-                // To not cause multiple competing request that modify
-                // same param field send update only once per object
-                if (param_block->isEmpty())
-                {
-                    object->setHasRenderMaterialParams(false);
-                }
-                else if (object->hasRenderMaterialParams())
-                {
-                    object->parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, true);
-                }
-                else
-                {
-                    object->setHasRenderMaterialParams(true);
-                }
-            }
-
             if (!mItem)
             {
                 // 1 particle effect per object				
@@ -2209,14 +2184,13 @@ void LLSelectMgr::selectionRevertGLTFMaterials()
             {
                 // Restore base material
                 LLUUID asset_id = nodep->mSavedGLTFMaterialIds[te];
-                objectp->setRenderMaterialID(te, asset_id, false /*wait for bulk update*/);
 
+                // Update material locally
+                objectp->setRenderMaterialID(te, asset_id, false /*wait for LLGLTFMaterialList update*/);
+                objectp->setTEGLTFMaterialOverride(te, nodep->mSavedGLTFOverrideMaterials[te]);
 
-                // todo: make sure this does not cause race condition with setRenderMaterialID
-                // when we are reverting from null id to non null plus override
-                if (te < (S32)nodep->mSavedGLTFOverrideMaterials.size()
-                    && nodep->mSavedGLTFOverrideMaterials[te].notNull()
-                    && asset_id.notNull())
+                // Enqueue update to server
+                if (asset_id.notNull())
                 {
                     // Restore overrides
                     LLGLTFMaterialList::queueModify(objectp, te, nodep->mSavedGLTFOverrideMaterials[te]);
@@ -2232,38 +2206,6 @@ void LLSelectMgr::selectionRevertGLTFMaterials()
         }
     } setfunc(mSelectedObjects);
     getSelection()->applyToTEs(&setfunc);
-
-    struct g : public LLSelectedObjectFunctor
-    {
-        virtual bool apply(LLViewerObject* object)
-        {
-            if (object && !object->permModify())
-            {
-                return false;
-            }
-
-            LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)object->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
-            if (param_block)
-            {
-                if (param_block->isEmpty())
-                {
-                    object->setHasRenderMaterialParams(false);
-                }
-                else if (object->hasRenderMaterialParams())
-                {
-                    object->parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, true);
-                }
-                else
-                {
-                    object->setHasRenderMaterialParams(true);
-                }
-            }
-
-            object->sendTEUpdate();
-            return true;
-        }
-    } sendfunc;
-    getSelection()->applyToObjects(&sendfunc);
 }
 
 void LLSelectMgr::selectionSetBumpmap(U8 bumpmap, const LLUUID &image_id)
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 3c0a08cee1..d4c0b95701 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -6289,6 +6289,11 @@ void LLViewerObject::parameterChanged(U16 param_type, LLNetworkData* data, BOOL
 {
 	if (local_origin)
 	{
+        // *NOTE: Do not send the render material ID in this way as it will get
+        // out-of-sync with other sent client data.
+        // See LLViewerObject::setRenderMaterialID and LLGLTFMaterialList
+        llassert(param_type != LLNetworkData::PARAMS_RENDER_MATERIAL);
+
 		LLViewerRegion* regionp = getRegion();
 		if(!regionp) return;
 
@@ -7245,18 +7250,6 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat
         });
     }
 
-    if (update_server)
-    {
-        // update via ModifyMaterialParams cap (server will echo back changes)
-        for (S32 te = start_idx; te < end_idx; ++te)
-        {
-            // 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)
     if (param_block)
     { // update existing parameter block
@@ -7264,17 +7257,17 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat
         {
             param_block->setMaterial(te, id);
         }
+    }
 
-        if (update_server)
+    if (update_server)
+    {
+        // update via ModifyMaterialParams cap (server will echo back changes)
+        for (S32 te = start_idx; te < end_idx; ++te)
         {
-            // If 'in use' changes, it will send an update itself.
-            bool in_use_changed = setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, !param_block->isEmpty(), true);
-
-            if (!in_use_changed)
-            {
-                // In use didn't change, but the parameter did, send an update
-                parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, param_block, !param_block->isEmpty(), true);
-            }
+            // 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);
         }
     }
 }
-- 
cgit v1.2.3