summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llprimitive/CMakeLists.txt2
-rw-r--r--indra/llprimitive/llgltfmaterial.cpp159
-rw-r--r--indra/llprimitive/llgltfmaterial.h53
-rw-r--r--indra/llprimitive/tests/llgltfmaterial_test.cpp369
-rw-r--r--indra/newview/lldrawpool.cpp5
-rw-r--r--indra/newview/llgltfmateriallist.cpp4
-rw-r--r--indra/newview/llmaterialeditor.cpp209
-rw-r--r--indra/newview/llmaterialeditor.h9
-rw-r--r--indra/newview/llpanelface.cpp29
-rw-r--r--indra/newview/llpanelvolume.cpp8
-rw-r--r--indra/newview/llreflectionmapmanager.cpp6
-rw-r--r--indra/newview/llselectmgr.cpp68
-rw-r--r--indra/newview/lltinygltfhelper.cpp16
-rw-r--r--indra/newview/llviewermenufile.cpp8
-rw-r--r--indra/newview/llviewerobject.cpp43
-rw-r--r--indra/newview/llvovolume.cpp2
-rw-r--r--indra/newview/pipeline.cpp23
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml2
18 files changed, 613 insertions, 402 deletions
diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt
index 328b22f900..dd25c19713 100644
--- a/indra/llprimitive/CMakeLists.txt
+++ b/indra/llprimitive/CMakeLists.txt
@@ -99,6 +99,8 @@ if (LL_TESTS)
SET(llprimitive_TEST_SOURCE_FILES
llmediaentry.cpp
llprimitive.cpp
+ llgltfmaterial.cpp
)
+
LL_ADD_PROJECT_UNIT_TESTS(llprimitive "${llprimitive_TEST_SOURCE_FILES}")
endif (LL_TESTS)
diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp
index a8dad89292..4d7b10982a 100644
--- a/indra/llprimitive/llgltfmaterial.cpp
+++ b/indra/llprimitive/llgltfmaterial.cpp
@@ -31,10 +31,14 @@
// NOTE -- this should be the one and only place tiny_gltf.h is included
#include "tinygltf/tiny_gltf.h"
-const char* GLTF_FILE_EXTENSION_TRANSFORM = "KHR_texture_transform";
-const char* GLTF_FILE_EXTENSION_TRANSFORM_SCALE = "scale";
-const char* GLTF_FILE_EXTENSION_TRANSFORM_OFFSET = "offset";
-const char* GLTF_FILE_EXTENSION_TRANSFORM_ROTATION = "rotation";
+const char* const LLGLTFMaterial::ASSET_VERSION = "1.1";
+const char* const LLGLTFMaterial::ASSET_TYPE = "GLTF 2.0";
+const std::array<std::string, 2> LLGLTFMaterial::ACCEPTED_ASSET_VERSIONS = { "1.0", "1.1" };
+
+const char* const GLTF_FILE_EXTENSION_TRANSFORM = "KHR_texture_transform";
+const char* const GLTF_FILE_EXTENSION_TRANSFORM_SCALE = "scale";
+const char* const GLTF_FILE_EXTENSION_TRANSFORM_OFFSET = "offset";
+const char* const GLTF_FILE_EXTENSION_TRANSFORM_ROTATION = "rotation";
// special UUID that indicates a null UUID in override data
static const LLUUID GLTF_OVERRIDE_NULL_UUID = LLUUID("ffffffff-ffff-ffff-ffff-ffffffffffff");
@@ -73,16 +77,14 @@ LLGLTFMaterial::LLGLTFMaterial(const LLGLTFMaterial& rhs)
LLGLTFMaterial& LLGLTFMaterial::operator=(const LLGLTFMaterial& rhs)
{
- LL_PROFILE_ZONE_SCOPED;
- //have to do a manual operator= because of LLRefCount
- mBaseColorId = rhs.mBaseColorId;
- mNormalId = rhs.mNormalId;
- mMetallicRoughnessId = rhs.mMetallicRoughnessId;
- mEmissiveId = rhs.mEmissiveId;
+ //have to do a manual operator= because of LLRefCount
+ mTextureId = rhs.mTextureId;
+
+ mTextureTransform = rhs.mTextureTransform;
mBaseColor = rhs.mBaseColor;
mEmissiveColor = rhs.mEmissiveColor;
-
+
mMetallicFactor = rhs.mMetallicFactor;
mRoughnessFactor = rhs.mRoughnessFactor;
mAlphaCutoff = rhs.mAlphaCutoff;
@@ -90,8 +92,6 @@ LLGLTFMaterial& LLGLTFMaterial::operator=(const LLGLTFMaterial& rhs)
mDoubleSided = rhs.mDoubleSided;
mAlphaMode = rhs.mAlphaMode;
- mTextureTransform = rhs.mTextureTransform;
-
mOverrideDoubleSided = rhs.mOverrideDoubleSided;
mOverrideAlphaMode = rhs.mOverrideAlphaMode;
@@ -100,10 +100,9 @@ LLGLTFMaterial& LLGLTFMaterial::operator=(const LLGLTFMaterial& rhs)
bool LLGLTFMaterial::operator==(const LLGLTFMaterial& rhs) const
{
- return mBaseColorId == rhs.mBaseColorId &&
- mNormalId == rhs.mNormalId &&
- mMetallicRoughnessId == rhs.mMetallicRoughnessId &&
- mEmissiveId == rhs.mEmissiveId &&
+ return mTextureId == rhs.mTextureId &&
+
+ mTextureTransform == rhs.mTextureTransform &&
mBaseColor == rhs.mBaseColor &&
mEmissiveColor == rhs.mEmissiveColor &&
@@ -115,8 +114,6 @@ bool LLGLTFMaterial::operator==(const LLGLTFMaterial& rhs) const
mDoubleSided == rhs.mDoubleSided &&
mAlphaMode == rhs.mAlphaMode &&
- mTextureTransform == rhs.mTextureTransform &&
-
mOverrideDoubleSided == rhs.mOverrideDoubleSided &&
mOverrideAlphaMode == rhs.mOverrideAlphaMode;
}
@@ -148,6 +145,8 @@ std::string LLGLTFMaterial::asJSON(bool prettyprint) const
writeToModel(model_out, 0);
+ // To ensure consistency in asset upload, this should be the only reference
+ // to WriteGltfSceneToStream in the viewer.
gltf.WriteGltfSceneToStream(&model_out, str, prettyprint, false);
return str.str();
@@ -164,13 +163,13 @@ void LLGLTFMaterial::setFromModel(const tinygltf::Model& model, S32 mat_index)
const tinygltf::Material& material_in = model.materials[mat_index];
// Apply base color texture
- setFromTexture(model, material_in.pbrMetallicRoughness.baseColorTexture, GLTF_TEXTURE_INFO_BASE_COLOR, mBaseColorId);
+ setFromTexture(model, material_in.pbrMetallicRoughness.baseColorTexture, GLTF_TEXTURE_INFO_BASE_COLOR);
// Apply normal map
- setFromTexture(model, material_in.normalTexture, GLTF_TEXTURE_INFO_NORMAL, mNormalId);
+ setFromTexture(model, material_in.normalTexture, GLTF_TEXTURE_INFO_NORMAL);
// Apply metallic-roughness texture
- setFromTexture(model, material_in.pbrMetallicRoughness.metallicRoughnessTexture, GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS, mMetallicRoughnessId);
+ setFromTexture(model, material_in.pbrMetallicRoughness.metallicRoughnessTexture, GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS);
// Apply emissive texture
- setFromTexture(model, material_in.emissiveTexture, GLTF_TEXTURE_INFO_EMISSIVE, mEmissiveId);
+ setFromTexture(model, material_in.emissiveTexture, GLTF_TEXTURE_INFO_EMISSIVE);
setAlphaMode(material_in.alphaMode);
mAlphaCutoff = llclamp((F32)material_in.alphaCutoff, 0.f, 1.f);
@@ -264,11 +263,11 @@ std::string gltf_get_texture_image(const tinygltf::Model& model, const T& textur
// *NOTE: Use template here as workaround for the different similar texture info classes
template<typename T>
-void LLGLTFMaterial::setFromTexture(const tinygltf::Model& model, const T& texture_info, TextureInfo texture_info_id, LLUUID& texture_id_out)
+void LLGLTFMaterial::setFromTexture(const tinygltf::Model& model, const T& texture_info, TextureInfo texture_info_id)
{
LL_PROFILE_ZONE_SCOPED;
const std::string uri = gltf_get_texture_image(model, texture_info);
- texture_id_out.set(uri);
+ mTextureId[texture_info_id].set(uri);
const tinygltf::Value::Object& extensions_object = texture_info.extensions;
const auto transform_it = extensions_object.find(GLTF_FILE_EXTENSION_TRANSFORM);
@@ -297,21 +296,24 @@ void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const
tinygltf::Material& material_out = model.materials[mat_index];
// set base color texture
- writeToTexture(model, material_out.pbrMetallicRoughness.baseColorTexture, GLTF_TEXTURE_INFO_BASE_COLOR, mBaseColorId);
+ writeToTexture(model, material_out.pbrMetallicRoughness.baseColorTexture, GLTF_TEXTURE_INFO_BASE_COLOR);
// set normal texture
- writeToTexture(model, material_out.normalTexture, GLTF_TEXTURE_INFO_NORMAL, mNormalId);
+ writeToTexture(model, material_out.normalTexture, GLTF_TEXTURE_INFO_NORMAL);
// set metallic-roughness texture
- writeToTexture(model, material_out.pbrMetallicRoughness.metallicRoughnessTexture, GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS, mMetallicRoughnessId);
+ writeToTexture(model, material_out.pbrMetallicRoughness.metallicRoughnessTexture, GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS);
// set emissive texture
- writeToTexture(model, material_out.emissiveTexture, GLTF_TEXTURE_INFO_EMISSIVE, mEmissiveId);
+ writeToTexture(model, material_out.emissiveTexture, GLTF_TEXTURE_INFO_EMISSIVE);
+ // set occlusion texture
+ // *NOTE: This is required for ORM materials for GLTF compliance.
+ // See: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#_material_occlusiontexture
+ writeToTexture(model, material_out.occlusionTexture, GLTF_TEXTURE_INFO_OCCLUSION);
+
material_out.alphaMode = getAlphaMode();
material_out.alphaCutoff = mAlphaCutoff;
-
+
mBaseColor.write(material_out.pbrMetallicRoughness.baseColorFactor);
- material_out.emissiveFactor.resize(3); // 0 size by default
-
if (mEmissiveColor != LLGLTFMaterial::getDefaultEmissiveColor())
{
material_out.emissiveFactor.resize(3);
@@ -323,7 +325,6 @@ void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const
material_out.doubleSided = mDoubleSided;
-
// generate "extras" string
tinygltf::Value::Object extras;
bool write_extras = false;
@@ -364,28 +365,43 @@ void gltf_allocate_texture_image(tinygltf::Model& model, T& texture_info, const
}
template<typename T>
-void LLGLTFMaterial::writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, const LLUUID& texture_id) const
+void LLGLTFMaterial::writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, bool force_write) const
{
LL_PROFILE_ZONE_SCOPED;
+ const LLUUID& texture_id = mTextureId[texture_info_id];
const TextureTransform& transform = mTextureTransform[texture_info_id];
- if (texture_id.isNull() && transform == sDefault.mTextureTransform[0])
+ const bool is_blank_transform = transform == sDefault.mTextureTransform[0];
+ // Check if this material matches all the fallback values, and if so, then
+ // skip including it to reduce material size
+ if (!force_write && texture_id.isNull() && is_blank_transform)
{
return;
}
+ // tinygltf will discard this texture info if there is no valid texture,
+ // causing potential loss of information for overrides, so ensure one is
+ // defined. -Cosmic,2023-01-30
gltf_allocate_texture_image(model, texture_info, texture_id.asString());
- tinygltf::Value::Object transform_map;
- transform_map[GLTF_FILE_EXTENSION_TRANSFORM_OFFSET] = tinygltf::Value(tinygltf::Value::Array({
- tinygltf::Value(transform.mOffset.mV[VX]),
- tinygltf::Value(transform.mOffset.mV[VY])
- }));
- transform_map[GLTF_FILE_EXTENSION_TRANSFORM_SCALE] = tinygltf::Value(tinygltf::Value::Array({
- tinygltf::Value(transform.mScale.mV[VX]),
- tinygltf::Value(transform.mScale.mV[VY])
- }));
- transform_map[GLTF_FILE_EXTENSION_TRANSFORM_ROTATION] = tinygltf::Value(transform.mRotation);
- texture_info.extensions[GLTF_FILE_EXTENSION_TRANSFORM] = tinygltf::Value(transform_map);
+ if (!is_blank_transform)
+ {
+ tinygltf::Value::Object transform_map;
+ transform_map[GLTF_FILE_EXTENSION_TRANSFORM_OFFSET] = tinygltf::Value(tinygltf::Value::Array({
+ tinygltf::Value(transform.mOffset.mV[VX]),
+ tinygltf::Value(transform.mOffset.mV[VY])
+ }));
+ transform_map[GLTF_FILE_EXTENSION_TRANSFORM_SCALE] = tinygltf::Value(tinygltf::Value::Array({
+ tinygltf::Value(transform.mScale.mV[VX]),
+ tinygltf::Value(transform.mScale.mV[VY])
+ }));
+ transform_map[GLTF_FILE_EXTENSION_TRANSFORM_ROTATION] = tinygltf::Value(transform.mRotation);
+ texture_info.extensions[GLTF_FILE_EXTENSION_TRANSFORM] = tinygltf::Value(transform_map);
+ }
+}
+
+void LLGLTFMaterial::sanitizeAssetMaterial()
+{
+ mTextureTransform = sDefault.mTextureTransform;
}
bool LLGLTFMaterial::setBaseMaterial()
@@ -419,40 +435,33 @@ void LLGLTFMaterial::hackOverrideUUID(LLUUID& id)
}
}
-void LLGLTFMaterial::setBaseColorId(const LLUUID& id, bool for_override)
+void LLGLTFMaterial::setTextureId(TextureInfo texture_info, const LLUUID& id, bool for_override)
{
- mBaseColorId = id;
+ mTextureId[texture_info] = id;
if (for_override)
{
- hackOverrideUUID(mBaseColorId);
+ hackOverrideUUID(mTextureId[texture_info]);
}
}
+void LLGLTFMaterial::setBaseColorId(const LLUUID& id, bool for_override)
+{
+ setTextureId(GLTF_TEXTURE_INFO_BASE_COLOR, id, for_override);
+}
+
void LLGLTFMaterial::setNormalId(const LLUUID& id, bool for_override)
{
- mNormalId = id;
- if (for_override)
- {
- hackOverrideUUID(mNormalId);
- }
+ setTextureId(GLTF_TEXTURE_INFO_NORMAL, id, for_override);
}
-void LLGLTFMaterial::setMetallicRoughnessId(const LLUUID& id, bool for_override)
+void LLGLTFMaterial::setOcclusionRoughnessMetallicId(const LLUUID& id, bool for_override)
{
- mMetallicRoughnessId = id;
- if (for_override)
- {
- hackOverrideUUID(mMetallicRoughnessId);
- }
+ setTextureId(GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS, id, for_override);
}
void LLGLTFMaterial::setEmissiveId(const LLUUID& id, bool for_override)
{
- mEmissiveId = id;
- if (for_override)
- {
- hackOverrideUUID(mEmissiveId);
- }
+ setTextureId(GLTF_TEXTURE_INFO_EMISSIVE, id, for_override);
}
void LLGLTFMaterial::setBaseColorFactor(const LLColor4& baseColor, bool for_override)
@@ -533,10 +542,7 @@ const char* LLGLTFMaterial::getAlphaMode() const
void LLGLTFMaterial::setAlphaMode(S32 mode, bool for_override)
{
mAlphaMode = (AlphaMode) llclamp(mode, (S32) ALPHA_MODE_OPAQUE, (S32) ALPHA_MODE_MASK);
- if (for_override)
- {
- mOverrideAlphaMode = true;
- }
+ mOverrideAlphaMode = for_override && mAlphaMode == getDefaultAlphaMode();
}
void LLGLTFMaterial::setDoubleSided(bool double_sided, bool for_override)
@@ -544,10 +550,7 @@ void LLGLTFMaterial::setDoubleSided(bool double_sided, bool for_override)
// sure, no clamping will ever be needed for a bool, but include the
// setter for consistency with the clamping API
mDoubleSided = double_sided;
- if (for_override)
- {
- mOverrideDoubleSided = true;
- }
+ mOverrideDoubleSided = for_override && mDoubleSided == getDefaultDoubleSided();
}
void LLGLTFMaterial::setTextureOffset(TextureInfo texture_info, const LLVector2& offset)
@@ -640,10 +643,12 @@ void LLGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat)
{
LL_PROFILE_ZONE_SCOPED;
- applyOverrideUUID(mBaseColorId, override_mat.mBaseColorId);
- applyOverrideUUID(mNormalId, override_mat.mNormalId);
- applyOverrideUUID(mMetallicRoughnessId, override_mat.mMetallicRoughnessId);
- applyOverrideUUID(mEmissiveId, override_mat.mEmissiveId);
+ for (int i = 0; i < GLTF_TEXTURE_INFO_COUNT; ++i)
+ {
+ LLUUID& texture_id = mTextureId[i];
+ const LLUUID& override_texture_id = override_mat.mTextureId[i];
+ applyOverrideUUID(texture_id, override_texture_id);
+ }
if (override_mat.mBaseColor != getDefaultBaseColor())
{
diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h
index 2bd2d34b53..cae7284421 100644
--- a/indra/llprimitive/llgltfmaterial.h
+++ b/indra/llprimitive/llgltfmaterial.h
@@ -49,6 +49,11 @@ public:
// default material for reference
static const LLGLTFMaterial sDefault;
+ static const char* const ASSET_VERSION;
+ static const char* const ASSET_TYPE;
+ static const std::array<std::string, 2> ACCEPTED_ASSET_VERSIONS;
+ static bool isAcceptedVersion(const std::string& version) { return std::find(ACCEPTED_ASSET_VERSIONS.cbegin(), ACCEPTED_ASSET_VERSIONS.cend(), version) != ACCEPTED_ASSET_VERSIONS.cend(); }
+
struct TextureTransform
{
LLVector2 mOffset = { 0.f, 0.f };
@@ -74,10 +79,25 @@ public:
bool operator==(const LLGLTFMaterial& rhs) const;
bool operator!=(const LLGLTFMaterial& rhs) const { return !(*this == rhs); }
- LLUUID mBaseColorId;
- LLUUID mNormalId;
- LLUUID mMetallicRoughnessId;
- LLUUID mEmissiveId;
+ enum TextureInfo : U32
+ {
+ GLTF_TEXTURE_INFO_BASE_COLOR,
+ GLTF_TEXTURE_INFO_NORMAL,
+ GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS,
+ // *NOTE: GLTF_TEXTURE_INFO_OCCLUSION is currently ignored, in favor of
+ // the values specified with GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS.
+ // Currently, only ORM materials are supported (materials which define
+ // occlusion, roughness, and metallic in the same texture).
+ // -Cosmic,2023-01-26
+ GLTF_TEXTURE_INFO_OCCLUSION = GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS,
+ GLTF_TEXTURE_INFO_EMISSIVE,
+
+ GLTF_TEXTURE_INFO_COUNT
+ };
+
+ std::array<LLUUID, GLTF_TEXTURE_INFO_COUNT> mTextureId;
+
+ std::array<TextureTransform, GLTF_TEXTURE_INFO_COUNT> mTextureTransform;
// NOTE : initialize values to defaults according to the GLTF spec
LLColor4 mBaseColor = LLColor4(1, 1, 1, 1);
@@ -104,24 +124,14 @@ public:
return hash;
}
- enum TextureInfo : U32
- {
- GLTF_TEXTURE_INFO_BASE_COLOR,
- GLTF_TEXTURE_INFO_NORMAL,
- GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS,
- GLTF_TEXTURE_INFO_EMISSIVE,
-
- GLTF_TEXTURE_INFO_COUNT
- };
-
- std::array<TextureTransform, GLTF_TEXTURE_INFO_COUNT> mTextureTransform;
-
//setters for various members (will clamp to acceptable ranges)
// for_override - set to true if this value is being set as part of an override (important for handling override to default value)
+ void setTextureId(TextureInfo texture_info, const LLUUID& id, bool for_override = false);
+
void setBaseColorId(const LLUUID& id, bool for_override = false);
void setNormalId(const LLUUID& id, bool for_override = false);
- void setMetallicRoughnessId(const LLUUID& id, bool for_override = false);
+ void setOcclusionRoughnessMetallicId(const LLUUID& id, bool for_override = false);
void setEmissiveId(const LLUUID& id, bool for_override = false);
void setBaseColorFactor(const LLColor4& baseColor, bool for_override = false);
@@ -180,6 +190,10 @@ public:
void applyOverride(const LLGLTFMaterial& override_mat);
+ // For base materials only (i.e. assets). Clears transforms to
+ // default since they're not supported in assets yet.
+ void sanitizeAssetMaterial();
+
// For material overrides only. Clears most properties to
// default/fallthrough, but preserves the transforms.
bool setBaseMaterial();
@@ -187,12 +201,11 @@ public:
bool isClearedForBaseMaterial();
private:
-
template<typename T>
- void setFromTexture(const tinygltf::Model& model, const T& texture_info, TextureInfo texture_info_id, LLUUID& texture_id_out);
+ void setFromTexture(const tinygltf::Model& model, const T& texture_info, TextureInfo texture_info_id);
template<typename T>
- void writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, const LLUUID& texture_id) const;
+ void writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, bool force_write = false) const;
void setBaseMaterial(const LLGLTFMaterial& old_override_mat);
};
diff --git a/indra/llprimitive/tests/llgltfmaterial_test.cpp b/indra/llprimitive/tests/llgltfmaterial_test.cpp
new file mode 100644
index 0000000000..88b6fae3a7
--- /dev/null
+++ b/indra/llprimitive/tests/llgltfmaterial_test.cpp
@@ -0,0 +1,369 @@
+/**
+ * @file llgltfmaterial_test.cpp
+ *
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2023, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include "lltut.h"
+
+#include "../llgltfmaterial.h"
+#include "lluuid.cpp"
+
+// Import & define single-header gltf import/export lib
+#define TINYGLTF_IMPLEMENTATION
+#define TINYGLTF_USE_CPP14 // default is C++ 11
+
+// tinygltf by default loads image files using STB
+#define STB_IMAGE_IMPLEMENTATION
+// to use our own image loading:
+// 1. replace this definition with TINYGLTF_NO_STB_IMAGE
+// 2. provide image loader callback with TinyGLTF::SetImageLoader(LoadimageDataFunction LoadImageData, void *user_data)
+
+// tinygltf saves image files using STB
+#define STB_IMAGE_WRITE_IMPLEMENTATION
+// similarly, can override with TINYGLTF_NO_STB_IMAGE_WRITE and TinyGLTF::SetImageWriter(fxn, data)
+
+// Disable reading external images to prevent warnings and speed up the tests.
+// We don't need this for the tests, but still need the filesystem
+// implementation to be defined in order for llprimitive to link correctly.
+#define TINYGLTF_NO_EXTERNAL_IMAGE 1
+
+#include "tinygltf/tiny_gltf.h"
+
+namespace tut
+{
+ struct llgltfmaterial
+ {
+ };
+ typedef test_group<llgltfmaterial> llgltfmaterial_t;
+ typedef llgltfmaterial_t::object llgltfmaterial_object_t;
+ tut::llgltfmaterial_t tut_llgltfmaterial("llgltfmaterial");
+
+ // A positive 32-bit float with a long string representation
+ constexpr F32 test_fraction = 1.09045365e-32;
+ // A larger positive 32-bit float for values that get zeroed if below a threshold
+ constexpr F32 test_fraction_big = 0.109045;
+
+ void apply_test_material_texture_ids(LLGLTFMaterial& material)
+ {
+ material.setBaseColorId(LLUUID::generateNewID());
+ material.setNormalId(LLUUID::generateNewID());
+ material.setOcclusionRoughnessMetallicId(LLUUID::generateNewID());
+ material.setEmissiveId(LLUUID::generateNewID());
+ }
+
+ void apply_test_material_texture_transforms(LLGLTFMaterial& material)
+ {
+ LLGLTFMaterial::TextureTransform test_transform;
+ test_transform.mOffset.mV[VX] = test_fraction;
+ test_transform.mOffset.mV[VY] = test_fraction;
+ test_transform.mScale.mV[VX] = test_fraction;
+ test_transform.mScale.mV[VY] = test_fraction;
+ test_transform.mRotation = test_fraction;
+ for (LLGLTFMaterial::TextureInfo i = LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; i = LLGLTFMaterial::TextureInfo((U32)i + 1))
+ {
+ material.setTextureOffset(i, test_transform.mOffset);
+ material.setTextureScale(i, test_transform.mScale);
+ material.setTextureRotation(i, test_transform.mRotation);
+ }
+ }
+
+ void apply_test_material_factors(LLGLTFMaterial& material)
+ {
+ material.setBaseColorFactor(LLColor4(test_fraction_big, test_fraction_big, test_fraction_big, test_fraction_big));
+ material.setEmissiveColorFactor(LLColor3(test_fraction_big, test_fraction_big, test_fraction_big));
+ material.setMetallicFactor(test_fraction);
+ material.setRoughnessFactor(test_fraction);
+ }
+
+ LLGLTFMaterial create_test_material()
+ {
+ LLGLTFMaterial material;
+
+ apply_test_material_texture_ids(material);
+
+ apply_test_material_texture_transforms(material);
+
+ apply_test_material_factors(material);
+
+ material.setAlphaCutoff(test_fraction);
+ // Because this is the default value, it should append to the extras field to mark it as an override
+ material.setAlphaMode(LLGLTFMaterial::ALPHA_MODE_OPAQUE);
+ // Because this is the default value, it should append to the extras field to mark it as an override
+ material.setDoubleSided(false);
+
+ return material;
+ }
+
+ void ensure_gltf_material_serialize(const std::string& ensure_suffix, const LLGLTFMaterial& material_in)
+ {
+ const std::string json_in = material_in.asJSON();
+ LLGLTFMaterial material_out;
+ std::string warn_msg;
+ std::string error_msg;
+ bool serialize_success = material_out.fromJSON(json_in, warn_msg, error_msg);
+ ensure_equals("LLGLTFMaterial serialization has no warnings: " + ensure_suffix, "", warn_msg);
+ ensure_equals("LLGLTFMaterial serialization has no errors: " + ensure_suffix, "", error_msg);
+ ensure("LLGLTFMaterial serializes successfully: " + ensure_suffix, serialize_success);
+ ensure("LLGLTFMaterial is preserved when deserialized: " + ensure_suffix, material_in == material_out);
+ const std::string json_out = material_out.asJSON();
+ ensure_equals("LLGLTFMaterial is preserved when serialized: " + ensure_suffix, json_in, json_out);
+ }
+
+ void ensure_gltf_material_trimmed(const std::string& material_json, const std::string& must_not_contain)
+ {
+ ensure("LLGLTFMaterial serialization trims property '" + must_not_contain + "'", material_json.find(must_not_contain) == std::string::npos);
+ }
+
+ // Test that GLTF material fields have not changed since these tests were written
+ template<> template<>
+ void llgltfmaterial_object_t::test<1>()
+ {
+#if ADDRESS_SIZE != 32
+#if LL_WINDOWS
+ // If any fields are added/changed, these tests should be updated (consider also updating ASSET_VERSION in LLGLTFMaterial)
+ // This test result will vary between compilers, so only test a single platform
+ ensure_equals("fields supported for GLTF (sizeof check)", sizeof(LLGLTFMaterial), 216);
+#endif
+#endif
+ ensure_equals("LLGLTFMaterial texture info count", (U32)LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT, 4);
+ }
+
+ // Test that occlusion and metallicRoughness are the same (They are different for asset validation. See lluploadmaterial.cpp)
+ template<> template<>
+ void llgltfmaterial_object_t::test<2>()
+ {
+ ensure_equals("LLGLTFMaterial occlusion does not differ from metallic roughness", LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS, LLGLTFMaterial::GLTF_TEXTURE_INFO_OCCLUSION);
+ }
+
+ // Ensure double sided and alpha mode overrides serialize as expected
+ template<> template<>
+ void llgltfmaterial_object_t::test<3>()
+ {
+ const bool doubleSideds[] { false, true };
+ const LLGLTFMaterial::AlphaMode alphaModes[] { LLGLTFMaterial::ALPHA_MODE_OPAQUE, LLGLTFMaterial::ALPHA_MODE_BLEND, LLGLTFMaterial::ALPHA_MODE_MASK };
+ const bool forOverrides[] { false, true };
+
+ for (bool doubleSided : doubleSideds)
+ {
+ for (bool forOverride : forOverrides)
+ {
+ LLGLTFMaterial material;
+ material.setDoubleSided(doubleSided, forOverride);
+ const bool overrideBit = (doubleSided == false) && forOverride;
+ ensure_equals("LLGLTFMaterial: double sided = " + std::to_string(doubleSided) + " override bit when forOverride = " + std::to_string(forOverride), material.mOverrideDoubleSided, overrideBit);
+ ensure_gltf_material_serialize("double sided = " + std::to_string(doubleSided), material);
+ }
+ }
+
+ for (LLGLTFMaterial::AlphaMode alphaMode : alphaModes)
+ {
+ for (bool forOverride : forOverrides)
+ {
+ LLGLTFMaterial material;
+ material.setAlphaMode(alphaMode, forOverride);
+ const bool overrideBit = (alphaMode == LLGLTFMaterial::ALPHA_MODE_OPAQUE) && forOverride;
+ ensure_equals("LLGLTFMaterial: alpha mode = " + std::to_string(alphaMode) + " override bit when forOverride = " + std::to_string(forOverride), material.mOverrideAlphaMode, overrideBit);
+ ensure_gltf_material_serialize("alpha mode = " + std::to_string(alphaMode), material);
+ }
+ }
+ }
+
+ // Test that a GLTF material's transform components serialize as expected
+ template<> template<>
+ void llgltfmaterial_object_t::test<4>()
+ {
+ LLGLTFMaterial material;
+ LLGLTFMaterial::TextureTransform& transform = material.mTextureTransform[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR];
+ transform.mOffset[VX] = 1.f;
+ transform.mOffset[VY] = 2.f;
+ transform.mScale[VX] = 0.05f;
+ transform.mScale[VY] = 100.f;
+ transform.mRotation = 1.571f;
+ ensure_gltf_material_serialize("material with transform", material);
+ }
+
+ // Test that a GLTF material avoids serializing a material unnecessarily
+ template<> template<>
+ void llgltfmaterial_object_t::test<5>()
+ {
+ {
+ const LLGLTFMaterial material;
+ const std::string material_json = material.asJSON();
+ ensure_gltf_material_trimmed(material_json, "pbrMetallicRoughness");
+ ensure_gltf_material_trimmed(material_json, "normalTexture");
+ ensure_gltf_material_trimmed(material_json, "emissiveTexture");
+ ensure_gltf_material_trimmed(material_json, "occlusionTexture");
+ }
+
+ {
+ LLGLTFMaterial metallic_factor_material;
+ metallic_factor_material.setMetallicFactor(0.5);
+ const std::string metallic_factor_material_json = metallic_factor_material.asJSON();
+ ensure_gltf_material_trimmed(metallic_factor_material_json, "baseColorTexture");
+ ensure_gltf_material_trimmed(metallic_factor_material_json, "metallicRoughnessTexture");
+ }
+ }
+
+ // Test that a GLTF material preserves values on serialization
+ template<> template<>
+ void llgltfmaterial_object_t::test<6>()
+ {
+ {
+ const LLGLTFMaterial full_material = create_test_material();
+ ensure_gltf_material_serialize("full material", full_material);
+ }
+
+ {
+ LLGLTFMaterial texture_ids_only_material;
+ apply_test_material_texture_ids(texture_ids_only_material);
+ ensure_gltf_material_serialize("material with texture IDs only", texture_ids_only_material);
+ }
+
+ {
+ LLGLTFMaterial texture_transforms_only_material;
+ apply_test_material_texture_ids(texture_transforms_only_material);
+ ensure_gltf_material_serialize("material with texture transforms only", texture_transforms_only_material);
+ }
+
+ {
+ LLGLTFMaterial factors_only_material;
+ apply_test_material_factors(factors_only_material);
+ ensure_gltf_material_serialize("material with scaling/tint factors only", factors_only_material);
+ }
+ }
+
+ // Test that sDefault is a no-op override
+ template<> template<>
+ void llgltfmaterial_object_t::test<7>()
+ {
+ const LLGLTFMaterial material_asset = create_test_material();
+ LLGLTFMaterial render_material = material_asset;
+ render_material.applyOverride(LLGLTFMaterial::sDefault);
+ ensure("LLGLTFMaterial: sDefault is a no-op override", material_asset == render_material);
+ }
+
+ // Test application of transform overrides
+ template<> template<>
+ void llgltfmaterial_object_t::test<8>()
+ {
+ LLGLTFMaterial override_material;
+ apply_test_material_texture_transforms(override_material);
+ LLGLTFMaterial render_material;
+ render_material.applyOverride(override_material);
+ ensure("LLGLTFMaterial: transform overrides", render_material == override_material);
+ }
+
+ // Test application of flag-based overrides
+ template<> template<>
+ void llgltfmaterial_object_t::test<9>()
+ {
+ {
+ LLGLTFMaterial override_material;
+ override_material.setAlphaMode(LLGLTFMaterial::ALPHA_MODE_BLEND, true);
+ override_material.setDoubleSided(true, true);
+
+ LLGLTFMaterial render_material;
+
+ render_material.applyOverride(override_material);
+
+ ensure("LLGLTFMaterial: extra overrides with non-default values applied over default", render_material == override_material);
+ }
+ {
+ LLGLTFMaterial override_material;
+ override_material.setAlphaMode(LLGLTFMaterial::ALPHA_MODE_OPAQUE, true);
+ override_material.setDoubleSided(false, true);
+
+ LLGLTFMaterial render_material;
+ override_material.setAlphaMode(LLGLTFMaterial::ALPHA_MODE_BLEND, false);
+ override_material.setDoubleSided(true, false);
+
+ render_material.applyOverride(override_material);
+ // Not interested in these flags for equality comparison
+ override_material.mOverrideDoubleSided = false;
+ override_material.mOverrideAlphaMode = false;
+
+ ensure("LLGLTFMaterial: extra overrides with default values applied over non-default", render_material == override_material);
+ }
+ }
+
+ // Test application of texture overrides
+ template<> template<>
+ void llgltfmaterial_object_t::test<10>()
+ {
+ const U32 texture_count = 2;
+ const LLUUID override_textures[texture_count] = { LLUUID::null, LLUUID::generateNewID() };
+ const LLUUID asset_textures[texture_count] = { LLUUID::generateNewID(), LLUUID::null };
+ for (U32 i = 0; i < texture_count; ++i)
+ {
+ LLGLTFMaterial override_material;
+ const LLUUID& override_texture = override_textures[i];
+ for (LLGLTFMaterial::TextureInfo j = LLGLTFMaterial::TextureInfo(0); j < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; j = LLGLTFMaterial::TextureInfo(U32(j) + 1))
+ {
+ override_material.setTextureId(j, override_texture, true);
+ }
+
+ LLGLTFMaterial render_material;
+ const LLUUID& asset_texture = asset_textures[i];
+ for (LLGLTFMaterial::TextureInfo j = LLGLTFMaterial::TextureInfo(0); j < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; j = LLGLTFMaterial::TextureInfo(U32(j) + 1))
+ {
+ render_material.setTextureId(j, asset_texture, false);
+ }
+
+ render_material.applyOverride(override_material);
+
+ for (LLGLTFMaterial::TextureInfo j = LLGLTFMaterial::TextureInfo(0); j < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; j = LLGLTFMaterial::TextureInfo(U32(j) + 1))
+ {
+ const LLUUID& render_texture = render_material.mTextureId[j];
+ ensure_equals("LLGLTFMaterial: Override texture ID " + override_texture.asString() + " replaces underlying texture ID " + asset_texture.asString(), render_texture, override_texture);
+ }
+ }
+ }
+
+ // Test non-persistence of default value flags in overrides
+ template<> template<>
+ void llgltfmaterial_object_t::test<11>()
+ {
+ const S32 non_default_alpha_modes[] = { LLGLTFMaterial::ALPHA_MODE_BLEND, LLGLTFMaterial::ALPHA_MODE_MASK };
+ for (S32 non_default_alpha_mode : non_default_alpha_modes)
+ {
+ LLGLTFMaterial material;
+ // Set default alpha mode
+ material.setAlphaMode(LLGLTFMaterial::ALPHA_MODE_OPAQUE, true);
+ ensure_equals("LLGLTFMaterial: alpha mode override flag set", material.mOverrideAlphaMode, true);
+ // Set non-default alpha mode
+ material.setAlphaMode(non_default_alpha_mode, true);
+ ensure_equals("LLGLTFMaterial: alpha mode override flag unset", material.mOverrideAlphaMode, false);
+ }
+
+ {
+ // Set default double sided
+ LLGLTFMaterial material;
+ material.setDoubleSided(false, true);
+ ensure_equals("LLGLTFMaterial: double sided override flag set", material.mOverrideDoubleSided, true);
+ // Set non-default double sided
+ material.setDoubleSided(true, true);
+ ensure_equals("LLGLTFMaterial: double sided override flag unset", material.mOverrideDoubleSided, false);
+ }
+ }
+}
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index 7fe8b02cc5..56377069bb 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -648,11 +648,6 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, bool texture, bool batch_textur
}
}
- //if (params.mGroup) // TOO LATE!
- //{
- // params.mGroup->rebuildMesh();
- //}
-
params.mVertexBuffer->setBuffer();
params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
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 14ebfa451a..41085afb3d 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
@@ -1975,7 +1862,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);
@@ -1986,24 +1875,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"));
}
@@ -2017,7 +1906,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
{
@@ -2040,8 +1933,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;
@@ -2584,7 +2478,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)
@@ -2593,16 +2487,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)
@@ -2638,7 +2532,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)
@@ -2751,20 +2645,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());
@@ -2774,15 +2671,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/llpanelface.cpp b/indra/newview/llpanelface.cpp
index ce086f2520..cb7bc7b5df 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -3825,34 +3825,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)
@@ -3867,7 +3845,6 @@ struct LLPanelFaceUpdateFunctor : public LLSelectedObjectFunctor
}
private:
bool mUpdateMedia;
- bool mUpdatePbr;
};
struct LLPanelFaceNavigateHomeFunctor : public LLSelectedTEFunctor
@@ -4003,7 +3980,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);
}
@@ -4364,7 +4341,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/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index 0cbc2b0bad..3c34d6ee65 100644
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -755,6 +755,7 @@ void LLPanelVolume::sendIsReflectionProbe()
if (value && !old_value)
{ // has become a reflection probe, slam to a 10m sphere and pop up a message
// warning people about the pitfalls of reflection probes
+#if 0
auto* select_mgr = LLSelectMgr::getInstance();
mObject->setScale(LLVector3(10.f, 10.f, 10.f));
@@ -768,6 +769,7 @@ void LLPanelVolume::sendIsReflectionProbe()
params.getPathParams().setCurveType(LL_PCODE_PATH_CIRCLE);
params.getProfileParams().setCurveType(LL_PCODE_PROFILE_CIRCLE_HALF);
mObject->updateVolume(params);
+#endif
LLNotificationsUtil::add("ReflectionProbeApplied");
}
@@ -1343,6 +1345,12 @@ void LLPanelVolume::onCommitProbe(LLUICtrl* ctrl, void* userdata)
if (volobjp->setReflectionProbeIsBox(is_box))
{
// make the volume match the probe
+ auto* select_mgr = LLSelectMgr::getInstance();
+
+ select_mgr->selectionUpdatePhantom(true);
+ select_mgr->selectionSetGLTFMaterial(LLUUID::null);
+ select_mgr->selectionSetAlphaOnly(0.f);
+
U8 profile, path;
if (!is_box)
diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp
index fd2906fa37..4377f26633 100644
--- a/indra/newview/llreflectionmapmanager.cpp
+++ b/indra/newview/llreflectionmapmanager.cpp
@@ -799,8 +799,12 @@ void LLReflectionMapManager::updateUniforms()
llassert(refmap->mCubeIndex >= 0); // should always be true, if not, getReflectionMaps is bugged
{
- //LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - refSphere");
+ if (refmap->mViewerObject)
+ { // have active manual probes live-track the object they're associated with
+ refmap->mOrigin.load3(refmap->mViewerObject->getPositionAgent().mV);
+ refmap->mRadius = refmap->mViewerObject->getScale().mV[0] * 0.5f;
+ }
modelview.affineTransform(refmap->mOrigin, oa);
rpd.refSphere[count].set(oa.getF32ptr());
rpd.refSphere[count].mV[3] = refmap->mRadius;
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/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 3c0a08cee1..e217ede067 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -4992,10 +4992,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]);
}
}
@@ -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);
}
}
}
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 9f51509f96..fec9f1cdd1 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -6681,7 +6681,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
{ //100% transparent, don't render unless we're highlighting transparent
registerFace(group, facep, LLRenderPass::PASS_ALPHA_INVISIBLE);
}
- else if (facep->canRenderAsMask())
+ else if (facep->canRenderAsMask() && !hud_group)
{
if (te->getFullbright() || LLPipeline::sNoAlpha)
{
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 388dee00db..e814b77725 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -4687,7 +4687,7 @@ void LLPipeline::renderDebug()
mReflectionMapManager.renderDebug();
}
- if (gSavedSettings.getBOOL("RenderReflectionProbeVolumes"))
+ if (gSavedSettings.getBOOL("RenderReflectionProbeVolumes") && !hud_only)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("probe debug display");
@@ -4740,7 +4740,7 @@ void LLPipeline::renderDebug()
}
}
- if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
+ if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !hud_only)
{
LLVertexBuffer::unbind();
@@ -8572,10 +8572,13 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
shader.uniform1f(LLShaderMgr::PROJECTOR_SHADOW_FADE, 1.f);
}
- //if (!gCubeSnapshot)
+ // make sure we're not already targeting the same spot light with both shadow maps
+ llassert(mTargetShadowSpotLight[0] != mTargetShadowSpotLight[1] || mTargetShadowSpotLight[0].isNull());
+
+ if (!gCubeSnapshot)
{
LLDrawable* potential = drawablep;
- //determine if this is a good light for casting shadows
+ //determine if this light is higher priority than one of the existing spot shadows
F32 m_pri = volume->getSpotLightPriority();
for (U32 i = 0; i < 2; i++)
@@ -8584,7 +8587,7 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
if (mTargetShadowSpotLight[i].notNull())
{
- pri = mTargetShadowSpotLight[i]->getVOVolume()->getSpotLightPriority();
+ pri = mTargetShadowSpotLight[i]->getVOVolume()->getSpotLightPriority();
}
if (m_pri > pri)
@@ -8597,6 +8600,9 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
}
}
+ // make sure we didn't end up targeting the same spot light with both shadow maps
+ llassert(mTargetShadowSpotLight[0] != mTargetShadowSpotLight[1] || mTargetShadowSpotLight[0].isNull());
+
LLViewerTexture* img = volume->getLightTexture();
if (img == NULL)
@@ -9886,7 +9892,6 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
}
}
-
//hack to disable projector shadows
bool gen_shadow = RenderShadowDetail > 1;
@@ -9898,6 +9903,9 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
F32 fade_amt = gFrameIntervalSeconds.value()
* llmax(LLTrace::get_frame_recording().getLastRecording().getSum(*velocity_stat) / LLTrace::get_frame_recording().getLastRecording().getDuration().value(), 1.0);
+ // should never happen
+ llassert(mTargetShadowSpotLight[0] != mTargetShadowSpotLight[1] || mTargetShadowSpotLight[0].isNull());
+
//update shadow targets
for (U32 i = 0; i < 2; i++)
{ //for each current shadow
@@ -9928,6 +9936,9 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
}
}
+ // this should never happen
+ llassert(mShadowSpotLight[0] != mShadowSpotLight[1] || mShadowSpotLight[0].isNull());
+
for (S32 i = 0; i < 2; i++)
{
set_current_modelview(saved_view);
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 7cdf4af5c2..711be76764 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -12041,7 +12041,7 @@ Material successfully created. Asset ID: [ASSET_ID]
name="ReflectionProbeApplied"
persist="true"
type="alertmodal">
- Your object has been set to the default Reflection Probe state, which is an invisible, phantom, 5m sphere. To learn more about Reflection Probes and how to use them, see the Knowledge Base.
+ WARNING: You have made your object a Refelction Probe. Continuing to manipulate the object while it is a probe will implicitly change the object to mimic its influence volume and will make irreversible changes to the object. If you don't know what a reflection probe is, uncheck "Reflection Probe" immediately. To learn more about Reflection Probes and how to use them, see https://wiki.secondlife.com/wiki/PBR_Materials#Understanding_and_Assisting_the_New_Reflections_System.
<usetemplate ignoretext="Reflection Probe tips"
name="okignore"
yestext="OK"/>