summaryrefslogtreecommitdiff
path: root/indra/llinventory
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llinventory')
-rw-r--r--indra/llinventory/llsettingsbase.cpp192
-rw-r--r--indra/llinventory/llsettingsbase.h26
-rw-r--r--indra/llinventory/llsettingssky.cpp10
-rw-r--r--indra/llinventory/llsettingswater.cpp2
4 files changed, 154 insertions, 76 deletions
diff --git a/indra/llinventory/llsettingsbase.cpp b/indra/llinventory/llsettingsbase.cpp
index 2adbb213e6..80680948b5 100644
--- a/indra/llinventory/llsettingsbase.cpp
+++ b/indra/llinventory/llsettingsbase.cpp
@@ -80,7 +80,7 @@ LLSettingsBase::LLSettingsBase(const LLSD setting) :
//=========================================================================
void LLSettingsBase::lerpSettings(const LLSettingsBase &other, F64 mix)
{
- mSettings = interpolateSDMap(mSettings, other.mSettings, mix);
+ mSettings = interpolateSDMap(mSettings, other.mSettings, other.getParameterMap(), mix);
setDirtyFlag(true);
}
@@ -158,7 +158,7 @@ LLSD LLSettingsBase::combineSDMaps(const LLSD &settings, const LLSD &other) cons
return newSettings;
}
-LLSD LLSettingsBase::interpolateSDMap(const LLSD &settings, const LLSD &other, F64 mix) const
+LLSD LLSettingsBase::interpolateSDMap(const LLSD &settings, const LLSD &other, const parammapping_t& defaults, F64 mix) const
{
LLSD newSettings;
@@ -173,81 +173,33 @@ LLSD LLSettingsBase::interpolateSDMap(const LLSD &settings, const LLSD &other, F
if (skip.find(key_name) != skip.end())
continue;
- if (!other.has(key_name))
- { // The other does not contain this setting, keep the original value
- // TODO: Should I blend this out instead?
- newSettings[key_name] = value;
- continue;
- }
- LLSD::Type setting_type = value.type();
- LLSD other_value = other[key_name];
-
- if (other_value.type() != setting_type)
- {
- // The data type mismatched between this and other. Hard switch when we pass the break point
- // but issue a warning.
- LL_WARNS("SETTINGS") << "Setting lerp between mismatched types for '" << key_name << "'." << LL_ENDL;
- newSettings[key_name] = (mix > BREAK_POINT) ? other_value : value;
- continue;
+ LLSD other_value;
+ if (other.has(key_name))
+ {
+ other_value = other[key_name];
}
-
- switch (setting_type)
+ else
{
- case LLSD::TypeInteger:
- // lerp between the two values rounding the result to the nearest integer.
- newSettings[key_name] = LLSD::Integer(llroundf(lerp(value.asReal(), other_value.asReal(), mix)));
- break;
- case LLSD::TypeReal:
- // lerp between the two values.
- newSettings[key_name] = LLSD::Real(lerp(value.asReal(), other_value.asReal(), mix));
- break;
- case LLSD::TypeMap:
- // deep copy.
- newSettings[key_name] = interpolateSDMap(value, other_value, mix);
- break;
-
- case LLSD::TypeArray:
+ parammapping_t::const_iterator def_iter = defaults.find(key_name);
+ if (def_iter != defaults.end())
{
- LLSD newvalue(LLSD::emptyArray());
-
- if (slerps.find(key_name) != slerps.end())
- {
- LLQuaternion a(value);
- LLQuaternion b(other_value);
- LLQuaternion q = slerp(mix, a, b);
- newvalue = q.getValue();
- }
- else
- { // TODO: We could expand this to inspect the type and do a deep lerp based on type.
- // for now assume a heterogeneous array of reals.
- size_t len = std::max(value.size(), other_value.size());
-
- for (size_t i = 0; i < len; ++i)
- {
-
- newvalue[i] = lerp(value[i].asReal(), other_value[i].asReal(), mix);
- }
- }
-
- newSettings[key_name] = newvalue;
+ other_value = def_iter->second.getDefaultValue();
+ }
+ else if (value.type() == LLSD::TypeMap)
+ {
+ // interpolate in case there are defaults inside (part of legacy)
+ other_value = LLSDMap();
+ }
+ else
+ {
+ // The other or defaults does not contain this setting, keep the original value
+ // TODO: Should I blend this out instead?
+ newSettings[key_name] = value;
+ continue;
}
-
- break;
-
- case LLSD::TypeUUID:
- newSettings[key_name] = value.asUUID();
- break;
-
-// case LLSD::TypeBoolean:
-// case LLSD::TypeString:
-// case LLSD::TypeURI:
-// case LLSD::TypeBinary:
-// case LLSD::TypeDate:
- default:
- // atomic or unknown data types. Lerping between them does not make sense so switch at the break.
- newSettings[key_name] = (mix > BREAK_POINT) ? other_value : value;
- break;
}
+
+ newSettings[key_name] = interpolateSDValue(key_name, value, other_value, defaults, mix, slerps);
}
// Special handling cases
@@ -264,6 +216,27 @@ LLSD LLSettingsBase::interpolateSDMap(const LLSD &settings, const LLSD &other, F
// Now add anything that is in other but not in the settings
for (LLSD::map_const_iterator it = other.beginMap(); it != other.endMap(); ++it)
{
+ std::string key_name = (*it).first;
+
+ if (skip.find(key_name) != skip.end())
+ continue;
+
+ if (settings.has(key_name))
+ continue;
+
+ parammapping_t::const_iterator def_iter = defaults.find(key_name);
+ if (def_iter != defaults.end())
+ {
+ // Blend against default value
+ newSettings[key_name] = interpolateSDValue(key_name, def_iter->second.getDefaultValue(), (*it).second, defaults, mix, slerps);
+ }
+ // else do nothing when no known defaults
+ // TODO: Should I blend this out instead?
+ }
+
+ // Note: writes variables from skip list, bug?
+ for (LLSD::map_const_iterator it = other.beginMap(); it != other.endMap(); ++it)
+ {
// TODO: Should I blend this in instead?
if (skip.find((*it).first) == skip.end())
continue;
@@ -277,6 +250,81 @@ LLSD LLSettingsBase::interpolateSDMap(const LLSD &settings, const LLSD &other, F
return newSettings;
}
+LLSD LLSettingsBase::interpolateSDValue(const std::string& key_name, const LLSD &value, const LLSD &other_value, const parammapping_t& defaults, BlendFactor mix, const stringset_t& slerps) const
+{
+ LLSD new_value;
+
+ LLSD::Type setting_type = value.type();
+
+ if (other_value.type() != setting_type)
+ {
+ // The data type mismatched between this and other. Hard switch when we pass the break point
+ // but issue a warning.
+ LL_WARNS("SETTINGS") << "Setting lerp between mismatched types for '" << key_name << "'." << LL_ENDL;
+ new_value = (mix > BREAK_POINT) ? other_value : value;
+ }
+
+ switch (setting_type)
+ {
+ case LLSD::TypeInteger:
+ // lerp between the two values rounding the result to the nearest integer.
+ new_value = LLSD::Integer(llroundf(lerp(value.asReal(), other_value.asReal(), mix)));
+ break;
+ case LLSD::TypeReal:
+ // lerp between the two values.
+ new_value = LLSD::Real(lerp(value.asReal(), other_value.asReal(), mix));
+ break;
+ case LLSD::TypeMap:
+ // deep copy.
+ new_value = interpolateSDMap(value, other_value, defaults, mix);
+ break;
+
+ case LLSD::TypeArray:
+ {
+ LLSD new_array(LLSD::emptyArray());
+
+ if (slerps.find(key_name) != slerps.end())
+ {
+ LLQuaternion a(value);
+ LLQuaternion b(other_value);
+ LLQuaternion q = slerp(mix, a, b);
+ new_array = q.getValue();
+ }
+ else
+ { // TODO: We could expand this to inspect the type and do a deep lerp based on type.
+ // for now assume a heterogeneous array of reals.
+ size_t len = std::max(value.size(), other_value.size());
+
+ for (size_t i = 0; i < len; ++i)
+ {
+
+ new_array[i] = lerp(value[i].asReal(), other_value[i].asReal(), mix);
+ }
+ }
+
+ new_value = new_array;
+ }
+
+ break;
+
+ case LLSD::TypeUUID:
+ new_value = value.asUUID();
+ break;
+
+ // case LLSD::TypeBoolean:
+ // case LLSD::TypeString:
+ // case LLSD::TypeURI:
+ // case LLSD::TypeBinary:
+ // case LLSD::TypeDate:
+ default:
+ // atomic or unknown data types. Lerping between them does not make sense so switch at the break.
+ new_value = (mix > BREAK_POINT) ? other_value : value;
+ break;
+ }
+
+ return new_value;
+}
+
LLSettingsBase::stringset_t LLSettingsBase::getSkipInterpolateKeys() const
{
static stringset_t skipSet;
diff --git a/indra/llinventory/llsettingsbase.h b/indra/llinventory/llsettingsbase.h
index aea1bc3fde..c7b685c6d5 100644
--- a/indra/llinventory/llsettingsbase.h
+++ b/indra/llinventory/llsettingsbase.h
@@ -76,7 +76,21 @@ public:
static const U32 FLAG_NOMOD;
static const U32 FLAG_NOTRANS;
- typedef std::map<std::string, S32> parammapping_t;
+ class DefaultParam
+ {
+ public:
+ DefaultParam(S32 key, const LLSD& value) : mShaderKey(key), mDefaultValue(value) {}
+ DefaultParam() : mShaderKey(-1) {}
+ S32 getShaderKey() const { return mShaderKey; }
+ const LLSD getDefaultValue() const { return mDefaultValue; }
+
+ private:
+ S32 mShaderKey;
+ LLSD mDefaultValue;
+ };
+ // Contains settings' names (map key), related shader id-key and default
+ // value for revert in case we need to reset shader (no need to search each time)
+ typedef std::map<std::string, DefaultParam> parammapping_t;
typedef PTR_NAMESPACE::shared_ptr<LLSettingsBase> ptr_t;
@@ -312,7 +326,15 @@ protected:
// combining settings objects. Customize for specific setting types
virtual void lerpSettings(const LLSettingsBase &other, BlendFactor mix);
- LLSD interpolateSDMap(const LLSD &settings, const LLSD &other, BlendFactor mix) const;
+
+ // combining settings maps where it can based on mix rate
+ // @settings initial value (mix==0)
+ // @other target value (mix==1)
+ // @defaults list of default values for legacy fields and (re)setting shaders
+ // @mix from 0 to 1, ratio or rate of transition from initial 'settings' to 'other'
+ // return interpolated and combined LLSD map
+ LLSD interpolateSDMap(const LLSD &settings, const LLSD &other, const parammapping_t& defaults, BlendFactor mix) const;
+ LLSD interpolateSDValue(const std::string& name, const LLSD &value, const LLSD &other, const parammapping_t& defaults, BlendFactor mix, const stringset_t& slerps) const;
/// when lerping between settings, some may require special handling.
/// Get a list of these key to be skipped by the default settings lerp.
diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp
index 8a1e74d7ea..cf6bc45080 100644
--- a/indra/llinventory/llsettingssky.cpp
+++ b/indra/llinventory/llsettingssky.cpp
@@ -438,7 +438,14 @@ void LLSettingsSky::blend(const LLSettingsBase::ptr_t &end, F64 blendf)
LLSettingsSky::ptr_t other = PTR_NAMESPACE::dynamic_pointer_cast<LLSettingsSky>(end);
if (other)
{
- LLSD blenddata = interpolateSDMap(mSettings, other->mSettings, blendf);
+ if (!mSettings.has(SETTING_LEGACY_HAZE) && !mSettings[SETTING_LEGACY_HAZE].has(SETTING_AMBIENT))
+ {
+ // Special case since SETTING_AMBIENT is both in outer and legacy maps, we prioritize legacy one
+ // see getAmbientColor()
+ setAmbientColor(getAmbientColor());
+ }
+
+ LLSD blenddata = interpolateSDMap(mSettings, other->mSettings, other->getParameterMap(), blendf);
replaceSettings(blenddata);
mNextSunTextureId = other->getSunTextureId();
mNextMoonTextureId = other->getMoonTextureId();
@@ -924,6 +931,7 @@ LLVector3 LLSettingsSky::getLightDirection() const
LLColor3 LLSettingsSky::getAmbientColor() const
{
+ // Todo: this causes complications, preferably to get rid of this duality
if (mSettings.has(SETTING_LEGACY_HAZE) && mSettings[SETTING_LEGACY_HAZE].has(SETTING_AMBIENT))
{
return LLColor3(mSettings[SETTING_LEGACY_HAZE][SETTING_AMBIENT]);
diff --git a/indra/llinventory/llsettingswater.cpp b/indra/llinventory/llsettingswater.cpp
index 87744453ed..7cfff954a0 100644
--- a/indra/llinventory/llsettingswater.cpp
+++ b/indra/llinventory/llsettingswater.cpp
@@ -178,7 +178,7 @@ void LLSettingsWater::blend(const LLSettingsBase::ptr_t &end, F64 blendf)
LLSettingsWater::ptr_t other = PTR_NAMESPACE::static_pointer_cast<LLSettingsWater>(end);
if (other)
{
- LLSD blenddata = interpolateSDMap(mSettings, other->mSettings, blendf);
+ LLSD blenddata = interpolateSDMap(mSettings, other->mSettings, other->getParameterMap(), blendf);
replaceSettings(blenddata);
mNextNormalMapID = other->getNormalMapID();
mNextTransparentTextureID = other->getTransparentTextureID();