summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorDave Parks <davep@lindenlab.com>2022-11-01 15:17:22 -0500
committerDave Parks <davep@lindenlab.com>2022-11-01 15:17:22 -0500
commita4ad75e93c20f140d9503c119201128b0f9e4d0e (patch)
tree32bc443fd0fdc68e50fbaea78020248bd9e3a052 /indra
parent9f21fba6d9a28cd1b324a115a0a2f86613a134e7 (diff)
SL-18520 WIP - Use off-by-epsilon and special UUID identifier hacks to allow overriding to default values.
Diffstat (limited to 'indra')
-rw-r--r--indra/llprimitive/llgltfmaterial.cpp176
-rw-r--r--indra/llprimitive/llgltfmaterial.h69
-rw-r--r--indra/newview/llmaterialeditor.cpp50
3 files changed, 182 insertions, 113 deletions
diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp
index cd629dbbd8..4b1f89f99f 100644
--- a/indra/llprimitive/llgltfmaterial.cpp
+++ b/indra/llprimitive/llgltfmaterial.cpp
@@ -28,6 +28,7 @@
#include "llgltfmaterial.h"
+// 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";
@@ -35,6 +36,9 @@ const char* GLTF_FILE_EXTENSION_TRANSFORM_SCALE = "scale";
const char* GLTF_FILE_EXTENSION_TRANSFORM_OFFSET = "offset";
const char* 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");
+
LLGLTFMaterial::LLGLTFMaterial(const LLGLTFMaterial& rhs)
{
*this = rhs;
@@ -296,64 +300,144 @@ void LLGLTFMaterial::writeToTexture(tinygltf::Model& model, T& texture_info, Tex
texture_info.extensions[GLTF_FILE_EXTENSION_TRANSFORM] = tinygltf::Value(transform_map);
}
+// static
+void LLGLTFMaterial::hackOverrideUUID(LLUUID& id)
+{
+ if (id == LLUUID::null)
+ {
+ id = GLTF_OVERRIDE_NULL_UUID;
+ }
+}
-void LLGLTFMaterial::setBaseColorId(const LLUUID& id)
+void LLGLTFMaterial::setBaseColorId(const LLUUID& id, bool for_override)
{
mBaseColorId = id;
+ if (for_override)
+ {
+ hackOverrideUUID(mBaseColorId);
+ }
}
-void LLGLTFMaterial::setNormalId(const LLUUID& id)
+void LLGLTFMaterial::setNormalId(const LLUUID& id, bool for_override)
{
mNormalId = id;
+ if (for_override)
+ {
+ hackOverrideUUID(mNormalId);
+ }
}
-void LLGLTFMaterial::setMetallicRoughnessId(const LLUUID& id)
+void LLGLTFMaterial::setMetallicRoughnessId(const LLUUID& id, bool for_override)
{
mMetallicRoughnessId = id;
+ if (for_override)
+ {
+ hackOverrideUUID(mMetallicRoughnessId);
+ }
}
-void LLGLTFMaterial::setEmissiveId(const LLUUID& id)
+void LLGLTFMaterial::setEmissiveId(const LLUUID& id, bool for_override)
{
mEmissiveId = id;
+ if (for_override)
+ {
+ hackOverrideUUID(mEmissiveId);
+ }
}
-void LLGLTFMaterial::setBaseColorFactor(const LLColor3& baseColor, F32 transparency)
+void LLGLTFMaterial::setBaseColorFactor(const LLColor4& baseColor, bool for_override)
{
- mBaseColor.set(baseColor, transparency);
+ mBaseColor.set(baseColor);
mBaseColor.clamp();
+
+ if (for_override)
+ { // hack -- nudge off of default value
+ if (mBaseColor == getDefaultBaseColor())
+ {
+ mBaseColor.mV[3] -= FLT_EPSILON;
+ }
+ }
}
-void LLGLTFMaterial::setAlphaCutoff(F32 cutoff)
+void LLGLTFMaterial::setAlphaCutoff(F32 cutoff, bool for_override)
{
mAlphaCutoff = llclamp(cutoff, 0.f, 1.f);
+ if (for_override)
+ { // hack -- nudge off of default value
+ if (mAlphaCutoff == getDefaultAlphaCutoff())
+ {
+ mAlphaCutoff -= FLT_EPSILON;
+ }
+ }
}
-void LLGLTFMaterial::setEmissiveColorFactor(const LLColor3& emissiveColor)
+void LLGLTFMaterial::setEmissiveColorFactor(const LLColor3& emissiveColor, bool for_override)
{
mEmissiveColor = emissiveColor;
mEmissiveColor.clamp();
+
+ if (for_override)
+ { // hack -- nudge off of default value
+ if (mEmissiveColor == getDefaultEmissiveColor())
+ {
+ mEmissiveColor.mV[0] += FLT_EPSILON;
+ }
+ }
+}
+
+void LLGLTFMaterial::setMetallicFactor(F32 metallic, bool for_override)
+{
+ mMetallicFactor = llclamp(metallic, 0.f, for_override ? 1.f - FLT_EPSILON : 1.f);
}
-void LLGLTFMaterial::setMetallicFactor(F32 metallic)
+void LLGLTFMaterial::setRoughnessFactor(F32 roughness, bool for_override)
{
- mMetallicFactor = llclamp(metallic, 0.f, 1.f);
+ mRoughnessFactor = llclamp(roughness, 0.f, for_override ? 1.f - FLT_EPSILON : 1.f);
}
-void LLGLTFMaterial::setRoughnessFactor(F32 roughness)
+void LLGLTFMaterial::setAlphaMode(const std::string& mode, bool for_override)
{
- mRoughnessFactor = llclamp(roughness, 0.f, 1.f);
+ S32 m = getDefaultAlphaMode();
+ if (mode == "MASK")
+ {
+ m = ALPHA_MODE_MASK;
+ }
+ else if (mode == "BLEND")
+ {
+ m = ALPHA_MODE_BLEND;
+ }
+
+ setAlphaMode(m, for_override);
+}
+
+const char* LLGLTFMaterial::getAlphaMode() const
+{
+ switch (mAlphaMode)
+ {
+ case ALPHA_MODE_MASK: return "MASK";
+ case ALPHA_MODE_BLEND: return "BLEND";
+ default: return "OPAQUE";
+ }
}
-void LLGLTFMaterial::setAlphaMode(S32 mode)
+void LLGLTFMaterial::setAlphaMode(S32 mode, bool for_override)
{
mAlphaMode = (AlphaMode) llclamp(mode, (S32) ALPHA_MODE_OPAQUE, (S32) ALPHA_MODE_MASK);
+ if (for_override)
+ {
+ // TODO: what do?
+ }
}
-void LLGLTFMaterial::setDoubleSided(bool double_sided)
+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)
+ {
+ // TODO: what do?
+ }
}
void LLGLTFMaterial::setTextureOffset(TextureInfo texture_info, const LLVector2& offset)
@@ -371,102 +455,102 @@ void LLGLTFMaterial::setTextureRotation(TextureInfo texture_info, float rotation
mTextureTransform[texture_info].mRotation = rotation;
}
-// Default value accessors
+// Default value accessors (NOTE: these MUST match the GLTF specification)
+
+// Make a static default material for accessors
+const LLGLTFMaterial LLGLTFMaterial::sDefault;
LLUUID LLGLTFMaterial::getDefaultBaseColorId()
{
- return LLUUID::null;
+ return sDefault.mBaseColorId;
}
LLUUID LLGLTFMaterial::getDefaultNormalId()
{
- return LLUUID::null;
+ return sDefault.mNormalId;
}
LLUUID LLGLTFMaterial::getDefaultEmissiveId()
{
- return LLUUID::null;
+ return sDefault.mEmissiveId;
}
LLUUID LLGLTFMaterial::getDefaultMetallicRoughnessId()
{
- return LLUUID::null;
+ return sDefault.mMetallicRoughnessId;
}
F32 LLGLTFMaterial::getDefaultAlphaCutoff()
{
- return 0.f;
+ return sDefault.mAlphaCutoff;
}
S32 LLGLTFMaterial::getDefaultAlphaMode()
{
- return (S32) ALPHA_MODE_OPAQUE;
+ return (S32) sDefault.mAlphaMode;
}
F32 LLGLTFMaterial::getDefaultMetallicFactor()
{
- return 0.f;
+ return sDefault.mMetallicFactor;
}
F32 LLGLTFMaterial::getDefaultRoughnessFactor()
{
- return 0.f;
+ return sDefault.mRoughnessFactor;
}
LLColor4 LLGLTFMaterial::getDefaultBaseColor()
{
- return LLColor4::white;
+ return sDefault.mBaseColor;
}
LLColor3 LLGLTFMaterial::getDefaultEmissiveColor()
{
- return LLColor3::black;
+ return sDefault.mEmissiveColor;
}
bool LLGLTFMaterial::getDefaultDoubleSided()
{
- return false;
+ return sDefault.mDoubleSided;
}
LLVector2 LLGLTFMaterial::getDefaultTextureOffset()
{
- return LLVector2(0.f, 0.f);
+ return sDefault.mTextureTransform[0].mOffset;
}
LLVector2 LLGLTFMaterial::getDefaultTextureScale()
{
- return LLVector2(1.f, 1.f);
+ return sDefault.mTextureTransform[0].mScale;
}
F32 LLGLTFMaterial::getDefaultTextureRotation()
{
- return 0.f;
+ return sDefault.mTextureTransform[0].mRotation;
}
-void LLGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat)
+// static
+void LLGLTFMaterial::applyOverrideUUID(LLUUID& dst_id, const LLUUID& override_id)
{
- LL_PROFILE_ZONE_SCOPED;
- // TODO: potentially reimplement this with a more general purpose JSON merge
-
- if (override_mat.mBaseColorId != getDefaultBaseColorId())
+ if (override_id != GLTF_OVERRIDE_NULL_UUID)
{
- mBaseColorId = override_mat.mBaseColorId;
+ dst_id = override_id;
}
-
- if (override_mat.mNormalId != getDefaultNormalId())
+ else
{
- mNormalId = override_mat.mNormalId;
+ dst_id = LLUUID::null;
}
+}
- if (override_mat.mMetallicRoughnessId != getDefaultMetallicRoughnessId())
- {
- mMetallicRoughnessId = override_mat.mMetallicRoughnessId;
- }
+void LLGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat)
+{
+ LL_PROFILE_ZONE_SCOPED;
- if (override_mat.mEmissiveId != getDefaultEmissiveId())
- {
- mEmissiveId = override_mat.mEmissiveId;
- }
+ applyOverrideUUID(mBaseColorId, override_mat.mBaseColorId);
+ applyOverrideUUID(mNormalId, override_mat.mNormalId);
+ applyOverrideUUID(mMetallicRoughnessId, override_mat.mMetallicRoughnessId);
+ applyOverrideUUID(mEmissiveId, override_mat.mEmissiveId);
if (override_mat.mBaseColor != getDefaultBaseColor())
{
diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h
index d94ce6e281..a385539cc5 100644
--- a/indra/llprimitive/llgltfmaterial.h
+++ b/indra/llprimitive/llgltfmaterial.h
@@ -45,6 +45,9 @@ class LLGLTFMaterial : public LLRefCount
{
public:
+ // default material for reference
+ static const LLGLTFMaterial sDefault;
+
struct TextureTransform
{
LLVector2 mOffset = { 0.f, 0.f };
@@ -69,12 +72,13 @@ public:
LLUUID mMetallicRoughnessId;
LLUUID mEmissiveId;
+ // NOTE : initialize values to defaults according to the GLTF spec
LLColor4 mBaseColor = LLColor4(1, 1, 1, 1);
LLColor3 mEmissiveColor = LLColor3(0, 0, 0);
- F32 mMetallicFactor = 0.f;
- F32 mRoughnessFactor = 0.f;
- F32 mAlphaCutoff = 0.f;
+ F32 mMetallicFactor = 1.f;
+ F32 mRoughnessFactor = 1.f;
+ F32 mAlphaCutoff = 0.5f;
bool mDoubleSided = false;
AlphaMode mAlphaMode = ALPHA_MODE_OPAQUE;
@@ -105,19 +109,22 @@ public:
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 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 setEmissiveId(const LLUUID& id, bool for_override = false);
- void setBaseColorId(const LLUUID& id);
- void setNormalId(const LLUUID& id);
- void setMetallicRoughnessId(const LLUUID& id);
- void setEmissiveId(const LLUUID& id);
+ void setBaseColorFactor(const LLColor4& baseColor, bool for_override = false);
+ void setAlphaCutoff(F32 cutoff, bool for_override = false);
+ void setEmissiveColorFactor(const LLColor3& emissiveColor, bool for_override = false);
+ void setMetallicFactor(F32 metallic, bool for_override = false);
+ void setRoughnessFactor(F32 roughness, bool for_override = false);
+ void setAlphaMode(S32 mode, bool for_override = false);
+ void setDoubleSided(bool double_sided, bool for_override = false);
- void setBaseColorFactor(const LLColor3& baseColor, F32 transparency);
- void setAlphaCutoff(F32 cutoff);
- void setEmissiveColorFactor(const LLColor3& emissiveColor);
- void setMetallicFactor(F32 metallic);
- void setRoughnessFactor(F32 roughness);
- void setAlphaMode(S32 mode);
- void setDoubleSided(bool double_sided);
+ //NOTE: texture offsets only exist in overrides, so "for_override" is not needed
void setTextureOffset(TextureInfo texture_info, const LLVector2& offset);
void setTextureScale(TextureInfo texture_info, const LLVector2& scale);
@@ -139,34 +146,16 @@ public:
static LLVector2 getDefaultTextureScale();
static F32 getDefaultTextureRotation();
+
+ static void hackOverrideUUID(LLUUID& id);
+ static void applyOverrideUUID(LLUUID& dst_id, const LLUUID& override_id);
+
// set mAlphaMode from string.
// Anything otherthan "MASK" or "BLEND" sets mAlphaMode to ALPHA_MODE_OPAQUE
- void setAlphaMode(const std::string& mode)
- {
- if (mode == "MASK")
- {
- mAlphaMode = ALPHA_MODE_MASK;
- }
- else if (mode == "BLEND")
- {
- mAlphaMode = ALPHA_MODE_BLEND;
- }
- else
- {
- mAlphaMode = ALPHA_MODE_OPAQUE;
- }
- }
-
- const char* getAlphaMode() const
- {
- switch (mAlphaMode)
- {
- case ALPHA_MODE_MASK: return "MASK";
- case ALPHA_MODE_BLEND: return "BLEND";
- default: return "OPAQUE";
- }
- }
-
+ void setAlphaMode(const std::string& mode, bool for_override = false);
+
+ const char* getAlphaMode() const;
+
// set the contents of this LLGLTFMaterial from the given json
// returns true if successful
// json - the json text to load from
diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp
index c99e7307ed..0ae8dcbcf7 100644
--- a/indra/newview/llmaterialeditor.cpp
+++ b/indra/newview/llmaterialeditor.cpp
@@ -70,21 +70,20 @@ static const std::string LIVE_MATERIAL_EDITOR_KEY = "Live Editor";
// Dirty flags
static const U32 MATERIAL_BASE_COLOR_DIRTY = 0x1 << 0;
-static const U32 MATERIAL_BASE_TRANSPARENCY_DIRTY = 0x1 << 1;
-static const U32 MATERIAL_BASE_COLOR_TEX_DIRTY = 0x1 << 2;
+static const U32 MATERIAL_BASE_COLOR_TEX_DIRTY = 0x1 << 1;
-static const U32 MATERIAL_NORMAL_TEX_DIRTY = 0x1 << 3;
+static const U32 MATERIAL_NORMAL_TEX_DIRTY = 0x1 << 2;
-static const U32 MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY = 0x1 << 4;
-static const U32 MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY = 0x1 << 5;
-static const U32 MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY = 0x1 << 6;
+static const U32 MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY = 0x1 << 3;
+static const U32 MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY = 0x1 << 4;
+static const U32 MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY = 0x1 << 5;
-static const U32 MATERIAL_EMISIVE_COLOR_DIRTY = 0x1 << 7;
-static const U32 MATERIAL_EMISIVE_TEX_DIRTY = 0x1 << 8;
+static const U32 MATERIAL_EMISIVE_COLOR_DIRTY = 0x1 << 6;
+static const U32 MATERIAL_EMISIVE_TEX_DIRTY = 0x1 << 7;
-static const U32 MATERIAL_DOUBLE_SIDED_DIRTY = 0x1 << 9;
-static const U32 MATERIAL_ALPHA_MODE_DIRTY = 0x1 << 10;
-static const U32 MATERIAL_ALPHA_CUTOFF_DIRTY = 0x1 << 11;
+static const U32 MATERIAL_DOUBLE_SIDED_DIRTY = 0x1 << 8;
+static const U32 MATERIAL_ALPHA_MODE_DIRTY = 0x1 << 9;
+static const U32 MATERIAL_ALPHA_CUTOFF_DIRTY = 0x1 << 10;
LLUUID LLMaterialEditor::mOverrideObjectId;
S32 LLMaterialEditor::mOverrideObjectTE = -1;
@@ -384,7 +383,7 @@ BOOL LLMaterialEditor::postBuild()
// BaseColor
childSetCommitCallback("base color", changes_callback, (void*)&MATERIAL_BASE_COLOR_DIRTY);
- childSetCommitCallback("transparency", changes_callback, (void*)&MATERIAL_BASE_TRANSPARENCY_DIRTY);
+ childSetCommitCallback("transparency", changes_callback, (void*)&MATERIAL_BASE_COLOR_DIRTY);
childSetCommitCallback("alpha mode", changes_callback, (void*)&MATERIAL_ALPHA_MODE_DIRTY);
childSetCommitCallback("alpha cutoff", changes_callback, (void*)&MATERIAL_ALPHA_CUTOFF_DIRTY);
@@ -2263,55 +2262,52 @@ public:
// Override object's values with values from editor where appropriate
if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_COLOR_DIRTY)
{
- material->mBaseColor = mEditor->getBaseColor();
- }
- if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_TRANSPARENCY_DIRTY)
- {
- material->mBaseColor.mV[3] = mEditor->getTransparency();
+ LLColor4 baseColor = mEditor->getBaseColor();
+ material->setBaseColorFactor(mEditor->getBaseColor(), true);
}
if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_COLOR_TEX_DIRTY)
{
- material->mBaseColorId = mEditor->getBaseColorId();
+ material->setBaseColorId(mEditor->getBaseColorId(), true);
}
if (mEditor->getUnsavedChangesFlags() & MATERIAL_NORMAL_TEX_DIRTY)
{
- material->mNormalId = mEditor->getNormalId();
+ material->setNormalId(mEditor->getNormalId(), true);
}
if (mEditor->getUnsavedChangesFlags() & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY)
{
- material->mMetallicRoughnessId = mEditor->getMetallicRoughnessId();
+ material->setMetallicRoughnessId(mEditor->getMetallicRoughnessId(), true);
}
if (mEditor->getUnsavedChangesFlags() & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY)
{
- material->mMetallicFactor = mEditor->getMetalnessFactor();
+ material->setMetallicFactor(mEditor->getMetalnessFactor(), true);
}
if (mEditor->getUnsavedChangesFlags() & MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY)
{
- material->mRoughnessFactor = mEditor->getRoughnessFactor();
+ material->setRoughnessFactor(mEditor->getRoughnessFactor(), true);
}
if (mEditor->getUnsavedChangesFlags() & MATERIAL_EMISIVE_COLOR_DIRTY)
{
- material->mEmissiveColor = mEditor->getEmissiveColor();
+ material->setEmissiveColorFactor(LLColor3(mEditor->getEmissiveColor()), true);
}
if (mEditor->getUnsavedChangesFlags() & MATERIAL_EMISIVE_TEX_DIRTY)
{
- material->mEmissiveId = mEditor->getEmissiveId();
+ material->setEmissiveId(mEditor->getEmissiveId(), true);
}
if (mEditor->getUnsavedChangesFlags() & MATERIAL_DOUBLE_SIDED_DIRTY)
{
- material->mDoubleSided = mEditor->getDoubleSided();
+ material->setDoubleSided(mEditor->getDoubleSided(), true);
}
if (mEditor->getUnsavedChangesFlags() & MATERIAL_ALPHA_MODE_DIRTY)
{
- material->setAlphaMode(mEditor->getAlphaMode());
+ material->setAlphaMode(mEditor->getAlphaMode(), true);
}
if (mEditor->getUnsavedChangesFlags() & MATERIAL_ALPHA_CUTOFF_DIRTY)
{
- material->mAlphaCutoff = mEditor->getAlphaCutoff();
+ material->setAlphaCutoff(mEditor->getAlphaCutoff(), true);
}
std::string overrides_json = material->asJSON();