From c04ceedbc3e462098eceaa233cd26f6bed79b773 Mon Sep 17 00:00:00 2001 From: Rider Linden Date: Tue, 19 Sep 2017 15:50:30 -0700 Subject: Baseline for settings changes --- indra/llcommon/llassettype.cpp | 69 ++++++++++++++++++++---------------------- indra/llcommon/llassettype.h | 18 ++++++++--- 2 files changed, 45 insertions(+), 42 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp index 4304db36be..22d6bae0eb 100644 --- a/indra/llcommon/llassettype.cpp +++ b/indra/llcommon/llassettype.cpp @@ -70,35 +70,38 @@ LLAssetDictionary::LLAssetDictionary() { // DESCRIPTION TYPE NAME HUMAN NAME CAN LINK? CAN FETCH? CAN KNOW? // |--------------------|-----------|-------------------|-----------|-----------|---------| - addEntry(LLAssetType::AT_TEXTURE, new AssetEntry("TEXTURE", "texture", "texture", true, false, true)); - addEntry(LLAssetType::AT_SOUND, new AssetEntry("SOUND", "sound", "sound", true, true, true)); - addEntry(LLAssetType::AT_CALLINGCARD, new AssetEntry("CALLINGCARD", "callcard", "calling card", true, false, false)); - addEntry(LLAssetType::AT_LANDMARK, new AssetEntry("LANDMARK", "landmark", "landmark", true, true, true)); - addEntry(LLAssetType::AT_SCRIPT, new AssetEntry("SCRIPT", "script", "legacy script", true, false, false)); - addEntry(LLAssetType::AT_CLOTHING, new AssetEntry("CLOTHING", "clothing", "clothing", true, true, true)); - addEntry(LLAssetType::AT_OBJECT, new AssetEntry("OBJECT", "object", "object", true, false, false)); - addEntry(LLAssetType::AT_NOTECARD, new AssetEntry("NOTECARD", "notecard", "note card", true, false, true)); - addEntry(LLAssetType::AT_CATEGORY, new AssetEntry("CATEGORY", "category", "folder", true, false, false)); - addEntry(LLAssetType::AT_LSL_TEXT, new AssetEntry("LSL_TEXT", "lsltext", "lsl2 script", true, false, false)); - addEntry(LLAssetType::AT_LSL_BYTECODE, new AssetEntry("LSL_BYTECODE", "lslbyte", "lsl bytecode", true, false, false)); - addEntry(LLAssetType::AT_TEXTURE_TGA, new AssetEntry("TEXTURE_TGA", "txtr_tga", "tga texture", true, false, false)); - addEntry(LLAssetType::AT_BODYPART, new AssetEntry("BODYPART", "bodypart", "body part", true, true, true)); - addEntry(LLAssetType::AT_SOUND_WAV, new AssetEntry("SOUND_WAV", "snd_wav", "sound", true, false, false)); - addEntry(LLAssetType::AT_IMAGE_TGA, new AssetEntry("IMAGE_TGA", "img_tga", "targa image", true, false, false)); - addEntry(LLAssetType::AT_IMAGE_JPEG, new AssetEntry("IMAGE_JPEG", "jpeg", "jpeg image", true, false, false)); - addEntry(LLAssetType::AT_ANIMATION, new AssetEntry("ANIMATION", "animatn", "animation", true, true, true)); - addEntry(LLAssetType::AT_GESTURE, new AssetEntry("GESTURE", "gesture", "gesture", true, true, true)); - addEntry(LLAssetType::AT_SIMSTATE, new AssetEntry("SIMSTATE", "simstate", "simstate", false, false, false)); - - addEntry(LLAssetType::AT_LINK, new AssetEntry("LINK", "link", "sym link", false, false, true)); - addEntry(LLAssetType::AT_LINK_FOLDER, new AssetEntry("FOLDER_LINK", "link_f", "sym folder link", false, false, true)); - addEntry(LLAssetType::AT_MESH, new AssetEntry("MESH", "mesh", "mesh", false, false, false)); - addEntry(LLAssetType::AT_WIDGET, new AssetEntry("WIDGET", "widget", "widget", false, false, false)); - addEntry(LLAssetType::AT_PERSON, new AssetEntry("PERSON", "person", "person", false, false, false)); - addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, FALSE, FALSE, FALSE)); + addEntry(LLAssetType::AT_TEXTURE, new AssetEntry("TEXTURE", "texture", "texture", true, false, true)); + addEntry(LLAssetType::AT_SOUND, new AssetEntry("SOUND", "sound", "sound", true, true, true)); + addEntry(LLAssetType::AT_CALLINGCARD, new AssetEntry("CALLINGCARD", "callcard", "calling card", true, false, false)); + addEntry(LLAssetType::AT_LANDMARK, new AssetEntry("LANDMARK", "landmark", "landmark", true, true, true)); + addEntry(LLAssetType::AT_SCRIPT, new AssetEntry("SCRIPT", "script", "legacy script", true, false, false)); + addEntry(LLAssetType::AT_CLOTHING, new AssetEntry("CLOTHING", "clothing", "clothing", true, true, true)); + addEntry(LLAssetType::AT_OBJECT, new AssetEntry("OBJECT", "object", "object", true, false, false)); + addEntry(LLAssetType::AT_NOTECARD, new AssetEntry("NOTECARD", "notecard", "note card", true, false, true)); + addEntry(LLAssetType::AT_CATEGORY, new AssetEntry("CATEGORY", "category", "folder", true, false, false)); + addEntry(LLAssetType::AT_LSL_TEXT, new AssetEntry("LSL_TEXT", "lsltext", "lsl2 script", true, false, false)); + addEntry(LLAssetType::AT_LSL_BYTECODE, new AssetEntry("LSL_BYTECODE", "lslbyte", "lsl bytecode", true, false, false)); + addEntry(LLAssetType::AT_TEXTURE_TGA, new AssetEntry("TEXTURE_TGA", "txtr_tga", "tga texture", true, false, false)); + addEntry(LLAssetType::AT_BODYPART, new AssetEntry("BODYPART", "bodypart", "body part", true, true, true)); + addEntry(LLAssetType::AT_SOUND_WAV, new AssetEntry("SOUND_WAV", "snd_wav", "sound", true, false, false)); + addEntry(LLAssetType::AT_IMAGE_TGA, new AssetEntry("IMAGE_TGA", "img_tga", "targa image", true, false, false)); + addEntry(LLAssetType::AT_IMAGE_JPEG, new AssetEntry("IMAGE_JPEG", "jpeg", "jpeg image", true, false, false)); + addEntry(LLAssetType::AT_ANIMATION, new AssetEntry("ANIMATION", "animatn", "animation", true, true, true)); + addEntry(LLAssetType::AT_GESTURE, new AssetEntry("GESTURE", "gesture", "gesture", true, true, true)); + addEntry(LLAssetType::AT_SIMSTATE, new AssetEntry("SIMSTATE", "simstate", "simstate", false, false, false)); + + addEntry(LLAssetType::AT_LINK, new AssetEntry("LINK", "link", "sym link", false, false, true)); + addEntry(LLAssetType::AT_LINK_FOLDER, new AssetEntry("FOLDER_LINK", "link_f", "sym folder link", false, false, true)); + addEntry(LLAssetType::AT_MESH, new AssetEntry("MESH", "mesh", "mesh", false, false, false)); + addEntry(LLAssetType::AT_WIDGET, new AssetEntry("WIDGET", "widget", "widget", false, false, false)); + addEntry(LLAssetType::AT_PERSON, new AssetEntry("PERSON", "person", "person", false, false, false)); + addEntry(LLAssetType::AT_SETTINGS, new AssetEntry("SETTINGS", "settings", "settings blob", false, true, true)); + addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, FALSE, FALSE, FALSE)); }; +const std::string LLAssetType::BADLOOKUP("llassettype_bad_lookup"); + // static LLAssetType::EType LLAssetType::getType(const std::string& desc_name) { @@ -117,7 +120,7 @@ const std::string &LLAssetType::getDesc(LLAssetType::EType asset_type) } else { - return badLookup(); + return BADLOOKUP; } } @@ -132,7 +135,7 @@ const char *LLAssetType::lookup(LLAssetType::EType asset_type) } else { - return badLookup().c_str(); + return BADLOOKUP.c_str(); } } @@ -170,7 +173,7 @@ const char *LLAssetType::lookupHumanReadable(LLAssetType::EType asset_type) } else { - return badLookup().c_str(); + return BADLOOKUP.c_str(); } } @@ -220,14 +223,6 @@ bool LLAssetType::lookupIsLinkType(EType asset_type) return false; } -// static -const std::string &LLAssetType::badLookup() -{ - static const std::string sBadLookup = "llassettype_bad_lookup"; - return sBadLookup; - -} - // static bool LLAssetType::lookupIsAssetFetchByIDAllowed(EType asset_type) { diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h index b849be9f16..3a660496e3 100644 --- a/indra/llcommon/llassettype.h +++ b/indra/llcommon/llassettype.h @@ -116,10 +116,18 @@ public: AT_PERSON = 45, // A user uuid which is not an inventory asset type, used in viewer only for adding a person to a chat via drag and drop. - AT_MESH = 49, - // Mesh data in our proprietary SLM format - - AT_COUNT = 50, + AT_MESH = 49, + // Mesh data in our proprietary SLM format + + AT_RESERVED_1 = 50, + AT_RESERVED_2 = 51, + AT_RESERVED_3 = 52, + AT_RESERVED_4 = 53, + AT_RESERVED_5 = 54, + + AT_SETTINGS = 55, // Collection of settings + + AT_COUNT = 56, // +*********************************************************+ // | TO ADD AN ELEMENT TO THIS ENUM: | @@ -153,7 +161,7 @@ public: static bool lookupIsAssetFetchByIDAllowed(EType asset_type); // the asset allows direct download static bool lookupIsAssetIDKnowable(EType asset_type); // asset data can be known by the viewer - static const std::string& badLookup(); // error string when a lookup fails + static const std::string BADLOOKUP; protected: LLAssetType() {} -- cgit v1.3 From 66ba27cb91b4f81625b8ab535f41bcf38a2aae99 Mon Sep 17 00:00:00 2001 From: Rider Linden Date: Mon, 27 Nov 2017 10:19:43 -0800 Subject: Added boost::hash<> spec for LLSD --- indra/llcommon/llsdutil.h | 65 ++++++++++++++++++++++++++++++++++++++++ indra/llcommon/lluuid.h | 20 +++++++++++++ indra/newview/llsettingsbase.cpp | 6 ++-- indra/newview/llsettingsbase.h | 6 ++++ indra/test/llsdutil_tut.cpp | 45 ++++++++++++++++++++++++++++ 5 files changed, 140 insertions(+), 2 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llsdutil.h b/indra/llcommon/llsdutil.h index 99cb79aa54..595bb91411 100644 --- a/indra/llcommon/llsdutil.h +++ b/indra/llcommon/llsdutil.h @@ -30,6 +30,7 @@ #define LL_LLSDUTIL_H #include "llsd.h" +#include // U32 LL_COMMON_API LLSD ll_sd_from_U32(const U32); @@ -419,4 +420,68 @@ private: } // namespace llsd + +// Specialization for generating a hash value from an LLSD block. +template <> +struct boost::hash +{ + typedef LLSD argument_type; + typedef std::size_t result_type; + result_type operator()(argument_type const& s) const + { + result_type seed(0); + + LLSD::Type stype = s.type(); + boost::hash_combine(seed, (S32)stype); + + switch (stype) + { + case LLSD::TypeBoolean: + boost::hash_combine(seed, s.asBoolean()); + break; + case LLSD::TypeInteger: + boost::hash_combine(seed, s.asInteger()); + break; + case LLSD::TypeReal: + boost::hash_combine(seed, s.asReal()); + break; + case LLSD::TypeURI: + case LLSD::TypeString: + boost::hash_combine(seed, s.asString()); + break; + case LLSD::TypeUUID: + boost::hash_combine(seed, s.asUUID()); + break; + case LLSD::TypeDate: + boost::hash_combine(seed, s.asDate().secondsSinceEpoch()); + break; + case LLSD::TypeBinary: + { + const LLSD::Binary &b(s.asBinary()); + boost::hash_range(seed, b.begin(), b.end()); + break; + } + case LLSD::TypeMap: + { + for (LLSD::map_const_iterator itm = s.beginMap(); itm != s.endMap(); ++itm) + { + boost::hash_combine(seed, (*itm).first); + boost::hash_combine(seed, (*itm).second); + } + break; + } + case LLSD::TypeArray: + for (LLSD::array_const_iterator ita = s.beginArray(); ita != s.endArray(); ++ita) + { + boost::hash_combine(seed, (*ita)); + } + break; + case LLSD::TypeUndefined: + break; + } + + return seed; + } +}; + #endif // LL_LLSDUTIL_H diff --git a/indra/llcommon/lluuid.h b/indra/llcommon/lluuid.h index dd8660a3c8..fe7482ba29 100644 --- a/indra/llcommon/lluuid.h +++ b/indra/llcommon/lluuid.h @@ -31,6 +31,7 @@ #include #include "stdtypes.h" #include "llpreprocessor.h" +#include class LLMutex; @@ -164,6 +165,25 @@ public: LLAssetID makeAssetID(const LLUUID& session) const; }; +// Generate a hash of an LLUUID object using the boost hash templates. +template <> +struct boost::hash +{ + typedef LLUUID argument_type; + typedef std::size_t result_type; + result_type operator()(argument_type const& s) const + { + result_type seed(0); + + for (S32 i = 0; i < UUID_BYTES; ++i) + { + boost::hash_combine(seed, s.mData[i]); + } + + return seed; + } +}; + #endif diff --git a/indra/newview/llsettingsbase.cpp b/indra/newview/llsettingsbase.cpp index 904d0dd07c..e36c6d4a84 100644 --- a/indra/newview/llsettingsbase.cpp +++ b/indra/newview/llsettingsbase.cpp @@ -48,13 +48,15 @@ const F32Seconds LLSettingsBlender::DEFAULT_THRESHOLD(0.01); //========================================================================= LLSettingsBase::LLSettingsBase(): mSettings(LLSD::emptyMap()), - mDirty(true) + mDirty(true), + mHashValue(0) { } LLSettingsBase::LLSettingsBase(const LLSD setting) : mSettings(setting), - mDirty(true) + mDirty(true), + mHashValue(0) { } diff --git a/indra/newview/llsettingsbase.h b/indra/newview/llsettingsbase.h index d32fcb26e8..d304b8702a 100644 --- a/indra/newview/llsettingsbase.h +++ b/indra/newview/llsettingsbase.h @@ -67,6 +67,11 @@ public: inline bool isDirty() const { return mDirty; } inline void setDirtyFlag(bool dirty) { mDirty = dirty; } + inline size_t getHash() const + { + return boost::hash{}(mSettings); + } + inline LLUUID getId() const { return getValue(SETTING_ID).asUUID(); @@ -227,6 +232,7 @@ protected: private: bool mDirty; + size_t mHashValue; LLSD combineSDMaps(const LLSD &first, const LLSD &other) const; diff --git a/indra/test/llsdutil_tut.cpp b/indra/test/llsdutil_tut.cpp index 140f4b832b..6fce53f335 100644 --- a/indra/test/llsdutil_tut.cpp +++ b/indra/test/llsdutil_tut.cpp @@ -386,4 +386,49 @@ namespace tut lmap["Seattle"] = 72; ensure("llsd_equals(superset left map)", ! llsd_equals(lmap, rmap)); } + + template<> template<> + void llsdutil_object::test<10>() + { + set_test_name("llsd_hashing"); + + { + LLSD data_s1 = LLSD::String("The quick brown aardvark jumped over the lazy lemming."); + LLSD data_s2 = LLSD::String("The quick brown aardvark jumped over the lazy lemming."); + + ensure("hash: Identical string hashes match.", boost::hash{}(data_s1) == boost::hash{}(data_s2)); + } + { + LLSD data_r1 = LLSD::Real(3.0f); + LLSD data_i1 = LLSD::Integer(3); + ensure("hash: equivalent values but different types do not match.", boost::hash{}(data_r1) != boost::hash{}(data_i1)); + } + { + LLSD data_a1 = LLSDArray("A")("B")("C"); + LLSD data_a2 = LLSDArray("A")("B")("C"); + + ensure("hash: identical arrays produce identical results", boost::hash{}(data_a1) == boost::hash{}(data_a2)); + + data_a2.append(LLSDArray(1)(2)); + + ensure("hash: changing the array changes the hash.", boost::hash{}(data_a1) != boost::hash{}(data_a2)); + + data_a1.append(LLSDArray(1)(2)); + ensure("hash: identical arrays produce identical results with nested arrays", boost::hash{}(data_a1) == boost::hash{}(data_a2)); + } + { + LLSD data_m1 = LLSDMap("key1", LLSD::Real(3.0))("key2", "value2")("key3", LLSDArray(1)(2)(3)); + LLSD data_m2 = LLSDMap("key1", LLSD::Real(3.0))("key2", "value2")("key3", LLSDArray(1)(2)(3)); + + ensure("hash: identical maps produce identical results", boost::hash{}(data_m1) == boost::hash{}(data_m2)); + + LLSD data_m3 = LLSDMap("key1", LLSD::Real(5.0))("key2", "value2")("key3", LLSDArray(1)(2)(3)); + ensure("hash: Different values in the map produce different hashes.", boost::hash{}(data_m1) != boost::hash{}(data_m3)); + + LLSD data_m4 = LLSDMap("keyA", LLSD::Real(3.0))("key2", "value2")("key3", LLSDArray(1)(2)(3)); + ensure("hash: Different keys in the map produce different hashes.", boost::hash{}(data_m1) != boost::hash{}(data_m4)); + + } + } + } -- cgit v1.3 From 28b98374da7acf4fc2eec2a243e951d1786f33a1 Mon Sep 17 00:00:00 2001 From: Rider Linden Date: Mon, 27 Nov 2017 11:12:29 -0800 Subject: Mac compile does not like not having a default even if it does nothing. --- indra/llcommon/llsdutil.h | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llsdutil.h b/indra/llcommon/llsdutil.h index 595bb91411..c100454e15 100644 --- a/indra/llcommon/llsdutil.h +++ b/indra/llcommon/llsdutil.h @@ -477,6 +477,7 @@ struct boost::hash } break; case LLSD::TypeUndefined: + default: break; } -- cgit v1.3 From d7dd10b88bc3fda88f6528ecc5936e4889f019f3 Mon Sep 17 00:00:00 2001 From: Rider Linden Date: Thu, 30 Nov 2017 11:32:22 -0800 Subject: Split for viewer/simhost sync LLSD with simhost. --- indra/llcommon/llsd.cpp | 26 +- indra/llcommon/llsd.h | 5 +- indra/llcommon/llsdutil.cpp | 275 +++++++++++++ indra/llcommon/llsdutil.h | 30 ++ indra/llinventory/CMakeLists.txt | 8 + indra/llinventory/llsettingsbase.cpp | 581 +++++++++++++++++++++++++++ indra/llinventory/llsettingsbase.h | 306 +++++++++++++++ indra/llinventory/llsettingsdaycycle.cpp | 545 +++++++++++++++++++++++++ indra/llinventory/llsettingsdaycycle.h | 156 ++++++++ indra/llinventory/llsettingssky.cpp | 561 ++++++++++++++++++++++++++ indra/llinventory/llsettingssky.h | 455 +++++++++++++++++++++ indra/llinventory/llsettingswater.cpp | 215 ++++++++++ indra/llinventory/llsettingswater.h | 227 +++++++++++ indra/newview/CMakeLists.txt | 10 +- indra/newview/llenvironment.cpp | 22 +- indra/newview/llenvironment.h | 3 + indra/newview/llsettingsbase.cpp | 617 ----------------------------- indra/newview/llsettingsbase.h | 312 --------------- indra/newview/llsettingsdaycycle.cpp | 613 ----------------------------- indra/newview/llsettingsdaycycle.h | 143 ------- indra/newview/llsettingssky.cpp | 655 ------------------------------- indra/newview/llsettingssky.h | 463 ---------------------- indra/newview/llsettingsvo.cpp | 420 ++++++++++++++++++++ indra/newview/llsettingsvo.h | 103 +++++ indra/newview/llsettingswater.cpp | 340 ---------------- indra/newview/llsettingswater.h | 243 ------------ 26 files changed, 3923 insertions(+), 3411 deletions(-) create mode 100644 indra/llinventory/llsettingsbase.cpp create mode 100644 indra/llinventory/llsettingsbase.h create mode 100644 indra/llinventory/llsettingsdaycycle.cpp create mode 100644 indra/llinventory/llsettingsdaycycle.h create mode 100644 indra/llinventory/llsettingssky.cpp create mode 100644 indra/llinventory/llsettingssky.h create mode 100644 indra/llinventory/llsettingswater.cpp create mode 100644 indra/llinventory/llsettingswater.h delete mode 100644 indra/newview/llsettingsbase.cpp delete mode 100644 indra/newview/llsettingsbase.h delete mode 100644 indra/newview/llsettingsdaycycle.cpp delete mode 100644 indra/newview/llsettingsdaycycle.h delete mode 100644 indra/newview/llsettingssky.cpp delete mode 100644 indra/newview/llsettingssky.h create mode 100644 indra/newview/llsettingsvo.cpp create mode 100644 indra/newview/llsettingsvo.h delete mode 100644 indra/newview/llsettingswater.cpp delete mode 100644 indra/newview/llsettingswater.h (limited to 'indra/llcommon') diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp index 57aa7d9c07..57b746889d 100644 --- a/indra/llcommon/llsd.cpp +++ b/indra/llcommon/llsd.cpp @@ -132,6 +132,7 @@ public: virtual bool has(const String&) const { return false; } virtual LLSD get(const String&) const { return LLSD(); } + virtual LLSD getKeys() const { return LLSD::emptyArray(); } virtual void erase(const String&) { } virtual const LLSD& ref(const String&) const{ return undef(); } @@ -380,7 +381,8 @@ namespace using LLSD::Impl::erase; // Unhiding erase(LLSD::Integer) using LLSD::Impl::ref; // Unhiding ref(LLSD::Integer) virtual LLSD get(const LLSD::String&) const; - void insert(const LLSD::String& k, const LLSD& v); + virtual LLSD getKeys() const; + void insert(const LLSD::String& k, const LLSD& v); virtual void erase(const LLSD::String&); LLSD& ref(const LLSD::String&); virtual const LLSD& ref(const LLSD::String&) const; @@ -421,7 +423,19 @@ namespace DataMap::const_iterator i = mData.find(k); return (i != mData.end()) ? i->second : LLSD(); } - + + LLSD ImplMap::getKeys() const + { + LLSD keys = LLSD::emptyArray(); + DataMap::const_iterator iter = mData.begin(); + while (iter != mData.end()) + { + keys.append((*iter).first); + iter++; + } + return keys; + } + void ImplMap::insert(const LLSD::String& k, const LLSD& v) { mData.insert(DataMap::value_type(k, v)); @@ -502,7 +516,7 @@ namespace virtual LLSD get(LLSD::Integer) const; void set(LLSD::Integer, const LLSD&); void insert(LLSD::Integer, const LLSD&); - void append(const LLSD&); + LLSD& append(const LLSD&); virtual void erase(LLSD::Integer); LLSD& ref(LLSD::Integer); virtual const LLSD& ref(LLSD::Integer) const; @@ -570,9 +584,10 @@ namespace mData.insert(mData.begin() + index, v); } - void ImplArray::append(const LLSD& v) + LLSD& ImplArray::append(const LLSD& v) { mData.push_back(v); + return mData.back(); } void ImplArray::erase(LLSD::Integer i) @@ -862,6 +877,7 @@ LLSD LLSD::emptyMap() bool LLSD::has(const String& k) const { return safe(impl).has(k); } LLSD LLSD::get(const String& k) const { return safe(impl).get(k); } +LLSD LLSD::getKeys() const { return safe(impl).getKeys(); } void LLSD::insert(const String& k, const LLSD& v) { makeMap(impl).insert(k, v); } LLSD& LLSD::with(const String& k, const LLSD& v) @@ -895,7 +911,7 @@ LLSD& LLSD::with(Integer i, const LLSD& v) makeArray(impl).insert(i, v); return *this; } -void LLSD::append(const LLSD& v) { makeArray(impl).append(v); } +LLSD& LLSD::append(const LLSD& v) { return makeArray(impl).append(v); } void LLSD::erase(Integer i) { makeArray(impl).erase(i); } LLSD& LLSD::operator[](Integer i) diff --git a/indra/llcommon/llsd.h b/indra/llcommon/llsd.h index 7b9b1285f5..5b6d5545af 100644 --- a/indra/llcommon/llsd.h +++ b/indra/llcommon/llsd.h @@ -79,7 +79,7 @@ an LLSD array). An array is a sequence of zero or more LLSD values. - + Thread Safety In general, these LLSD classes offer *less* safety than STL container @@ -284,6 +284,7 @@ public: bool has(const String&) const; LLSD get(const String&) const; + LLSD getKeys() const; // Return an LLSD array with keys as strings void insert(const String&, const LLSD&); void erase(const String&); LLSD& with(const String&, const LLSD&); @@ -301,7 +302,7 @@ public: LLSD get(Integer) const; void set(Integer, const LLSD&); void insert(Integer, const LLSD&); - void append(const LLSD&); + LLSD& append(const LLSD&); void erase(Integer); LLSD& with(Integer, const LLSD&); diff --git a/indra/llcommon/llsdutil.cpp b/indra/llcommon/llsdutil.cpp index 6ad4a97149..0171f2880e 100644 --- a/indra/llcommon/llsdutil.cpp +++ b/indra/llcommon/llsdutil.cpp @@ -314,6 +314,180 @@ BOOL compare_llsd_with_template( return TRUE; } +// filter_llsd_with_template() is a direct clone (copy-n-paste) of +// compare_llsd_with_template with the following differences: +// (1) bool vs BOOL return types +// (2) A map with the key value "*" is a special value and maps any key in the +// test llsd that doesn't have an explicitly matching key in the template. +// (3) The element of an array with exactly one element is taken as a template +// for *all* the elements of the test array. If the template array is of +// different size, compare_llsd_with_template() semantics apply. +bool filter_llsd_with_template( + const LLSD & llsd_to_test, + const LLSD & template_llsd, + LLSD & resultant_llsd) +{ + if (llsd_to_test.isUndefined() && template_llsd.isDefined()) + { + resultant_llsd = template_llsd; + return true; + } + else if (llsd_to_test.type() != template_llsd.type()) + { + resultant_llsd = LLSD(); + return false; + } + + if (llsd_to_test.isArray()) + { + //they are both arrays + //we loop over all the items in the template + //verifying that the to_test has a subset (in the same order) + //any shortcoming in the testing_llsd are just taken + //to be the rest of the template + LLSD data; + LLSD::array_const_iterator test_iter; + LLSD::array_const_iterator template_iter; + + resultant_llsd = LLSD::emptyArray(); + test_iter = llsd_to_test.beginArray(); + + if (1 == template_llsd.size()) + { + // If the template has a single item, treat it as + // the template for *all* items in the test LLSD. + template_iter = template_llsd.beginArray(); + + for (; test_iter != llsd_to_test.endArray(); ++test_iter) + { + if (! filter_llsd_with_template(*test_iter, *template_iter, data)) + { + resultant_llsd = LLSD(); + return false; + } + else + { + resultant_llsd.append(data); + } + } + } + else + { + // Traditional compare_llsd_with_template matching + + for (template_iter = template_llsd.beginArray(); + template_iter != template_llsd.endArray() && + test_iter != llsd_to_test.endArray(); + ++template_iter, ++test_iter) + { + if (! filter_llsd_with_template(*test_iter, *template_iter, data)) + { + resultant_llsd = LLSD(); + return false; + } + else + { + resultant_llsd.append(data); + } + } + + //so either the test or the template ended + //we do another loop now to the end of the template + //grabbing the default values + for (; + template_iter != template_llsd.endArray(); + ++template_iter) + { + resultant_llsd.append(*template_iter); + } + } + } + else if (llsd_to_test.isMap()) + { + resultant_llsd = LLSD::emptyMap(); + + //now we loop over the keys of the two maps + //any excess is taken from the template + //excess is ignored in the test + + // Special tag for wildcarded LLSD map key templates + const LLSD::String wildcard_tag("*"); + + const bool template_has_wildcard = template_llsd.has(wildcard_tag); + LLSD wildcard_value; + LLSD value; + + const LLSD::map_const_iterator template_iter_end(template_llsd.endMap()); + for (LLSD::map_const_iterator template_iter(template_llsd.beginMap()); + template_iter_end != template_iter; + ++template_iter) + { + if (wildcard_tag == template_iter->first) + { + wildcard_value = template_iter->second; + } + else if (llsd_to_test.has(template_iter->first)) + { + //the test LLSD has the same key + if (! filter_llsd_with_template(llsd_to_test[template_iter->first], + template_iter->second, + value)) + { + resultant_llsd = LLSD(); + return false; + } + else + { + resultant_llsd[template_iter->first] = value; + } + } + else if (! template_has_wildcard) + { + // test llsd doesn't have it...take the + // template as default value + resultant_llsd[template_iter->first] = template_iter->second; + } + } + if (template_has_wildcard) + { + LLSD sub_value; + LLSD::map_const_iterator test_iter; + + for (test_iter = llsd_to_test.beginMap(); + test_iter != llsd_to_test.endMap(); + ++test_iter) + { + if (resultant_llsd.has(test_iter->first)) + { + // Final value has test key, assume more specific + // template matched and we shouldn't modify it again. + continue; + } + else if (! filter_llsd_with_template(test_iter->second, + wildcard_value, + sub_value)) + { + // Test value doesn't match wildcarded template + resultant_llsd = LLSD(); + return false; + } + else + { + // Test value matches template, add the actuals. + resultant_llsd[test_iter->first] = sub_value; + } + } + } + } + else + { + //of same type...take the test llsd's value + resultant_llsd = llsd_to_test; + } + + return true; +} + /***************************************************************************** * Helpers for llsd_matches() *****************************************************************************/ @@ -673,3 +847,104 @@ bool llsd_equals(const LLSD& lhs, const LLSD& rhs, int bits) return false; // pacify the compiler } } + +// Construct a deep partial clone of of an LLSD object. primitive types share +// references, however maps, arrays and binary objects are duplicated. An optional +// filter may be include to exclude/include keys in a map. +LLSD llsd_clone(LLSD value, LLSD filter) +{ + LLSD clone; + bool has_filter(filter.isMap()); + + switch (value.type()) + { + case LLSD::TypeMap: + clone = LLSD::emptyMap(); + for (LLSD::map_const_iterator itm = value.beginMap(); itm != value.endMap(); ++itm) + { + if (has_filter) + { + if (filter.has((*itm).first)) + { + if (!filter[(*itm).first].asBoolean()) + continue; + } + else if (filter.has("*")) + { + if (!filter["*"].asBoolean()) + continue; + } + else + { + continue; + } + } + clone[(*itm).first] = llsd_clone((*itm).second, filter); + } + break; + case LLSD::TypeArray: + clone = LLSD::emptyArray(); + for (LLSD::array_const_iterator ita = value.beginArray(); ita != value.endArray(); ++ita) + { + clone.append(llsd_clone(*ita, filter)); + } + break; + + case LLSD::TypeBinary: + { + LLSD::Binary bin(value.asBinary().begin(), value.asBinary().end()); + clone = LLSD::Binary(bin); + break; + } + default: + clone = value; + } + + return clone; +} + +LLSD llsd_shallow(LLSD value, LLSD filter) +{ + LLSD shallow; + bool has_filter(filter.isMap()); + + if (value.isMap()) + { + shallow = LLSD::emptyMap(); + for (LLSD::map_const_iterator itm = value.beginMap(); itm != value.endMap(); ++itm) + { + if (has_filter) + { + if (filter.has((*itm).first)) + { + if (!filter[(*itm).first].asBoolean()) + continue; + } + else if (filter.has("*")) + { + if (!filter["*"].asBoolean()) + continue; + } + else + { + continue; + } + } + shallow[(*itm).first] = (*itm).second; + } + } + else if (value.isArray()) + { + shallow = LLSD::emptyArray(); + for (LLSD::array_const_iterator ita = value.beginArray(); ita != value.endArray(); ++ita) + { + shallow.append(*ita); + } + } + else + { + return value; + } + + return shallow; +} diff --git a/indra/llcommon/llsdutil.h b/indra/llcommon/llsdutil.h index c100454e15..33befef85b 100644 --- a/indra/llcommon/llsdutil.h +++ b/indra/llcommon/llsdutil.h @@ -69,6 +69,19 @@ LL_COMMON_API BOOL compare_llsd_with_template( const LLSD& template_llsd, LLSD& resultant_llsd); +// filter_llsd_with_template() is a direct clone (copy-n-paste) of +// compare_llsd_with_template with the following differences: +// (1) bool vs BOOL return types +// (2) A map with the key value "*" is a special value and maps any key in the +// test llsd that doesn't have an explicitly matching key in the template. +// (3) The element of an array with exactly one element is taken as a template +// for *all* the elements of the test array. If the template array is of +// different size, compare_llsd_with_template() semantics apply. +bool filter_llsd_with_template( + const LLSD & llsd_to_test, + const LLSD & template_llsd, + LLSD & resultant_llsd); + /** * Recursively determine whether a given LLSD data block "matches" another * LLSD prototype. The returned string is empty() on success, non-empty() on @@ -421,6 +434,23 @@ private: } // namespace llsd +// Creates a deep clone of an LLSD object. Maps, Arrays and binary objects +// are duplicated, atomic primitives (Boolean, Integer, Real, etc) simply +// use a shared reference. +// Optionally a filter may be specified to control what is duplicated. The +// map takes the form "keyname/boolean". +// If the value is true the value will be duplicated otherwise it will be skipped +// when encountered in a map. A key name of "*" can be specified as a wild card +// and will specify the default behavior. If no wild card is given and the clone +// encounters a name not in the filter, that value will be skipped. +LLSD llsd_clone(LLSD value, LLSD filter = LLSD()); + +// Creates a shallow copy of a map or array. If passed any other type of LLSD +// object it simply returns that value. See llsd_clone for a description of +// the filter parameter. +LLSD llsd_shallow(LLSD value, LLSD filter = LLSD()); + + // Specialization for generating a hash value from an LLSD block. template <> struct boost::hash diff --git a/indra/llinventory/CMakeLists.txt b/indra/llinventory/CMakeLists.txt index 68dd00d880..3eba746614 100644 --- a/indra/llinventory/CMakeLists.txt +++ b/indra/llinventory/CMakeLists.txt @@ -29,6 +29,10 @@ set(llinventory_SOURCE_FILES llparcel.cpp llpermissions.cpp llsaleinfo.cpp + llsettingsbase.cpp + llsettingsdaycycle.cpp + llsettingssky.cpp + llsettingswater.cpp lltransactionflags.cpp lluserrelations.cpp ) @@ -49,6 +53,10 @@ set(llinventory_HEADER_FILES llpermissions.h llpermissionsflags.h llsaleinfo.h + llsettingsbase.h + llsettingsdaycycle.h + llsettingssky.h + llsettingswater.h lltransactionflags.h lltransactiontypes.h lluserrelations.h diff --git a/indra/llinventory/llsettingsbase.cpp b/indra/llinventory/llsettingsbase.cpp new file mode 100644 index 0000000000..e4291d8080 --- /dev/null +++ b/indra/llinventory/llsettingsbase.cpp @@ -0,0 +1,581 @@ +/** +* @file llsettingsbase.cpp +* @author optional +* @brief A base class for asset based settings groups. +* +* $LicenseInfo:2011&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2017, 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 "llsettingsbase.h" + +#include "llmath.h" +#include + +#include "llsdserialize.h" + +//========================================================================= +namespace +{ + const F32 BREAK_POINT = 0.5; +} + +//========================================================================= +const std::string LLSettingsBase::SETTING_ID("id"); +const std::string LLSettingsBase::SETTING_NAME("name"); +const std::string LLSettingsBase::SETTING_HASH("hash"); +const std::string LLSettingsBase::SETTING_TYPE("type"); + +const F32Seconds LLSettingsBlender::DEFAULT_THRESHOLD(0.01); + +//========================================================================= +LLSettingsBase::LLSettingsBase(): + mSettings(LLSD::emptyMap()), + mDirty(true) +{ +} + +LLSettingsBase::LLSettingsBase(const LLSD setting) : + mSettings(setting), + mDirty(true) +{ +} + +//========================================================================= +void LLSettingsBase::lerpSettings(const LLSettingsBase &other, F32 mix) +{ + mSettings = interpolateSDMap(mSettings, other.mSettings, mix); + setDirtyFlag(true); +} + +LLSD LLSettingsBase::combineSDMaps(const LLSD &settings, const LLSD &other) const +{ + LLSD newSettings; + + for (LLSD::map_const_iterator it = settings.beginMap(); it != settings.endMap(); ++it) + { + std::string key_name = (*it).first; + LLSD value = (*it).second; + + LLSD::Type setting_type = value.type(); + switch (setting_type) + { + case LLSD::TypeMap: + newSettings[key_name] = combineSDMaps(value, LLSD()); + break; + case LLSD::TypeArray: + newSettings[key_name] = LLSD::emptyArray(); + for (LLSD::array_const_iterator ita = value.beginArray(); ita != value.endArray(); ++ita) + { + newSettings[key_name].append(*ita); + } + break; + //case LLSD::TypeInteger: + //case LLSD::TypeReal: + //case LLSD::TypeBoolean: + //case LLSD::TypeString: + //case LLSD::TypeUUID: + //case LLSD::TypeURI: + //case LLSD::TypeDate: + //case LLSD::TypeBinary: + default: + newSettings[key_name] = value; + break; + } + } + + if (!other.isUndefined()) + { + for (LLSD::map_const_iterator it = other.beginMap(); it != other.endMap(); ++it) + { + std::string key_name = (*it).first; + LLSD value = (*it).second; + + LLSD::Type setting_type = value.type(); + switch (setting_type) + { + case LLSD::TypeMap: + newSettings[key_name] = combineSDMaps(value, LLSD()); + break; + case LLSD::TypeArray: + newSettings[key_name] = LLSD::emptyArray(); + for (LLSD::array_const_iterator ita = value.beginArray(); ita != value.endArray(); ++ita) + { + newSettings[key_name].append(*ita); + } + break; + //case LLSD::TypeInteger: + //case LLSD::TypeReal: + //case LLSD::TypeBoolean: + //case LLSD::TypeString: + //case LLSD::TypeUUID: + //case LLSD::TypeURI: + //case LLSD::TypeDate: + //case LLSD::TypeBinary: + default: + newSettings[key_name] = value; + break; + } + } + } + + return newSettings; +} + +LLSD LLSettingsBase::interpolateSDMap(const LLSD &settings, const LLSD &other, F32 mix) const +{ + LLSD newSettings; + + stringset_t skip = getSkipInterpolateKeys(); + stringset_t slerps = getSlerpKeys(); + + for (LLSD::map_const_iterator it = settings.beginMap(); it != settings.endMap(); ++it) + { + std::string key_name = (*it).first; + LLSD value = (*it).second; + + 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; + } + + switch (setting_type) + { + 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: + { + LLSD newvalue(LLSD::emptyArray()); + + if (slerps.find(key_name) != slerps.end()) + { + LLQuaternion q = slerp(mix, LLQuaternion(value), LLQuaternion(other_value)); + 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; + } + + break; + +// case LLSD::TypeBoolean: +// case LLSD::TypeString: +// case LLSD::TypeUUID: +// case LLSD::TypeURI: +// case LLSD::TypeBinary: +// case LLSD::TypeDate: + default: + /* TODO: If the UUID points to an image ID, blend the images. */ + // 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; + } + } + + // Now add anything that is in other but not in the settings + 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; + + if (!settings.has((*it).first)) + continue; + + newSettings[(*it).first] = (*it).second; + } + + return newSettings; +} + +LLSD LLSettingsBase::getSettings() const +{ + return mSettings; +} + +LLSD LLSettingsBase::cloneSettings() const +{ + return combineSDMaps(mSettings, LLSD()); +} + +size_t LLSettingsBase::getHash() const +{ // get a shallow copy of the LLSD filtering out values to not include in the hash + LLSD hash_settings = llsd_shallow(getSettings(), + LLSDMap(SETTING_NAME, false)(SETTING_ID, false)(SETTING_HASH, false)("*", true)); + + return boost::hash{}(hash_settings); +} + +#ifdef VALIDATION_DEBUG +namespace +{ + bool compare_llsd(LLSD valA, LLSD valB) + { + if (valA.type() != valB.type()) + return false; + + switch (valA.type()) + { + // case LLSD::TypeMap: + // newSettings[key_name] = combineSDMaps(value, LLSD()); + // break; + case LLSD::TypeArray: + if (valA.size() != valB.size()) + return false; + + for (S32 idx = 0; idx < valA.size(); ++idx) + { + if (!compare_llsd(valA[idx], valB[idx])) + return false; + } + return true; + + case LLSD::TypeInteger: + return valA.asInteger() == valB.asInteger(); + + case LLSD::TypeReal: + return is_approx_equal(valA.asReal(), valB.asReal()); + + case LLSD::TypeBoolean: + return valA.asBoolean() == valB.asBoolean(); + + case LLSD::TypeString: + return valA.asString() == valB.asString(); + + case LLSD::TypeUUID: + return valA.asUUID() == valB.asUUID(); + + case LLSD::TypeURI: + return valA.asString() == valB.asString(); + + case LLSD::TypeDate: + return valA.asDate() == valB.asDate(); + } + + return true; + } +} +#endif + +bool LLSettingsBase::validate() +{ + static Validator validateName(SETTING_NAME, false, LLSD::TypeString); + static Validator validateId(SETTING_ID, false, LLSD::TypeUUID); + static Validator validateHash(SETTING_HASH, false, LLSD::TypeInteger); + static Validator validateType(SETTING_TYPE, false, LLSD::TypeString); + validation_list_t validations = getValidationList(); + stringset_t validated; + stringset_t strip; + + if (!mSettings.has(SETTING_TYPE)) + { + mSettings[SETTING_TYPE] = getSettingType(); + } + + // Fields common to all settings. + if (!validateName.verify(mSettings)) + { + LL_WARNS("SETTINGS") << "Unable to validate Name." << LL_ENDL; + mIsValid = false; + return false; + } + validated.insert(validateName.getName()); + + if (!validateId.verify(mSettings)) + { + LL_WARNS("SETTINGS") << "Unable to validate Id." << LL_ENDL; + mIsValid = false; + return false; + } + validated.insert(validateId.getName()); + + if (!validateHash.verify(mSettings)) + { + LL_WARNS("SETTINGS") << "Unable to validate Hash." << LL_ENDL; + mIsValid = false; + return false; + } + validated.insert(validateHash.getName()); + + if (!validateType.verify(mSettings)) + { + LL_WARNS("SETTINGS") << "Unable to validate Type." << LL_ENDL; + mIsValid = false; + return false; + } + validated.insert(validateType.getName()); + + // Fields for specific settings. + for (validation_list_t::iterator itv = validations.begin(); itv != validations.end(); ++itv) + { +#ifdef VALIDATION_DEBUG + LLSD oldvalue; + if (mSettings.has((*itv).getName())) + { + oldvalue = llsd_clone(mSettings[(*itv).getName()]); + } +#endif + + if (!(*itv).verify(mSettings)) + { + LL_WARNS("SETTINGS") << "Settings LLSD fails validation and could not be corrected for '" << (*itv).getName() << "'!" << LL_ENDL; + mIsValid = false; + return false; + } + validated.insert((*itv).getName()); + +#ifdef VALIDATION_DEBUG + if (!oldvalue.isUndefined()) + { + if (!compare_llsd(mSettings[(*itv).getName()], oldvalue)) + { + LL_WARNS("SETTINGS") << "Setting '" << (*itv).getName() << "' was changed: " << oldvalue << " -> " << mSettings[(*itv).getName()] << LL_ENDL; + } + } +#endif + } + + // strip extra entries + for (LLSD::map_iterator itm = mSettings.beginMap(); itm != mSettings.endMap(); ++itm) + { + if (validated.find((*itm).first) == validated.end()) + { + LL_WARNS("SETTINGS") << "Stripping setting '" << (*itm).first << "'" << LL_ENDL; + strip.insert((*itm).first); + } + } + + for (stringset_t::iterator its = strip.begin(); its != strip.end(); ++its) + { + mSettings.erase(*its); + } + + return true; +} + +//========================================================================= +bool LLSettingsBase::Validator::verify(LLSD &data) +{ + if (!data.has(mName) || (data.has(mName) && data[mName].isUndefined())) + { + if (mRequired) + LL_WARNS("SETTINGS") << "Missing required setting '" << mName << "'" << LL_ENDL; + return !mRequired; + } + + if (data[mName].type() != mType) + { + LL_WARNS("SETTINGS") << "Setting '" << mName << "' is incorrect type." << LL_ENDL; + return false; + } + + if (!mVerify.empty() && !mVerify(data[mName])) + { + LL_WARNS("SETTINGS") << "Setting '" << mName << "' fails validation." << LL_ENDL; + return false; + } + + return true; +} + +bool LLSettingsBase::Validator::verifyColor(LLSD &value) +{ + return (value.size() == 3 || value.size() == 4); +} + +bool LLSettingsBase::Validator::verifyVector(LLSD &value, S32 length) +{ + return (value.size() == length); +} + +bool LLSettingsBase::Validator::verifyVectorNormalized(LLSD &value, S32 length) +{ + if (value.size() != length) + return false; + + LLSD newvector; + + switch (length) + { + case 2: + { + LLVector2 vect(value); + + if (is_approx_equal(vect.normalize(), 1.0f)) + return true; + newvector = vect.getValue(); + break; + } + case 3: + { + LLVector3 vect(value); + + if (is_approx_equal(vect.normalize(), 1.0f)) + return true; + newvector = vect.getValue(); + break; + } + case 4: + { + LLVector4 vect(value); + + if (is_approx_equal(vect.normalize(), 1.0f)) + return true; + newvector = vect.getValue(); + break; + } + default: + return false; + } + + return true; +} + +bool LLSettingsBase::Validator::verifyVectorMinMax(LLSD &value, LLSD minvals, LLSD maxvals) +{ + for (S32 index = 0; index < value.size(); ++index) + { + if (minvals[index].asString() != "*") + { + if (minvals[index].asReal() > value[index].asReal()) + { + value[index] = minvals[index].asReal(); + } + } + if (maxvals[index].asString() != "*") + { + if (maxvals[index].asReal() < value[index].asReal()) + { + value[index] = maxvals[index].asReal(); + } + } + } + + return true; +} + +bool LLSettingsBase::Validator::verifyQuaternion(LLSD &value) +{ + return (value.size() == 4); +} + +bool LLSettingsBase::Validator::verifyQuaternionNormal(LLSD &value) +{ + if (value.size() != 4) + return false; + + LLQuaternion quat(value); + + if (is_approx_equal(quat.normalize(), 1.0f)) + return true; + + LLSD newquat = quat.getValue(); + for (S32 index = 0; index < 4; ++index) + { + value[index] = newquat[index]; + } + return true; +} + +bool LLSettingsBase::Validator::verifyFloatRange(LLSD &value, LLSD range) +{ + F32 real = value.asReal(); + + F32 clampedval = llclamp(LLSD::Real(real), range[0].asReal(), range[1].asReal()); + + if (is_approx_equal(clampedval, real)) + return true; + + value = LLSD::Real(clampedval); + return true; +} + +bool LLSettingsBase::Validator::verifyIntegerRange(LLSD &value, LLSD range) +{ + S32 ival = value.asInteger(); + + S32 clampedval = llclamp(LLSD::Integer(ival), range[0].asInteger(), range[1].asInteger()); + + if (clampedval == ival) + return true; + + value = LLSD::Integer(clampedval); + return true; +} + +//========================================================================= + +void LLSettingsBlender::update(F32Seconds timedelta) +{ + mTimeSpent += timedelta; + + if (mTimeSpent >= mSeconds) + { + LLSettingsBlender::ptr_t hold = shared_from_this(); // prevents this from deleting too soon + mOnFinished(shared_from_this()); + mOnFinished.disconnect_all_slots(); // prevent from firing more than once. + return; + } + + F32 blendf = fmod(mTimeSpent.value(), mSeconds.value()) / mSeconds.value(); + + mTarget->replaceSettings(mInitial->getSettings()); + mTarget->blend(mFinal, blendf); +} + diff --git a/indra/llinventory/llsettingsbase.h b/indra/llinventory/llsettingsbase.h new file mode 100644 index 0000000000..2b59a103ad --- /dev/null +++ b/indra/llinventory/llsettingsbase.h @@ -0,0 +1,306 @@ +/** +* @file llsettingsbase.h +* @author optional +* @brief A base class for asset based settings groups. +* +* $LicenseInfo:2011&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2017, 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$ +*/ + +#ifndef LL_SETTINGS_BASE_H +#define LL_SETTINGS_BASE_H + +#include +#include +#include +#include +#include + +#include "llsd.h" +#include "llsdutil.h" +#include "v2math.h" +#include "v3math.h" +#include "v4math.h" +#include "llquaternion.h" +#include "v4color.h" +#include "v3color.h" + +class LLSettingsBase : + public boost::enable_shared_from_this, + private boost::noncopyable +{ + friend class LLEnvironment; + friend class LLSettingsDay; + +public: + static const std::string SETTING_ID; + static const std::string SETTING_NAME; + static const std::string SETTING_HASH; + static const std::string SETTING_TYPE; + + typedef std::map parammapping_t; + + typedef boost::shared_ptr ptr_t; + + virtual ~LLSettingsBase() { }; + + //--------------------------------------------------------------------- + virtual std::string getSettingType() const = 0; + + //--------------------------------------------------------------------- + // Settings status + inline bool hasSetting(const std::string ¶m) const { return mSettings.has(param); } + inline bool isDirty() const { return mDirty; } + inline void setDirtyFlag(bool dirty) { mDirty = dirty; } + + size_t getHash() const; // Hash will not include Name, ID or a previously stored Hash + + inline LLUUID getId() const + { + return getValue(SETTING_ID).asUUID(); + } + + inline std::string getName() const + { + return getValue(SETTING_NAME).asString(); + } + + inline void setName(std::string val) + { + setValue(SETTING_NAME, val); + } + + inline void replaceSettings(LLSD settings) + { + mSettings = settings; + setDirtyFlag(true); + } + + virtual LLSD getSettings() const; + + //--------------------------------------------------------------------- + // + inline void setValue(const std::string &name, const LLSD &value) + { + mSettings[name] = value; + mDirty = true; + } + + inline LLSD getValue(const std::string &name, const LLSD &deflt = LLSD()) const + { + if (!mSettings.has(name)) + return deflt; + return mSettings[name]; + } + + inline void setValue(const std::string &name, const LLVector2 &value) + { + setValue(name, value.getValue()); + } + + inline void setValue(const std::string &name, const LLVector3 &value) + { + setValue(name, value.getValue()); + } + + inline void setValue(const std::string &name, const LLVector4 &value) + { + setValue(name, value.getValue()); + } + + inline void setValue(const std::string &name, const LLQuaternion &value) + { + setValue(name, value.getValue()); + } + + inline void setValue(const std::string &name, const LLColor3 &value) + { + setValue(name, value.getValue()); + } + + inline void setValue(const std::string &name, const LLColor4 &value) + { + setValue(name, value.getValue()); + } + + // Note this method is marked const but may modify the settings object. + // (note the internal const cast). This is so that it may be called without + // special consideration from getters. + inline void update() const + { + if (!mDirty) + return; + (const_cast(this))->updateSettings(); + } + + virtual void blend(const ptr_t &end, F32 blendf) = 0; + + virtual bool validate(); + +protected: + class Validator + { + public: + typedef boost::function verify_pr; + + Validator(std::string name, bool required, LLSD::Type type, verify_pr verify = verify_pr()) : + mName(name), + mRequired(required), + mType(type), + mVerify(verify) + { } + + std::string getName() const { return mName; } + bool isRequired() const { return mRequired; } + LLSD::Type getType() const { return mType; } + + bool verify(LLSD &data); + + // Some basic verifications + static bool verifyColor(LLSD &value); + static bool verifyVector(LLSD &value, S32 length); + static bool verifyVectorMinMax(LLSD &value, LLSD minvals, LLSD maxvals); + static bool verifyVectorNormalized(LLSD &value, S32 length); + static bool verifyQuaternion(LLSD &value); + static bool verifyQuaternionNormal(LLSD &value); + static bool verifyFloatRange(LLSD &value, LLSD range); + static bool verifyIntegerRange(LLSD &value, LLSD range); + + private: + std::string mName; + bool mRequired; + LLSD::Type mType; + verify_pr mVerify; + }; + typedef std::vector validation_list_t; + + LLSettingsBase(); + LLSettingsBase(const LLSD setting); + + typedef std::set stringset_t; + + // combining settings objects. Customize for specific setting types + virtual void lerpSettings(const LLSettingsBase &other, F32 mix); + LLSD interpolateSDMap(const LLSD &settings, const LLSD &other, F32 mix) const; + + /// when lerping between settings, some may require special handling. + /// Get a list of these key to be skipped by the default settings lerp. + /// (handling should be performed in the override of lerpSettings. + virtual stringset_t getSkipInterpolateKeys() const { return stringset_t(); } + + // A list of settings that represent quaternions and should be slerped + // rather than lerped. + virtual stringset_t getSlerpKeys() const { return stringset_t(); } + + // Calculate any custom settings that may need to be cached. + virtual void updateSettings() { mDirty = false; }; + + virtual validation_list_t getValidationList() const = 0; + + // Apply any settings that need special handling. + virtual void applySpecial(void *) { }; + + virtual parammapping_t getParameterMap() const { return parammapping_t(); } + + LLSD mSettings; + bool mIsValid; + + LLSD cloneSettings() const; + +private: + bool mDirty; + + LLSD combineSDMaps(const LLSD &first, const LLSD &other) const; + +}; + + +class LLSettingsBlender : public boost::enable_shared_from_this +{ +public: + typedef boost::shared_ptr ptr_t; + typedef boost::signals2::signal finish_signal_t; + typedef boost::signals2::connection connection_t; + + static const F32Seconds DEFAULT_THRESHOLD; + + LLSettingsBlender(const LLSettingsBase::ptr_t &target, + const LLSettingsBase::ptr_t &initsetting, const LLSettingsBase::ptr_t &endsetting, F32Seconds seconds) : + mTarget(target), + mInitial(initsetting), + mFinal(endsetting), + mSeconds(seconds), + mOnFinished(), + mBlendThreshold(DEFAULT_THRESHOLD), + mLastUpdate(0.0f), + mTimeSpent(0.0f) + { + mTarget->replaceSettings(mInitial->getSettings()); + mTimeStart = F32Seconds(LLDate::now().secondsSinceEpoch()); + mLastUpdate = mTimeStart; + } + + ~LLSettingsBlender() {} + + connection_t setOnFinished(const finish_signal_t::slot_type &onfinished) + { + return mOnFinished.connect(onfinished); + } + + void setUpdateThreshold(F32Seconds threshold) + { + mBlendThreshold = threshold; + } + + F32Seconds getUpdateThreshold() const + { + return mBlendThreshold; + } + + LLSettingsBase::ptr_t getTarget() const + { + return mTarget; + } + + LLSettingsBase::ptr_t getInitial() const + { + return mInitial; + } + + LLSettingsBase::ptr_t getFinal() const + { + return mFinal; + } + + void update(F32Seconds time); +private: + LLSettingsBase::ptr_t mTarget; + LLSettingsBase::ptr_t mInitial; + LLSettingsBase::ptr_t mFinal; + F32Seconds mSeconds; + finish_signal_t mOnFinished; + F32Seconds mBlendThreshold; + F32Seconds mLastUpdate; + F32Seconds mTimeSpent; + F32Seconds mTimeStart; +}; + +#endif diff --git a/indra/llinventory/llsettingsdaycycle.cpp b/indra/llinventory/llsettingsdaycycle.cpp new file mode 100644 index 0000000000..687210e127 --- /dev/null +++ b/indra/llinventory/llsettingsdaycycle.cpp @@ -0,0 +1,545 @@ +/** +* @file llsettingsdaycycle.cpp +* @author optional +* @brief A base class for asset based settings groups. +* +* $LicenseInfo:2011&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2017, 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 "llsettingsdaycycle.h" +#include +#include +#include "lltrace.h" +#include "llfasttimer.h" +#include "v3colorutil.h" + +#include "llsettingssky.h" +#include "llsettingswater.h" + +#include "llframetimer.h" +//========================================================================= +namespace +{ + LLTrace::BlockTimerStatHandle FTM_BLEND_WATERVALUES("Blending Water Environment"); + LLTrace::BlockTimerStatHandle FTM_UPDATE_WATERVALUES("Update Water Environment"); + + inline F32 get_wrapping_distance(F32 begin, F32 end) + { + if (begin < end) + { + return end - begin; + } + else if (begin > end) + { + return 1.0 - (begin - end); + } + + return 0; + } + + LLSettingsDay::CycleTrack_t::iterator get_wrapping_atafter(LLSettingsDay::CycleTrack_t &collection, F32 key) + { + if (collection.empty()) + return collection.end(); + + LLSettingsDay::CycleTrack_t::iterator it = collection.upper_bound(key); + + if (it == collection.end()) + { // wrap around + it = collection.begin(); + } + + return it; + } + + LLSettingsDay::CycleTrack_t::iterator get_wrapping_atbefore(LLSettingsDay::CycleTrack_t &collection, F32 key) + { + if (collection.empty()) + return collection.end(); + + LLSettingsDay::CycleTrack_t::iterator it = collection.lower_bound(key); + + if (it == collection.end()) + { // all keyframes are lower, take the last one. + --it; // we know the range is not empty + } + else if ((*it).first > key) + { // the keyframe we are interested in is smaller than the found. + if (it == collection.begin()) + it = collection.end(); + --it; + } + + return it; + } + + +} + +//========================================================================= +const std::string LLSettingsDay::SETTING_DAYLENGTH("day_length"); +const std::string LLSettingsDay::SETTING_KEYID("key_id"); +const std::string LLSettingsDay::SETTING_KEYNAME("key_name"); +const std::string LLSettingsDay::SETTING_KEYKFRAME("key_keyframe"); +const std::string LLSettingsDay::SETTING_KEYHASH("key_hash"); +const std::string LLSettingsDay::SETTING_TRACKS("tracks"); +const std::string LLSettingsDay::SETTING_FRAMES("frames"); + +const S64 LLSettingsDay::MINIMUM_DAYLENGTH( 300); // 5 mins + +//const S64 LLSettingsDay::MINIMUM_DAYLENGTH( 14400); // 4 hours +const S64 LLSettingsDay::MAXIMUM_DAYLENGTH(604800); // 7 days + +const S32 LLSettingsDay::TRACK_WATER(0); // water track is 0 +const S32 LLSettingsDay::TRACK_MAX(5); // 5 tracks, 4 skys, 1 water +const S32 LLSettingsDay::FRAME_MAX(56); + +//========================================================================= +LLSettingsDay::LLSettingsDay(const LLSD &data) : + LLSettingsBase(data), + mInitialized(false) +{ + mDayTracks.resize(TRACK_MAX); +} + +LLSettingsDay::LLSettingsDay() : + LLSettingsBase(), + mInitialized(false) +{ + mDayTracks.resize(TRACK_MAX); +} + +//========================================================================= +LLSD LLSettingsDay::getSettings() const +{ + LLSD settings(LLSD::emptyMap()); + + if (mSettings.has(SETTING_NAME)) + settings[SETTING_NAME] = mSettings[SETTING_NAME]; + + if (mSettings.has(SETTING_ID)) + settings[SETTING_ID] = mSettings[SETTING_ID]; + + std::map in_use; + + LLSD tracks(LLSD::emptyArray()); + + for (CycleList_t::const_iterator itTrack = mDayTracks.begin(); itTrack != mDayTracks.end(); ++itTrack) + { + LLSD trackout(LLSD::emptyArray()); + + for (CycleTrack_t::const_iterator itFrame = (*itTrack).begin(); itFrame != (*itTrack).end(); ++itFrame) + { + F32 frame = (*itFrame).first; + LLSettingsBase::ptr_t data = (*itFrame).second; + size_t datahash = data->getHash(); + + std::stringstream keyname; + keyname << datahash; + + trackout.append(LLSD(LLSDMap(SETTING_KEYKFRAME, LLSD::Real(frame))(SETTING_KEYNAME, keyname.str()))); + in_use[keyname.str()] = data; + } + tracks.append(trackout); + } + settings[SETTING_TRACKS] = tracks; + + LLSD frames(LLSD::emptyMap()); + for (std::map::iterator itFrame = in_use.begin(); itFrame != in_use.end(); ++itFrame) + { + LLSD framesettings = llsd_clone((*itFrame).second->getSettings(), + LLSDMap("*", true)(SETTING_NAME, false)(SETTING_ID, false)(SETTING_HASH, false)); + + frames[(*itFrame).first] = framesettings; + } + settings[SETTING_FRAMES] = frames; + + return settings; +} + +void LLSettingsDay::initialize() +{ + LLSD tracks = mSettings[SETTING_TRACKS]; + LLSD frames = mSettings[SETTING_FRAMES]; + + std::map used; + + for (LLSD::map_const_iterator itFrame = frames.beginMap(); itFrame != frames.endMap(); ++itFrame) + { + std::string name = (*itFrame).first; + LLSD data = (*itFrame).second; + + if (data[SETTING_TYPE].asString() == "sky") + { + used[name] = buildSky(data); + } + else if (data[SETTING_TYPE].asString() == "water") + { + used[name] = buildWater(data); + } + else + { + LL_WARNS("DAYCYCLE") << "Unknown child setting type '" << data[SETTING_TYPE].asString() << "' named '" << name << "'" << LL_ENDL; + } + } + + for (S32 i = 0; (i < tracks.size()) && (i < TRACK_MAX); ++i) + { + mDayTracks[i].clear(); + LLSD curtrack = tracks[i]; + for (LLSD::array_const_iterator it = curtrack.beginArray(); it != curtrack.endArray(); ++it) + { + F32 keyframe = (*it)[SETTING_KEYKFRAME].asReal(); + keyframe = llclamp(keyframe, 0.0f, 1.0f); + LLSettingsBase::ptr_t setting; + + if ((*it).has(SETTING_KEYNAME)) + { + if (i == TRACK_WATER) + { + setting = used[(*it)[SETTING_KEYNAME]]; + if (!setting) + setting = getNamedWater((*it)[SETTING_KEYNAME]); + if (setting && setting->getSettingType() != "water") + { + LL_WARNS("DAYCYCLE") << "Water track referencing " << setting->getSettingType() << " frame at " << keyframe << "." << LL_ENDL; + setting.reset(); + } + } + else + { + setting = used[(*it)[SETTING_KEYNAME]]; + if (!setting) + setting = getNamedSky((*it)[SETTING_KEYNAME]); + if (setting && setting->getSettingType() != "sky") + { + LL_WARNS("DAYCYCLE") << "Sky track #" << i << " referencing " << setting->getSettingType() << " frame at " << keyframe << "." << LL_ENDL; + setting.reset(); + } + } + } + + if (setting) + mDayTracks[i][keyframe] = setting; + } + } + + // these are no longer needed and just take up space now. + mSettings.erase(SETTING_TRACKS); + mSettings.erase(SETTING_FRAMES); + + mInitialized = true; +} + + +//========================================================================= +LLSD LLSettingsDay::defaults() +{ + LLSD dfltsetting; + + dfltsetting[SETTING_NAME] = "_default_"; + dfltsetting[SETTING_DAYLENGTH] = static_cast(MINIMUM_DAYLENGTH); + dfltsetting[SETTING_TRACKS] = LLSDArray( + LLSDArray(LLSDMap(SETTING_KEYKFRAME, LLSD::Real(0.0f))(SETTING_KEYNAME, "_default_")) + (LLSDMap(SETTING_KEYKFRAME, LLSD::Real(0.0f))(SETTING_KEYNAME, "_default_"))); + dfltsetting[SETTING_FRAMES] = LLSD::emptyMap(); + + return dfltsetting; +} + +void LLSettingsDay::blend(const LLSettingsBase::ptr_t &other, F32 mix) +{ + LL_ERRS("DAYCYCLE") << "Day cycles are not blendable!" << LL_ENDL; +} + +namespace +{ + bool validateDayCycleTrack(LLSD &value) + { + // Trim extra tracks. + while (value.size() > LLSettingsDay::TRACK_MAX) + { + value.erase(value.size() - 1); + } + + for (LLSD::array_iterator track = value.beginArray(); track != value.endArray(); ++track) + { + S32 index = 0; + while (index < (*track).size()) + { + if (index >= LLSettingsDay::FRAME_MAX) + { + (*track).erase(index); + continue; + } + + if (!(*track)[index].has(LLSettingsDay::SETTING_KEYKFRAME) || + !(*track)[index][LLSettingsDay::SETTING_KEYKFRAME].isReal()) + { + (*track).erase(index); + continue; + } + + if (!(*track)[index].has(LLSettingsDay::SETTING_KEYNAME) && + !(*track)[index].has(LLSettingsDay::SETTING_KEYID)) + { + (*track).erase(index); + continue; + } + + F32 frame = (*track)[index][LLSettingsDay::SETTING_KEYKFRAME].asReal(); + if ((frame < 0.0) || (frame > 1.0)) + { + frame = llclamp(frame, 0.0f, 1.0f); + (*track)[index][LLSettingsDay::SETTING_KEYKFRAME] = frame; + } + ++index; + } + + } + return true; + } +} + +LLSettingsDay::validation_list_t LLSettingsDay::getValidationList() const +{ + static validation_list_t validation; + + if (validation.empty()) + { + validation.push_back(Validator(SETTING_TRACKS, false, LLSD::TypeArray, + &validateDayCycleTrack)); + validation.push_back(Validator(SETTING_FRAMES, false, LLSD::TypeMap)); + validation.push_back(Validator(SETTING_DAYLENGTH, false, LLSD::TypeInteger, + boost::bind(&Validator::verifyIntegerRange, _1, + LLSD(LLSDArray(LLSD::Integer(MINIMUM_DAYLENGTH))(LLSD::Integer(MAXIMUM_DAYLENGTH)))))); + } + + return validation; +} + +//========================================================================= +F32 LLSettingsDay::secondsToKeyframe(S64Seconds seconds) +{ + S64Seconds daylength = getDayLength(); + + return llclamp(static_cast(seconds.value() % daylength.value()) / static_cast(daylength.value()), 0.0f, 1.0f); +} + +F64Seconds LLSettingsDay::keyframeToSeconds(F32 keyframe) +{ + S64Seconds daylength = getDayLength(); + + return F64Seconds(static_cast(keyframe * static_cast(daylength.value()))); +} + +//========================================================================= +void LLSettingsDay::startDayCycle() +{ + F64Seconds now(LLDate::now().secondsSinceEpoch()); + + if (!mInitialized) + { + LL_WARNS("DAYCYCLE") << "Attempt to start day cycle on uninitialized object." << LL_ENDL; + return; + } + + // water + if (mDayTracks[0].empty()) + { + mBlendedWater.reset(); + mWaterBlender.reset(); + } + else if (mDayTracks[0].size() == 1) + { + mBlendedWater = boost::static_pointer_cast((*(mDayTracks[0].begin())).second); + mWaterBlender.reset(); + } + else + { + TrackBound_t bounds = getBoundingEntries(mDayTracks[0], now); + + F64Seconds timespan = F64Seconds( getDayLength() * get_wrapping_distance((*bounds.first).first, (*bounds.second).first)); + + mBlendedWater = getDefaultWater(); + mWaterBlender = boost::make_shared(mBlendedWater, + (*bounds.first).second, (*bounds.second).second, timespan); + mWaterBlender->setOnFinished(boost::bind(&LLSettingsDay::onWaterTransitionDone, this, _1)); + } + + // sky + if (mDayTracks[1].empty()) + { + mBlendedSky.reset(); + mSkyBlender.reset(); + } + else if (mDayTracks[1].size() == 1) + { + mBlendedSky = boost::static_pointer_cast( (*(mDayTracks[1].begin())).second); + mSkyBlender.reset(); + } + else + { + TrackBound_t bounds = getBoundingEntries(mDayTracks[1], now); + F64Seconds timespan = F64Seconds(getDayLength() * get_wrapping_distance((*bounds.first).first, (*bounds.second).first)); + + mBlendedSky = getDefaultSky(); + mSkyBlender = boost::make_shared(mBlendedSky, + (*bounds.first).second, (*bounds.second).second, timespan); + mSkyBlender->setOnFinished(boost::bind(&LLSettingsDay::onSkyTransitionDone, this, 1, _1)); + } +} + + +void LLSettingsDay::updateSettings() +{ + static LLFrameTimer timer; + + + F64Seconds delta(timer.getElapsedTimeAndResetF32()); + + if (mSkyBlender) + mSkyBlender->update(delta); + if (mWaterBlender) + mWaterBlender->update(delta); +} + +//========================================================================= +void LLSettingsDay::setDayLength(S64Seconds seconds) +{ + S32 val = llclamp(seconds.value(), MINIMUM_DAYLENGTH, MAXIMUM_DAYLENGTH); + + setValue(SETTING_DAYLENGTH, val); +} + +LLSettingsDay::KeyframeList_t LLSettingsDay::getTrackKeyframes(S32 trackno) +{ + if ((trackno < 1) || (trackno >= TRACK_MAX)) + { + LL_WARNS("DAYCYCLE") << "Attempt get track (#" << trackno << ") out of range!" << LL_ENDL; + return KeyframeList_t(); + } + + KeyframeList_t keyframes; + CycleTrack_t &track = mDayTracks[trackno]; + + keyframes.reserve(track.size()); + + for (CycleTrack_t::iterator it = track.begin(); it != track.end(); ++it) + { + keyframes.push_back((*it).first); + } + + return keyframes; +} + +LLSettingsDay::TimeList_t LLSettingsDay::getTrackTimes(S32 trackno) +{ + KeyframeList_t keyframes = getTrackKeyframes(trackno); + + if (keyframes.empty()) + return TimeList_t(); + + TimeList_t times; + + times.reserve(keyframes.size()); + for (KeyframeList_t::iterator it = keyframes.begin(); it != keyframes.end(); ++it) + { + times.push_back(keyframeToSeconds(*it)); + } + + return times; +} + +void LLSettingsDay::setWaterAtTime(const LLSettingsWaterPtr_t &water, S64Seconds seconds) +{ + F32 keyframe = secondsToKeyframe(seconds); + setWaterAtKeyframe(water, keyframe); +} + +void LLSettingsDay::setWaterAtKeyframe(const LLSettingsWaterPtr_t &water, F32 keyframe) +{ + mDayTracks[TRACK_WATER][llclamp(keyframe, 0.0f, 1.0f)] = water; + setDirtyFlag(true); +} + + +void LLSettingsDay::setSkyAtTime(const LLSettingsSkyPtr_t &sky, S64Seconds seconds, S32 track) +{ + F32 keyframe = secondsToKeyframe(seconds); + setSkyAtKeyframe(sky, keyframe, track); +} + +void LLSettingsDay::setSkyAtKeyframe(const LLSettingsSkyPtr_t &sky, F32 keyframe, S32 track) +{ + if ((track < 1) || (track >= TRACK_MAX)) + { + LL_WARNS("DAYCYCLE") << "Attempt to set sky track (#" << track << ") out of range!" << LL_ENDL; + return; + } + + mDayTracks[track][llclamp(keyframe, 0.0f, 1.0f)] = sky; + setDirtyFlag(true); +} + +LLSettingsDay::TrackBound_t LLSettingsDay::getBoundingEntries(LLSettingsDay::CycleTrack_t &track, F32 keyframe) +{ + return TrackBound_t(get_wrapping_atbefore(track, keyframe), get_wrapping_atafter(track, keyframe)); +} + +LLSettingsDay::TrackBound_t LLSettingsDay::getBoundingEntries(LLSettingsDay::CycleTrack_t &track, F64Seconds time) +{ + F32 frame = secondsToKeyframe(time); + + return getBoundingEntries(track, frame); +} + +//========================================================================= +void LLSettingsDay::onSkyTransitionDone(S32 track, const LLSettingsBlender::ptr_t &blender) +{ + F64Seconds now(LLDate::now().secondsSinceEpoch()); + TrackBound_t bounds = getBoundingEntries(mDayTracks[track], now); + + F32 distance = get_wrapping_distance((*bounds.first).first, (*bounds.second).first); + F64Seconds timespan = F64Seconds(distance * getDayLength()); + + LL_DEBUGS("DAYCYCLE") << "New sky blender. now=" << now << + " start=" << (*bounds.first).first << " end=" << (*bounds.second).first << + " span=" << timespan << LL_ENDL; + + mSkyBlender = boost::make_shared(mBlendedSky, + (*bounds.first).second, (*bounds.second).second, timespan); + mSkyBlender->setOnFinished(boost::bind(&LLSettingsDay::onSkyTransitionDone, this, track, _1)); +} + +void LLSettingsDay::onWaterTransitionDone(const LLSettingsBlender::ptr_t &blender) +{ + F64Seconds now(LLDate::now().secondsSinceEpoch()); + TrackBound_t bounds = getBoundingEntries(mDayTracks[0], now); + + F32 distance = get_wrapping_distance((*bounds.first).first, (*bounds.second).first); + F64Seconds timespan = F64Seconds(distance * getDayLength()); + + mWaterBlender = boost::make_shared(mBlendedWater, + (*bounds.first).second, (*bounds.second).second, timespan); + mWaterBlender->setOnFinished(boost::bind(&LLSettingsDay::onWaterTransitionDone, this, _1)); +} diff --git a/indra/llinventory/llsettingsdaycycle.h b/indra/llinventory/llsettingsdaycycle.h new file mode 100644 index 0000000000..3b24ce9f97 --- /dev/null +++ b/indra/llinventory/llsettingsdaycycle.h @@ -0,0 +1,156 @@ +/** +* @file llsettingsdaycycle.h +* @author optional +* @brief A base class for asset based settings groups. +* +* $LicenseInfo:2011&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2017, 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$ +*/ + +#ifndef LL_SETTINGS_DAYCYCLE_H +#define LL_SETTINGS_DAYCYCLE_H + +#include "llsettingsbase.h" + +class LLSettingsWater; +class LLSettingsSky; + +typedef boost::shared_ptr LLSettingsWaterPtr_t; +typedef boost::shared_ptr LLSettingsSkyPtr_t; + +class LLSettingsDay : public LLSettingsBase +{ +public: + static const std::string SETTING_DAYLENGTH; + static const std::string SETTING_KEYID; + static const std::string SETTING_KEYNAME; + static const std::string SETTING_KEYKFRAME; + static const std::string SETTING_KEYHASH; + static const std::string SETTING_TRACKS; + static const std::string SETTING_FRAMES; + + static const S64 MINIMUM_DAYLENGTH; + static const S64 MAXIMUM_DAYLENGTH; + + static const S32 TRACK_WATER; + static const S32 TRACK_MAX; + static const S32 FRAME_MAX; + + typedef std::map CycleTrack_t; + typedef std::vector CycleList_t; + typedef boost::shared_ptr ptr_t; + typedef std::vector TimeList_t; + typedef std::vector KeyframeList_t; + typedef std::pair TrackBound_t; + + //--------------------------------------------------------------------- + LLSettingsDay(const LLSD &data); + virtual ~LLSettingsDay() { }; + + void initialize(); + + virtual ptr_t buildClone() = 0; + virtual LLSD getSettings() const; + + //--------------------------------------------------------------------- + virtual std::string getSettingType() const { return std::string("daycycle"); } + + // Settings status + virtual void blend(const LLSettingsBase::ptr_t &other, F32 mix); + + static LLSD defaults(); + + //--------------------------------------------------------------------- + S64Seconds getDayLength() const + { + return S64Seconds(mSettings[SETTING_DAYLENGTH].asInteger()); + } + + void setDayLength(S64Seconds seconds); + + KeyframeList_t getTrackKeyframes(S32 track); + TimeList_t getTrackTimes(S32 track); + + void setWaterAtTime(const LLSettingsWaterPtr_t &water, S64Seconds seconds); + void setWaterAtKeyframe(const LLSettingsWaterPtr_t &water, F32 keyframe); + + void setSkyAtTime(const LLSettingsSkyPtr_t &sky, S64Seconds seconds, S32 track); + void setSkyAtKeyframe(const LLSettingsSkyPtr_t &sky, F32 keyframe, S32 track); + //--------------------------------------------------------------------- + void startDayCycle(); + + LLSettingsSkyPtr_t getCurrentSky() const + { + return mBlendedSky; + } + + LLSettingsWaterPtr_t getCurrentWater() const + { + return mBlendedWater; + } + + virtual LLSettingsSkyPtr_t getDefaultSky() const = 0; + virtual LLSettingsWaterPtr_t getDefaultWater() const = 0; + + virtual LLSettingsSkyPtr_t buildSky(LLSD) const = 0; + virtual LLSettingsWaterPtr_t buildWater(LLSD) const = 0; + + virtual LLSettingsSkyPtr_t getNamedSky(const std::string &) const = 0; + virtual LLSettingsWaterPtr_t getNamedWater(const std::string &) const = 0; + + void setInitialized(bool value = true) { mInitialized = value; } +protected: + LLSettingsDay(); + + virtual void updateSettings(); + + virtual validation_list_t getValidationList() const; + + bool mInitialized; + +private: + LLSettingsBlender::ptr_t mSkyBlender; // convert to [] for altitudes + LLSettingsBlender::ptr_t mWaterBlender; + + LLSettingsSkyPtr_t mBlendedSky; + LLSettingsWaterPtr_t mBlendedWater; + + CycleList_t mDayTracks; + + F64Seconds mLastUpdateTime; + + F32 secondsToKeyframe(S64Seconds seconds); + F64Seconds keyframeToSeconds(F32 keyframe); + + void parseFromLLSD(LLSD &data); + + static CycleTrack_t::iterator getEntryAtOrBefore(CycleTrack_t &track, F32 keyframe); + static CycleTrack_t::iterator getEntryAtOrAfter(CycleTrack_t &track, F32 keyframe); + + TrackBound_t getBoundingEntries(CycleTrack_t &track, F32 keyframe); + TrackBound_t getBoundingEntries(CycleTrack_t &track, F64Seconds time); + + void onSkyTransitionDone(S32 track, const LLSettingsBlender::ptr_t &blender); + void onWaterTransitionDone(const LLSettingsBlender::ptr_t &blender); + +}; + +#endif diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp new file mode 100644 index 0000000000..ecc89165e8 --- /dev/null +++ b/indra/llinventory/llsettingssky.cpp @@ -0,0 +1,561 @@ +/** +* @file llsettingssky.cpp +* @author optional +* @brief A base class for asset based settings groups. +* +* $LicenseInfo:2011&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2017, 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 "llsettingssky.h" +#include "indra_constants.h" +#include +#include "lltrace.h" +#include "llfasttimer.h" +#include "v3colorutil.h" + +//========================================================================= +namespace +{ + const LLVector3 DUE_EAST(0.0f, 0.0f, 1.0); + const LLVector3 VECT_ZENITH(0.f, 1.f, 0.f); + const LLVector3 VECT_NORTHSOUTH(1.f, 0.f, 0.f); + + LLTrace::BlockTimerStatHandle FTM_BLEND_SKYVALUES("Blending Sky Environment"); + LLTrace::BlockTimerStatHandle FTM_UPDATE_SKYVALUES("Update Sky Environment"); + + LLQuaternion body_position_from_angles(F32 azimuth, F32 altitude); + void angles_from_rotation(LLQuaternion quat, F32 &azimuth, F32 &altitude); +} + +const F32 LLSettingsSky::DOME_OFFSET(0.96f); +const F32 LLSettingsSky::DOME_RADIUS(15000.f); + +const F32 LLSettingsSky::NIGHTTIME_ELEVATION(-8.0f); // degrees +const F32 LLSettingsSky::NIGHTTIME_ELEVATION_COS((F32)sin(NIGHTTIME_ELEVATION*DEG_TO_RAD)); + +//========================================================================= +const std::string LLSettingsSky::SETTING_AMBIENT("ambient"); +const std::string LLSettingsSky::SETTING_BLOOM_TEXTUREID("bloom_id"); +const std::string LLSettingsSky::SETTING_BLUE_DENSITY("blue_density"); +const std::string LLSettingsSky::SETTING_BLUE_HORIZON("blue_horizon"); +const std::string LLSettingsSky::SETTING_CLOUD_COLOR("cloud_color"); +const std::string LLSettingsSky::SETTING_CLOUD_POS_DENSITY1("cloud_pos_density1"); +const std::string LLSettingsSky::SETTING_CLOUD_POS_DENSITY2("cloud_pos_density2"); +const std::string LLSettingsSky::SETTING_CLOUD_SCALE("cloud_scale"); +const std::string LLSettingsSky::SETTING_CLOUD_SCROLL_RATE("cloud_scroll_rate"); +const std::string LLSettingsSky::SETTING_CLOUD_SHADOW("cloud_shadow"); +const std::string LLSettingsSky::SETTING_CLOUD_TEXTUREID("cloud_id"); +const std::string LLSettingsSky::SETTING_DENSITY_MULTIPLIER("density_multiplier"); +const std::string LLSettingsSky::SETTING_DISTANCE_MULTIPLIER("distance_multiplier"); +const std::string LLSettingsSky::SETTING_DOME_OFFSET("dome_offset"); +const std::string LLSettingsSky::SETTING_DOME_RADIUS("dome_radius"); +const std::string LLSettingsSky::SETTING_GAMMA("gamma"); +const std::string LLSettingsSky::SETTING_GLOW("glow"); +const std::string LLSettingsSky::SETTING_HAZE_DENSITY("haze_density"); +const std::string LLSettingsSky::SETTING_HAZE_HORIZON("haze_horizon"); +const std::string LLSettingsSky::SETTING_LIGHT_NORMAL("lightnorm"); +const std::string LLSettingsSky::SETTING_MAX_Y("max_y"); +const std::string LLSettingsSky::SETTING_MOON_ROTATION("moon_rotation"); +const std::string LLSettingsSky::SETTING_MOON_TEXTUREID("moon_id"); +const std::string LLSettingsSky::SETTING_STAR_BRIGHTNESS("star_brightness"); +const std::string LLSettingsSky::SETTING_SUNLIGHT_COLOR("sunlight_color"); +const std::string LLSettingsSky::SETTING_SUN_ROTATION("sun_rotation"); +const std::string LLSettingsSky::SETTING_SUN_TEXUTUREID("sun_id"); + +const std::string LLSettingsSky::SETTING_LEGACY_EAST_ANGLE("east_angle"); +const std::string LLSettingsSky::SETTING_LEGACY_ENABLE_CLOUD_SCROLL("enable_cloud_scroll"); +const std::string LLSettingsSky::SETTING_LEGACY_SUN_ANGLE("sun_angle"); + +//========================================================================= +LLSettingsSky::LLSettingsSky(const LLSD &data) : + LLSettingsBase(data) +{ +} + +LLSettingsSky::LLSettingsSky(): + LLSettingsBase() +{ +} + +void LLSettingsSky::blend(const LLSettingsBase::ptr_t &end, F32 blendf) +{ + LLSettingsSky::ptr_t other = boost::static_pointer_cast(end); + LLSD blenddata = interpolateSDMap(mSettings, other->mSettings, blendf); + + replaceSettings(blenddata); +} + + +void LLSettingsSky::setMoonRotation(F32 azimuth, F32 altitude) +{ + setValue(SETTING_MOON_ROTATION, ::body_position_from_angles(azimuth, altitude)); +} + +LLSettingsSky::azimalt_t LLSettingsSky::getMoonRotationAzAl() const +{ + azimalt_t res; + ::angles_from_rotation(getMoonRotation(), res.first, res.second); + + return res; +} + +void LLSettingsSky::setSunRotation(F32 azimuth, F32 altitude) +{ + setValue(SETTING_SUN_ROTATION, ::body_position_from_angles(azimuth, altitude)); +} + +LLSettingsSky::azimalt_t LLSettingsSky::getSunRotationAzAl() const +{ + azimalt_t res; + ::angles_from_rotation(getSunRotation(), res.first, res.second); + + return res; +} + +LLSettingsSky::stringset_t LLSettingsSky::getSlerpKeys() const +{ + static stringset_t slepSet; + + if (slepSet.empty()) + { + slepSet.insert(SETTING_SUN_ROTATION); + slepSet.insert(SETTING_MOON_ROTATION); + } + + return slepSet; +} + +LLSettingsSky::validation_list_t LLSettingsSky::getValidationList() const +{ + static validation_list_t validation; + + if (validation.empty()) + { // Note the use of LLSD(LLSDArray()()()...) This is due to an issue with the + // copy constructor for LLSDArray. Directly binding the LLSDArray as + // a parameter without first wrapping it in a pure LLSD object will result + // in deeply nested arrays like this [[[[[[[[[[v1,v2,v3]]]]]]]]]] + + validation.push_back(Validator(SETTING_AMBIENT, true, LLSD::TypeArray, + boost::bind(&Validator::verifyVectorMinMax, _1, + LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")), + LLSD(LLSDArray(3.0f)(3.0f)(3.0f)("*"))))); + validation.push_back(Validator(SETTING_BLOOM_TEXTUREID, true, LLSD::TypeUUID)); + validation.push_back(Validator(SETTING_BLUE_DENSITY, true, LLSD::TypeArray, + boost::bind(&Validator::verifyVectorMinMax, _1, + LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")), + LLSD(LLSDArray(2.0f)(2.0f)(2.0f)("*"))))); + validation.push_back(Validator(SETTING_BLUE_HORIZON, true, LLSD::TypeArray, + boost::bind(&Validator::verifyVectorMinMax, _1, + LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")), + LLSD(LLSDArray(2.0f)(2.0f)(2.0f)("*"))))); + validation.push_back(Validator(SETTING_CLOUD_COLOR, true, LLSD::TypeArray, + boost::bind(&Validator::verifyVectorMinMax, _1, + LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")), + LLSD(LLSDArray(1.0f)(1.0f)(1.0f)("*"))))); + validation.push_back(Validator(SETTING_CLOUD_POS_DENSITY1, true, LLSD::TypeArray, + boost::bind(&Validator::verifyVectorMinMax, _1, + LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")), + LLSD(LLSDArray(1.68841f)(1.0f)(1.0f)("*"))))); + validation.push_back(Validator(SETTING_CLOUD_POS_DENSITY2, true, LLSD::TypeArray, + boost::bind(&Validator::verifyVectorMinMax, _1, + LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")), + LLSD(LLSDArray(1.68841f)(1.0f)(1.0f)("*"))))); + validation.push_back(Validator(SETTING_CLOUD_SCALE, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.001f)(0.999f))))); + validation.push_back(Validator(SETTING_CLOUD_SCROLL_RATE, true, LLSD::TypeArray, + boost::bind(&Validator::verifyVectorMinMax, _1, + LLSD(LLSDArray(0.0f)(0.0f)), + LLSD(LLSDArray(20.0f)(20.0f))))); + validation.push_back(Validator(SETTING_CLOUD_SHADOW, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f))))); + validation.push_back(Validator(SETTING_CLOUD_TEXTUREID, false, LLSD::TypeUUID)); + validation.push_back(Validator(SETTING_DENSITY_MULTIPLIER, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(0.0009f))))); + validation.push_back(Validator(SETTING_DISTANCE_MULTIPLIER, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(100.0f))))); + validation.push_back(Validator(SETTING_DOME_OFFSET, false, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f))))); + validation.push_back(Validator(SETTING_DOME_RADIUS, false, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(1000.0f)(2000.0f))))); + validation.push_back(Validator(SETTING_GAMMA, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(10.0f))))); + validation.push_back(Validator(SETTING_GLOW, true, LLSD::TypeArray, + boost::bind(&Validator::verifyVectorMinMax, _1, + LLSD(LLSDArray(0.2f)("*")(-2.5f)("*")), + LLSD(LLSDArray(20.0f)("*")(0.0f)("*"))))); + validation.push_back(Validator(SETTING_HAZE_DENSITY, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(4.0f))))); + validation.push_back(Validator(SETTING_HAZE_HORIZON, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f))))); + validation.push_back(Validator(SETTING_LIGHT_NORMAL, false, LLSD::TypeArray, + boost::bind(&Validator::verifyVectorNormalized, _1, 3))); + validation.push_back(Validator(SETTING_MAX_Y, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(4000.0f))))); + validation.push_back(Validator(SETTING_MOON_ROTATION, true, LLSD::TypeArray, &Validator::verifyQuaternionNormal)); + validation.push_back(Validator(SETTING_MOON_TEXTUREID, false, LLSD::TypeUUID)); + validation.push_back(Validator(SETTING_STAR_BRIGHTNESS, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(2.0f))))); + validation.push_back(Validator(SETTING_SUNLIGHT_COLOR, true, LLSD::TypeArray, + boost::bind(&Validator::verifyVectorMinMax, _1, + LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")), + LLSD(LLSDArray(3.0f)(3.0f)(3.0f)("*"))))); + validation.push_back(Validator(SETTING_SUN_ROTATION, true, LLSD::TypeArray, &Validator::verifyQuaternionNormal)); + validation.push_back(Validator(SETTING_SUN_TEXUTUREID, false, LLSD::TypeUUID)); + } + + return validation; +} + + +LLSD LLSettingsSky::defaults() +{ + LLSD dfltsetting; + + + LLQuaternion sunquat; + sunquat.setEulerAngles(1.39626, 0.0, 0.0); // 80deg Azumith/0deg East + LLQuaternion moonquat = ~sunquat; + + // Magic constants copied form dfltsetting.xml + dfltsetting[SETTING_AMBIENT] = LLColor4::white.getValue(); + dfltsetting[SETTING_BLUE_DENSITY] = LLColor4(0.2447, 0.4487, 0.7599, 0.0).getValue(); + dfltsetting[SETTING_BLUE_HORIZON] = LLColor4(0.4954, 0.4954, 0.6399, 0.0).getValue(); + dfltsetting[SETTING_CLOUD_COLOR] = LLColor4(0.4099, 0.4099, 0.4099, 0.0).getValue(); + dfltsetting[SETTING_CLOUD_POS_DENSITY1] = LLColor4(1.0000, 0.5260, 1.0000, 0.0).getValue(); + dfltsetting[SETTING_CLOUD_POS_DENSITY2] = LLColor4(1.0000, 0.5260, 1.0000, 0.0).getValue(); + dfltsetting[SETTING_CLOUD_SCALE] = LLSD::Real(0.4199); + dfltsetting[SETTING_CLOUD_SCROLL_RATE] = LLSDArray(10.1999)(10.0109); + dfltsetting[SETTING_CLOUD_SHADOW] = LLSD::Real(0.2699); + dfltsetting[SETTING_DENSITY_MULTIPLIER] = LLSD::Real(0.0001); + dfltsetting[SETTING_DISTANCE_MULTIPLIER] = LLSD::Real(0.8000); + dfltsetting[SETTING_DOME_OFFSET] = LLSD::Real(0.96f); + dfltsetting[SETTING_DOME_RADIUS] = LLSD::Real(15000.f); + dfltsetting[SETTING_GAMMA] = LLSD::Real(1.0); + dfltsetting[SETTING_GLOW] = LLColor4(5.000, 0.0010, -0.4799, 1.0).getValue(); + dfltsetting[SETTING_HAZE_DENSITY] = LLSD::Real(0.6999); + dfltsetting[SETTING_HAZE_HORIZON] = LLSD::Real(0.1899); + dfltsetting[SETTING_LIGHT_NORMAL] = LLVector3(0.0000, 0.9126, -0.4086).getValue(); + dfltsetting[SETTING_MAX_Y] = LLSD::Real(1605); + dfltsetting[SETTING_MOON_ROTATION] = moonquat.getValue(); + dfltsetting[SETTING_STAR_BRIGHTNESS] = LLSD::Real(0.0000); + dfltsetting[SETTING_SUNLIGHT_COLOR] = LLColor4(0.7342, 0.7815, 0.8999, 0.0).getValue(); + dfltsetting[SETTING_SUN_ROTATION] = sunquat.getValue(); + + dfltsetting[SETTING_BLOOM_TEXTUREID] = LLUUID::null; + dfltsetting[SETTING_CLOUD_TEXTUREID] = LLUUID::null; + dfltsetting[SETTING_MOON_TEXTUREID] = IMG_MOON; // gMoonTextureID; // These two are returned by the login... wow! + dfltsetting[SETTING_SUN_TEXUTUREID] = IMG_SUN; // gSunTextureID; + + return dfltsetting; +} + +LLSD LLSettingsSky::translateLegacySettings(LLSD legacy) +{ + LLSD newsettings(defaults()); + + if (legacy.has(SETTING_AMBIENT)) + { + newsettings[SETTING_AMBIENT] = LLColor3(legacy[SETTING_AMBIENT]).getValue(); + } + if (legacy.has(SETTING_BLUE_DENSITY)) + { + newsettings[SETTING_BLUE_DENSITY] = LLColor3(legacy[SETTING_BLUE_DENSITY]).getValue(); + } + if (legacy.has(SETTING_BLUE_HORIZON)) + { + newsettings[SETTING_BLUE_HORIZON] = LLColor3(legacy[SETTING_BLUE_HORIZON]).getValue(); + } + if (legacy.has(SETTING_CLOUD_COLOR)) + { + newsettings[SETTING_CLOUD_COLOR] = LLColor3(legacy[SETTING_CLOUD_COLOR]).getValue(); + } + if (legacy.has(SETTING_CLOUD_POS_DENSITY1)) + { + newsettings[SETTING_CLOUD_POS_DENSITY1] = LLColor3(legacy[SETTING_CLOUD_POS_DENSITY1]).getValue(); + } + if (legacy.has(SETTING_CLOUD_POS_DENSITY2)) + { + newsettings[SETTING_CLOUD_POS_DENSITY2] = LLColor3(legacy[SETTING_CLOUD_POS_DENSITY2]).getValue(); + } + if (legacy.has(SETTING_CLOUD_SCALE)) + { + newsettings[SETTING_CLOUD_SCALE] = LLSD::Real(legacy[SETTING_CLOUD_SCALE][0].asReal()); + } + if (legacy.has(SETTING_CLOUD_SCROLL_RATE)) + { + LLVector2 cloud_scroll(legacy[SETTING_CLOUD_SCROLL_RATE]); + + if (legacy.has(SETTING_LEGACY_ENABLE_CLOUD_SCROLL)) + { + LLSD enabled = legacy[SETTING_LEGACY_ENABLE_CLOUD_SCROLL]; + if (!enabled[0].asBoolean()) + cloud_scroll.mV[0] = 0.0f; + if (!enabled[1].asBoolean()) + cloud_scroll.mV[1] = 0.0f; + } + + newsettings[SETTING_CLOUD_SCROLL_RATE] = cloud_scroll.getValue(); + } + if (legacy.has(SETTING_CLOUD_SHADOW)) + { + newsettings[SETTING_CLOUD_SHADOW] = LLSD::Real(legacy[SETTING_CLOUD_SHADOW][0].asReal()); + } + if (legacy.has(SETTING_DENSITY_MULTIPLIER)) + { + newsettings[SETTING_DENSITY_MULTIPLIER] = LLSD::Real(legacy[SETTING_DENSITY_MULTIPLIER][0].asReal()); + } + if (legacy.has(SETTING_DISTANCE_MULTIPLIER)) + { + newsettings[SETTING_DISTANCE_MULTIPLIER] = LLSD::Real(legacy[SETTING_DISTANCE_MULTIPLIER][0].asReal()); + } + if (legacy.has(SETTING_GAMMA)) + { + newsettings[SETTING_GAMMA] = legacy[SETTING_GAMMA][0].asReal(); + } + if (legacy.has(SETTING_GLOW)) + { + newsettings[SETTING_GLOW] = LLColor3(legacy[SETTING_GLOW]).getValue(); + } + if (legacy.has(SETTING_HAZE_DENSITY)) + { + newsettings[SETTING_HAZE_DENSITY] = LLSD::Real(legacy[SETTING_HAZE_DENSITY][0].asReal()); + } + if (legacy.has(SETTING_HAZE_HORIZON)) + { + newsettings[SETTING_HAZE_HORIZON] = LLSD::Real(legacy[SETTING_HAZE_HORIZON][0].asReal()); + } + if (legacy.has(SETTING_LIGHT_NORMAL)) + { + newsettings[SETTING_LIGHT_NORMAL] = LLVector3(legacy[SETTING_LIGHT_NORMAL]).getValue(); + } + if (legacy.has(SETTING_MAX_Y)) + { + newsettings[SETTING_MAX_Y] = LLSD::Real(legacy[SETTING_MAX_Y][0].asReal()); + } + if (legacy.has(SETTING_STAR_BRIGHTNESS)) + { + newsettings[SETTING_STAR_BRIGHTNESS] = LLSD::Real(legacy[SETTING_STAR_BRIGHTNESS].asReal()); + } + if (legacy.has(SETTING_SUNLIGHT_COLOR)) + { + newsettings[SETTING_SUNLIGHT_COLOR] = LLColor4(legacy[SETTING_SUNLIGHT_COLOR]).getValue(); + } + + if (legacy.has(SETTING_LEGACY_EAST_ANGLE) && legacy.has(SETTING_LEGACY_SUN_ANGLE)) + { // convert the east and sun angles into a quaternion. + F32 azimuth = legacy[SETTING_LEGACY_EAST_ANGLE].asReal(); + F32 altitude = legacy[SETTING_LEGACY_SUN_ANGLE].asReal(); + + LLQuaternion sunquat = ::body_position_from_angles(azimuth, altitude); + LLQuaternion moonquat = ::body_position_from_angles(azimuth + F_PI, -altitude); + + F32 az(0), al(0); + ::angles_from_rotation(sunquat, az, al); + + newsettings[SETTING_SUN_ROTATION] = sunquat.getValue(); + newsettings[SETTING_MOON_ROTATION] = moonquat.getValue(); + } + + return newsettings; +} + +void LLSettingsSky::updateSettings() +{ + LL_RECORD_BLOCK_TIME(FTM_UPDATE_SKYVALUES); + //LL_INFOS("WINDLIGHT", "SKY", "EEP") << "WL Parameters are dirty. Reticulating Splines..." << LL_ENDL; + + // base class clears dirty flag so as to not trigger recursive update + LLSettingsBase::updateSettings(); + + calculateHeavnlyBodyPositions(); + calculateLightSettings(); +} + +void LLSettingsSky::calculateHeavnlyBodyPositions() +{ + mSunDirection = DUE_EAST * getSunRotation(); + mSunDirection.normalize(); + mMoonDirection = DUE_EAST * getMoonRotation(); + mMoonDirection.normalize(); + + // is the normal from the sun or the moon + if (mSunDirection.mV[1] >= 0.0) + { + mLightDirection = mSunDirection; + } + else if (mSunDirection.mV[1] < 0.0 && mSunDirection.mV[1] > NIGHTTIME_ELEVATION_COS) + { + // clamp v1 to 0 so sun never points up and causes weirdness on some machines + LLVector3 vec(mSunDirection); + vec.mV[1] = 0.0; + vec.normalize(); + mLightDirection = vec; + } + else + { + mLightDirection = mMoonDirection; + } + + // calculate the clamp lightnorm for sky (to prevent ugly banding in sky + // when haze goes below the horizon + mClampedLightDirection = mLightDirection; + + if (mClampedLightDirection.mV[1] < -0.1f) + { + mClampedLightDirection.mV[1] = -0.1f; + mClampedLightDirection.normalize(); + } +} + +void LLSettingsSky::calculateLightSettings() +{ + LLColor3 vary_HazeColor; + LLColor3 vary_SunlightColor; + LLColor3 vary_AmbientColor; + { + // Initialize temp variables + LLColor3 sunlight = getSunlightColor(); + LLColor3 ambient = getAmbientColor(); + F32 gamma = getGamma(); + LLColor3 blue_density = getBlueDensity(); + LLColor3 blue_horizon = getBlueHorizon(); + F32 haze_density = getHazeDensity(); + F32 haze_horizon = getHazeHorizon(); + F32 density_multiplier = getDensityMultiplier(); + F32 max_y = getMaxY(); + F32 cloud_shadow = getCloudShadow(); + LLVector3 lightnorm = getLightDirection(); + + // Sunlight attenuation effect (hue and brightness) due to atmosphere + // this is used later for sunlight modulation at various altitudes + LLColor3 light_atten = + (blue_density * 1.0 + smear(haze_density * 0.25f)) * (density_multiplier * max_y); + + // Calculate relative weights + LLColor3 temp2(0.f, 0.f, 0.f); + LLColor3 temp1 = blue_density + smear(haze_density); + LLColor3 blue_weight = componentDiv(blue_density, temp1); + LLColor3 haze_weight = componentDiv(smear(haze_density), temp1); + + // Compute sunlight from P & lightnorm (for long rays like sky) + /// USE only lightnorm. + // temp2[1] = llmax(0.f, llmax(0.f, Pn[1]) * 1.0f + lightnorm[1] ); + + // and vary_sunlight will work properly with moon light + F32 lighty = lightnorm[1]; + if (lighty < NIGHTTIME_ELEVATION_COS) + { + lighty = -lighty; + } + + temp2.mV[1] = llmax(0.f, lighty); + if(temp2.mV[1] > 0.f) + { + temp2.mV[1] = 1.f / temp2.mV[1]; + } + componentMultBy(sunlight, componentExp((light_atten * -1.f) * temp2.mV[1])); + + // Distance + temp2.mV[2] = density_multiplier; + + // Transparency (-> temp1) + temp1 = componentExp((temp1 * -1.f) * temp2.mV[2]); + + // vary_AtmosAttenuation = temp1; + + //increase ambient when there are more clouds + LLColor3 tmpAmbient = ambient + (smear(1.f) - ambient) * cloud_shadow * 0.5f; + + //haze color + vary_HazeColor = + (blue_horizon * blue_weight * (sunlight*(1.f - cloud_shadow) + tmpAmbient) + + componentMult(haze_horizon * haze_weight, sunlight*(1.f - cloud_shadow) * temp2.mV[0] + tmpAmbient) + ); + + //brightness of surface both sunlight and ambient + vary_SunlightColor = componentMult(sunlight, temp1) * 1.f; + vary_SunlightColor.clamp(); + vary_SunlightColor = smear(1.0f) - vary_SunlightColor; + vary_SunlightColor = componentPow(vary_SunlightColor, gamma); + vary_SunlightColor = smear(1.0f) - vary_SunlightColor; + vary_AmbientColor = componentMult(tmpAmbient, temp1) * 0.5; + vary_AmbientColor.clamp(); + vary_AmbientColor = smear(1.0f) - vary_AmbientColor; + vary_AmbientColor = componentPow(vary_AmbientColor, gamma); + vary_AmbientColor = smear(1.0f) - vary_AmbientColor; + + componentMultBy(vary_HazeColor, LLColor3(1.f, 1.f, 1.f) - temp1); + + } + + mSunDiffuse = vary_SunlightColor; + mSunAmbient = vary_AmbientColor; + mMoonDiffuse = vary_SunlightColor; + mMoonAmbient = vary_AmbientColor; + + mTotalAmbient = LLColor4(vary_AmbientColor, 1.0f); + + mFadeColor = mTotalAmbient + (mSunDiffuse + mMoonDiffuse) * 0.5f; + mFadeColor.setAlpha(0); +} + + +//========================================================================= +namespace +{ + LLQuaternion body_position_from_angles(F32 azimuth, F32 altitude) + { + // Azimuth is traditionally calculated from North, we are going from East. + LLQuaternion rot_azi; + LLQuaternion rot_alt; + + rot_azi.setAngleAxis(azimuth, VECT_ZENITH); + rot_alt.setAngleAxis(-altitude, VECT_NORTHSOUTH); + + LLQuaternion body_quat = rot_alt * rot_azi; + body_quat.normalize(); + + //LLVector3 sun_vector = (DUE_EAST * body_quat); + //_WARNS("RIDER") << "Azimuth=" << azimuth << " Altitude=" << altitude << " Body Vector=" << sun_vector.getValue() << LL_ENDL; + return body_quat; + } + + void angles_from_rotation(LLQuaternion quat, F32 &azimuth, F32 &altitude) + { + LLVector3 body_vector = (DUE_EAST * quat); + + LLVector3 body_az(body_vector[0], 0.f, body_vector[2]); + LLVector3 body_al(0.f, body_vector[1], body_vector[2]); + + if (fabs(body_az.normalize()) > 0.001) + azimuth = angle_between(DUE_EAST, body_az); + else + azimuth = 0.0f; + + if (fabs(body_al.normalize()) > 0.001) + altitude = angle_between(DUE_EAST, body_al); + else + altitude = 0.0f; + } +} + + diff --git a/indra/llinventory/llsettingssky.h b/indra/llinventory/llsettingssky.h new file mode 100644 index 0000000000..ff4b62f86e --- /dev/null +++ b/indra/llinventory/llsettingssky.h @@ -0,0 +1,455 @@ +/** +* @file llsettingssky.h +* @author optional +* @brief A base class for asset based settings groups. +* +* $LicenseInfo:2011&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2017, 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$ +*/ + +#ifndef LL_SETTINGS_SKY_H +#define LL_SETTINGS_SKY_H + +#include "llsettingsbase.h" +#include "v4coloru.h" + +class LLSettingsSky: public LLSettingsBase +{ +public: + static const std::string SETTING_AMBIENT; + static const std::string SETTING_BLOOM_TEXTUREID; + static const std::string SETTING_BLUE_DENSITY; + static const std::string SETTING_BLUE_HORIZON; + static const std::string SETTING_CLOUD_COLOR; + static const std::string SETTING_CLOUD_POS_DENSITY1; + static const std::string SETTING_CLOUD_POS_DENSITY2; + static const std::string SETTING_CLOUD_SCALE; + static const std::string SETTING_CLOUD_SCROLL_RATE; + static const std::string SETTING_CLOUD_SHADOW; + static const std::string SETTING_CLOUD_TEXTUREID; + static const std::string SETTING_DENSITY_MULTIPLIER; + static const std::string SETTING_DISTANCE_MULTIPLIER; + static const std::string SETTING_DOME_OFFSET; + static const std::string SETTING_DOME_RADIUS; + static const std::string SETTING_GAMMA; + static const std::string SETTING_GLOW; + static const std::string SETTING_HAZE_DENSITY; + static const std::string SETTING_HAZE_HORIZON; + static const std::string SETTING_LIGHT_NORMAL; + static const std::string SETTING_MAX_Y; + static const std::string SETTING_MOON_ROTATION; + static const std::string SETTING_MOON_TEXTUREID; + static const std::string SETTING_STAR_BRIGHTNESS; + static const std::string SETTING_SUNLIGHT_COLOR; + static const std::string SETTING_SUN_ROTATION; + static const std::string SETTING_SUN_TEXUTUREID; + + typedef boost::shared_ptr ptr_t; + typedef std::pair azimalt_t; + + //--------------------------------------------------------------------- + LLSettingsSky(const LLSD &data); + virtual ~LLSettingsSky() { }; + + virtual ptr_t buildClone() = 0; + + //--------------------------------------------------------------------- + virtual std::string getSettingType() const { return std::string("sky"); } + + // Settings status + virtual void blend(const LLSettingsBase::ptr_t &end, F32 blendf); + + static LLSD defaults(); + + //--------------------------------------------------------------------- + LLColor3 getAmbientColor() const + { + return LLColor3(mSettings[SETTING_AMBIENT]); + } + + void setAmbientColor(const LLColor3 &val) + { + setValue(SETTING_AMBIENT, val); + } + + LLUUID getBloomTextureId() const + { + return mSettings[SETTING_BLOOM_TEXTUREID].asUUID(); + } + + LLColor3 getBlueDensity() const + { + return LLColor3(mSettings[SETTING_BLUE_DENSITY]); + } + + void setBlueDensity(const LLColor3 &val) + { + setValue(SETTING_BLUE_DENSITY, val); + } + + LLColor3 getBlueHorizon() const + { + return LLColor3(mSettings[SETTING_BLUE_HORIZON]); + } + + void setBlueHorizon(const LLColor3 &val) + { + setValue(SETTING_BLUE_HORIZON, val); + } + + LLColor3 getCloudColor() const + { + return LLColor3(mSettings[SETTING_CLOUD_COLOR]); + } + + void setCloudColor(const LLColor3 &val) + { + setValue(SETTING_CLOUD_COLOR, val); + } + + LLUUID getCloudNoiseTextureId() const + { + return mSettings[SETTING_CLOUD_TEXTUREID].asUUID(); + } + + LLColor3 getCloudPosDensity1() const + { + return LLColor3(mSettings[SETTING_CLOUD_POS_DENSITY1]); + } + + void setCloudPosDensity1(const LLColor3 &val) + { + setValue(SETTING_CLOUD_POS_DENSITY1, val); + } + + LLColor3 getCloudPosDensity2() const + { + return LLColor3(mSettings[SETTING_CLOUD_POS_DENSITY2]); + } + + void setCloudPosDensity2(const LLColor3 &val) + { + setValue(SETTING_CLOUD_POS_DENSITY2, val); + } + + F32 getCloudScale() const + { + return mSettings[SETTING_CLOUD_SCALE].asReal(); + } + + void setCloudScale(F32 val) + { + setValue(SETTING_CLOUD_SCALE, val); + } + + LLVector2 getCloudScrollRate() const + { + return LLVector2(mSettings[SETTING_CLOUD_SCROLL_RATE]); + } + + void setCloudScrollRate(const LLVector2 &val) + { + setValue(SETTING_CLOUD_SCROLL_RATE, val); + } + + void setCloudScrollRateX(F32 val) + { + mSettings[SETTING_CLOUD_SCROLL_RATE][0] = val; + setDirtyFlag(true); + } + + void setCloudScrollRateY(F32 val) + { + mSettings[SETTING_CLOUD_SCROLL_RATE][1] = val; + setDirtyFlag(true); + } + + F32 getCloudShadow() const + { + return mSettings[SETTING_CLOUD_SHADOW].asReal(); + } + + void setCloudShadow(F32 val) + { + setValue(SETTING_CLOUD_SHADOW, val); + } + + F32 getDensityMultiplier() const + { + return mSettings[SETTING_DENSITY_MULTIPLIER].asReal(); + } + + void setDensityMultiplier(F32 val) + { + setValue(SETTING_DENSITY_MULTIPLIER, val); + } + + F32 getDistanceMultiplier() const + { + return mSettings[SETTING_DISTANCE_MULTIPLIER].asReal(); + } + + void setDistanceMultiplier(F32 val) + { + setValue(SETTING_DISTANCE_MULTIPLIER, val); + } + + F32 getDomeOffset() const + { + return DOME_OFFSET; + //return mSettings[SETTING_DOME_OFFSET].asReal(); + } + + F32 getDomeRadius() const + { + return DOME_RADIUS; + //return mSettings[SETTING_DOME_RADIUS].asReal(); + } + + F32 getGamma() const + { + return mSettings[SETTING_GAMMA].asReal(); + } + + void setGamma(F32 val) + { + mSettings[SETTING_GAMMA] = LLSD::Real(val); + setDirtyFlag(true); + } + + LLColor3 getGlow() const + { + return LLColor3(mSettings[SETTING_GLOW]); + } + + void setGlow(const LLColor3 &val) + { + setValue(SETTING_GLOW, val); + } + + F32 getHazeDensity() const + { + return mSettings[SETTING_HAZE_DENSITY].asReal(); + } + + void setHazeDensity(F32 val) + { + setValue(SETTING_HAZE_DENSITY, val); + } + + F32 getHazeHorizon() const + { + return mSettings[SETTING_HAZE_HORIZON].asReal(); + } + + void setHazeHorizon(F32 val) + { + setValue(SETTING_HAZE_HORIZON, val); + } + + LLVector3 getLightNormal() const + { + return LLVector3(mSettings[SETTING_LIGHT_NORMAL]); + } + + void setLightNormal(const LLVector3 &val) + { + setValue(SETTING_LIGHT_NORMAL, val); + } + + F32 getMaxY() const + { + return mSettings[SETTING_MAX_Y].asReal(); + } + + LLQuaternion getMoonRotation() const + { + return LLQuaternion(mSettings[SETTING_MOON_ROTATION]); + } + + void setMoonRotation(const LLQuaternion &val) + { + setValue(SETTING_MOON_ROTATION, val); + } + + azimalt_t getMoonRotationAzAl() const; + + void setMoonRotation(F32 azimuth, F32 altitude); + + void setMoonRotation(const azimalt_t &azialt) + { + setMoonRotation(azialt.first, azialt.second); + } + + LLUUID getMoonTextureId() const + { + return mSettings[SETTING_MOON_TEXTUREID].asUUID(); + } + + F32 getStarBrightness() const + { + return mSettings[SETTING_STAR_BRIGHTNESS].asReal(); + } + + void setStarBrightness(F32 val) + { + setValue(SETTING_STAR_BRIGHTNESS, val); + } + + LLColor3 getSunlightColor() const + { + return LLColor3(mSettings[SETTING_SUNLIGHT_COLOR]); + } + + void setSunlightColor(const LLColor3 &val) + { + setValue(SETTING_SUNLIGHT_COLOR, val); + } + + LLQuaternion getSunRotation() const + { + return LLQuaternion(mSettings[SETTING_SUN_ROTATION]); + } + + azimalt_t getSunRotationAzAl() const; + + void setSunRotation(const LLQuaternion &val) + { + setValue(SETTING_SUN_ROTATION, val); + } + + void setSunRotation(F32 azimuth, F32 altitude); + + void setSunRotation(const azimalt_t & azimalt) + { + setSunRotation(azimalt.first, azimalt.second); + } + + LLUUID getSunTextureId() const + { + return mSettings[SETTING_SUN_TEXUTUREID].asUUID(); + } + + // Internal/calculated settings + LLVector3 getLightDirection() const + { + update(); + return mLightDirection; + }; + + LLVector3 getClampedLightDirection() const + { + update(); + return mClampedLightDirection; + }; + + LLVector3 getSunDirection() const + { + update(); + return mSunDirection; + } + + LLVector3 getMoonDirection() const + { + update(); + return mMoonDirection; + } + + LLColor4U getFadeColor() const + { + update(); + return mFadeColor; + } + + LLColor4 getMoonAmbient() const + { + update(); + return mMoonAmbient; + } + + LLColor3 getMoonDiffuse() const + { + update(); + return mMoonDiffuse; + } + + LLColor4 getSunAmbient() const + { + update(); + return mSunAmbient; + } + + LLColor3 getSunDiffuse() const + { + update(); + return mSunDiffuse; + } + + LLColor4 getTotalAmbient() const + { + update(); + return mTotalAmbient; + } + +protected: + LLSettingsSky(); + + virtual stringset_t getSlerpKeys() const; + + virtual validation_list_t getValidationList() const; + + virtual void updateSettings(); + + static LLSD translateLegacySettings(LLSD legacy); + +private: + static const std::string SETTING_LEGACY_EAST_ANGLE; + static const std::string SETTING_LEGACY_ENABLE_CLOUD_SCROLL; + static const std::string SETTING_LEGACY_SUN_ANGLE; + + static const F32 NIGHTTIME_ELEVATION; + static const F32 NIGHTTIME_ELEVATION_COS; + + void calculateHeavnlyBodyPositions(); + void calculateLightSettings(); + + LLVector3 mSunDirection; + LLVector3 mMoonDirection; + LLVector3 mLightDirection; + LLVector3 mClampedLightDirection; + + static const F32 DOME_RADIUS; + static const F32 DOME_OFFSET; + + LLColor4U mFadeColor; + LLColor4 mMoonAmbient; + LLColor3 mMoonDiffuse; + LLColor4 mSunAmbient; + LLColor3 mSunDiffuse; + + LLColor4 mTotalAmbient; + + typedef std::map mapNameToUniformId_t; + + static mapNameToUniformId_t sNameToUniformMapping; +}; + +#endif diff --git a/indra/llinventory/llsettingswater.cpp b/indra/llinventory/llsettingswater.cpp new file mode 100644 index 0000000000..1b960746d5 --- /dev/null +++ b/indra/llinventory/llsettingswater.cpp @@ -0,0 +1,215 @@ +/** +* @file llsettingswater.h +* @author optional +* @brief A base class for asset based settings groups. +* +* $LicenseInfo:2011&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2017, 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 "llsettingswater.h" +#include +#include +#include "lltrace.h" +#include "llfasttimer.h" +#include "v3colorutil.h" +#include "indra_constants.h" + +//========================================================================= +namespace +{ + LLTrace::BlockTimerStatHandle FTM_BLEND_WATERVALUES("Blending Water Environment"); + LLTrace::BlockTimerStatHandle FTM_UPDATE_WATERVALUES("Update Water Environment"); +} + +//========================================================================= +const std::string LLSettingsWater::SETTING_BLUR_MULTIPILER("blur_multiplier"); +const std::string LLSettingsWater::SETTING_FOG_COLOR("water_fog_color"); +const std::string LLSettingsWater::SETTING_FOG_DENSITY("water_fog_density"); +const std::string LLSettingsWater::SETTING_FOG_MOD("underwater_fog_mod"); +const std::string LLSettingsWater::SETTING_FRESNEL_OFFSET("fresnel_offset"); +const std::string LLSettingsWater::SETTING_FRESNEL_SCALE("fresnel_scale"); +const std::string LLSettingsWater::SETTING_NORMAL_MAP("normal_map"); +const std::string LLSettingsWater::SETTING_NORMAL_SCALE("normal_scale"); +const std::string LLSettingsWater::SETTING_SCALE_ABOVE("scale_above"); +const std::string LLSettingsWater::SETTING_SCALE_BELOW("scale_below"); +const std::string LLSettingsWater::SETTING_WAVE1_DIR("wave1_direction"); +const std::string LLSettingsWater::SETTING_WAVE2_DIR("wave2_direction"); + +const std::string LLSettingsWater::SETTING_LEGACY_BLUR_MULTIPILER("blurMultiplier"); +const std::string LLSettingsWater::SETTING_LEGACY_FOG_COLOR("waterFogColor"); +const std::string LLSettingsWater::SETTING_LEGACY_FOG_DENSITY("waterFogDensity"); +const std::string LLSettingsWater::SETTING_LEGACY_FOG_MOD("underWaterFogMod"); +const std::string LLSettingsWater::SETTING_LEGACY_FRESNEL_OFFSET("fresnelOffset"); +const std::string LLSettingsWater::SETTING_LEGACY_FRESNEL_SCALE("fresnelScale"); +const std::string LLSettingsWater::SETTING_LEGACY_NORMAL_MAP("normalMap"); +const std::string LLSettingsWater::SETTING_LEGACY_NORMAL_SCALE("normScale"); +const std::string LLSettingsWater::SETTING_LEGACY_SCALE_ABOVE("scaleAbove"); +const std::string LLSettingsWater::SETTING_LEGACY_SCALE_BELOW("scaleBelow"); +const std::string LLSettingsWater::SETTING_LEGACY_WAVE1_DIR("wave1Dir"); +const std::string LLSettingsWater::SETTING_LEGACY_WAVE2_DIR("wave2Dir"); + +const LLUUID LLSettingsWater::DEFAULT_WATER_NORMAL_ID(DEFAULT_WATER_NORMAL); + + +//========================================================================= +LLSettingsWater::LLSettingsWater(const LLSD &data) : + LLSettingsBase(data) +{ +} + +LLSettingsWater::LLSettingsWater() : + LLSettingsBase() +{ +} + +//========================================================================= +LLSD LLSettingsWater::defaults() +{ + LLSD dfltsetting; + + // Magic constants copied form defaults.xml + dfltsetting[SETTING_BLUR_MULTIPILER] = LLSD::Real(0.04000f); + dfltsetting[SETTING_FOG_COLOR] = LLColor3(0.0156f, 0.1490f, 0.2509f).getValue(); + dfltsetting[SETTING_FOG_DENSITY] = LLSD::Real(2.0f); + dfltsetting[SETTING_FOG_MOD] = LLSD::Real(0.25f); + dfltsetting[SETTING_FRESNEL_OFFSET] = LLSD::Real(0.5f); + dfltsetting[SETTING_FRESNEL_SCALE] = LLSD::Real(0.3999); + dfltsetting[SETTING_NORMAL_MAP] = LLSD::UUID(DEFAULT_WATER_NORMAL_ID); + dfltsetting[SETTING_NORMAL_SCALE] = LLVector3(2.0f, 2.0f, 2.0f).getValue(); + dfltsetting[SETTING_SCALE_ABOVE] = LLSD::Real(0.0299f); + dfltsetting[SETTING_SCALE_BELOW] = LLSD::Real(0.2000f); + dfltsetting[SETTING_WAVE1_DIR] = LLVector2(1.04999f, -0.42000f).getValue(); + dfltsetting[SETTING_WAVE2_DIR] = LLVector2(1.10999f, -1.16000f).getValue(); + + return dfltsetting; +} + +LLSD LLSettingsWater::translateLegacySettings(LLSD legacy) +{ + LLSD newsettings(defaults()); + + if (legacy.has(SETTING_LEGACY_BLUR_MULTIPILER)) + { + newsettings[SETTING_BLUR_MULTIPILER] = LLSD::Real(legacy[SETTING_LEGACY_BLUR_MULTIPILER].asReal()); + } + if (legacy.has(SETTING_LEGACY_FOG_COLOR)) + { + newsettings[SETTING_FOG_COLOR] = LLColor3(legacy[SETTING_LEGACY_FOG_COLOR]).getValue(); + } + if (legacy.has(SETTING_LEGACY_FOG_DENSITY)) + { + newsettings[SETTING_FOG_DENSITY] = LLSD::Real(legacy[SETTING_LEGACY_FOG_DENSITY]); + } + if (legacy.has(SETTING_LEGACY_FOG_MOD)) + { + newsettings[SETTING_FOG_MOD] = LLSD::Real(legacy[SETTING_LEGACY_FOG_MOD].asReal()); + } + if (legacy.has(SETTING_LEGACY_FRESNEL_OFFSET)) + { + newsettings[SETTING_FRESNEL_OFFSET] = LLSD::Real(legacy[SETTING_LEGACY_FRESNEL_OFFSET].asReal()); + } + if (legacy.has(SETTING_LEGACY_FRESNEL_SCALE)) + { + newsettings[SETTING_FRESNEL_SCALE] = LLSD::Real(legacy[SETTING_LEGACY_FRESNEL_SCALE].asReal()); + } + if (legacy.has(SETTING_LEGACY_NORMAL_MAP)) + { + newsettings[SETTING_NORMAL_MAP] = LLSD::UUID(legacy[SETTING_LEGACY_NORMAL_MAP].asUUID()); + } + if (legacy.has(SETTING_LEGACY_NORMAL_SCALE)) + { + newsettings[SETTING_NORMAL_SCALE] = LLVector3(legacy[SETTING_LEGACY_NORMAL_SCALE]).getValue(); + } + if (legacy.has(SETTING_LEGACY_SCALE_ABOVE)) + { + newsettings[SETTING_SCALE_ABOVE] = LLSD::Real(legacy[SETTING_LEGACY_SCALE_ABOVE].asReal()); + } + if (legacy.has(SETTING_LEGACY_SCALE_BELOW)) + { + newsettings[SETTING_SCALE_BELOW] = LLSD::Real(legacy[SETTING_LEGACY_SCALE_BELOW].asReal()); + } + if (legacy.has(SETTING_LEGACY_WAVE1_DIR)) + { + newsettings[SETTING_WAVE1_DIR] = LLVector2(legacy[SETTING_LEGACY_WAVE1_DIR]).getValue(); + } + if (legacy.has(SETTING_LEGACY_WAVE2_DIR)) + { + newsettings[SETTING_WAVE2_DIR] = LLVector2(legacy[SETTING_LEGACY_WAVE2_DIR]).getValue(); + } + + return newsettings; +} + +void LLSettingsWater::blend(const LLSettingsBase::ptr_t &end, F32 blendf) +{ + LLSettingsWater::ptr_t other = boost::static_pointer_cast(end); + LLSD blenddata = interpolateSDMap(mSettings, other->mSettings, blendf); + + replaceSettings(blenddata); +} + +LLSettingsWater::validation_list_t LLSettingsWater::getValidationList() const +{ + static validation_list_t validation; + + if (validation.empty()) + { // Note the use of LLSD(LLSDArray()()()...) This is due to an issue with the + // copy constructor for LLSDArray. Directly binding the LLSDArray as + // a parameter without first wrapping it in a pure LLSD object will result + // in deeply nested arrays like this [[[[[[[[[[v1,v2,v3]]]]]]]]]] + + validation.push_back(Validator(SETTING_BLUR_MULTIPILER, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(0.16f))))); + validation.push_back(Validator(SETTING_FOG_COLOR, true, LLSD::TypeArray, + boost::bind(&Validator::verifyVectorMinMax, _1, + LLSD(LLSDArray(0.0f)(0.0f)(0.0f)(1.0f)), + LLSD(LLSDArray(1.0f)(1.0f)(1.0f)(1.0f))))); + validation.push_back(Validator(SETTING_FOG_DENSITY, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(1.0f)(1024.0f))))); + validation.push_back(Validator(SETTING_FOG_MOD, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(1.0f)(1024.0f))))); + validation.push_back(Validator(SETTING_FRESNEL_OFFSET, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f))))); + validation.push_back(Validator(SETTING_FRESNEL_SCALE, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f))))); + validation.push_back(Validator(SETTING_NORMAL_MAP, true, LLSD::TypeUUID)); + validation.push_back(Validator(SETTING_NORMAL_SCALE, true, LLSD::TypeArray, + boost::bind(&Validator::verifyVectorMinMax, _1, + LLSD(LLSDArray(0.0f)(0.0f)(0.0f)), + LLSD(LLSDArray(10.0f)(10.0f)(10.0f))))); + validation.push_back(Validator(SETTING_SCALE_ABOVE, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f))))); + validation.push_back(Validator(SETTING_SCALE_BELOW, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f))))); + validation.push_back(Validator(SETTING_WAVE1_DIR, true, LLSD::TypeArray, + boost::bind(&Validator::verifyVectorMinMax, _1, + LLSD(LLSDArray(-4.0f)(-4.0f)), + LLSD(LLSDArray(4.0f)(4.0f))))); + validation.push_back(Validator(SETTING_WAVE2_DIR, true, LLSD::TypeArray, + boost::bind(&Validator::verifyVectorMinMax, _1, + LLSD(LLSDArray(-4.0f)(-4.0f)), + LLSD(LLSDArray(4.0f)(4.0f))))); + } + + return validation; +} + diff --git a/indra/llinventory/llsettingswater.h b/indra/llinventory/llsettingswater.h new file mode 100644 index 0000000000..5d6a482d56 --- /dev/null +++ b/indra/llinventory/llsettingswater.h @@ -0,0 +1,227 @@ +/** +* @file llsettingssky.h +* @author optional +* @brief A base class for asset based settings groups. +* +* $LicenseInfo:2011&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2017, 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$ +*/ + +#ifndef LL_SETTINGS_WATER_H +#define LL_SETTINGS_WATER_H + +#include "llsettingsbase.h" + +class LLSettingsWater : public LLSettingsBase +{ +public: + static const std::string SETTING_BLUR_MULTIPILER; + static const std::string SETTING_FOG_COLOR; + static const std::string SETTING_FOG_DENSITY; + static const std::string SETTING_FOG_MOD; + static const std::string SETTING_FRESNEL_OFFSET; + static const std::string SETTING_FRESNEL_SCALE; + static const std::string SETTING_NORMAL_MAP; + static const std::string SETTING_NORMAL_SCALE; + static const std::string SETTING_SCALE_ABOVE; + static const std::string SETTING_SCALE_BELOW; + static const std::string SETTING_WAVE1_DIR; + static const std::string SETTING_WAVE2_DIR; + + static const LLUUID DEFAULT_WATER_NORMAL_ID; + + typedef boost::shared_ptr ptr_t; + + //--------------------------------------------------------------------- + LLSettingsWater(const LLSD &data); + virtual ~LLSettingsWater() { }; + + virtual ptr_t buildClone() = 0; + + //--------------------------------------------------------------------- + virtual std::string getSettingType() const { return std::string("water"); } + + // Settings status + virtual void blend(const LLSettingsBase::ptr_t &end, F32 blendf); + + static LLSD defaults(); + + //--------------------------------------------------------------------- + F32 getBlurMultiplier() const + { + return mSettings[SETTING_BLUR_MULTIPILER].asReal(); + } + + void setBlurMultiplier(F32 val) + { + setValue(SETTING_BLUR_MULTIPILER, val); + } + + LLColor3 getFogColor() const + { + return LLColor3(mSettings[SETTING_FOG_COLOR]); + } + + void setFogColor(LLColor3 val) + { + setValue(SETTING_FOG_COLOR, val); + } + + F32 getFogDensity() const + { + return mSettings[SETTING_FOG_DENSITY].asReal(); + } + + void setFogDensity(F32 val) + { + setValue(SETTING_FOG_DENSITY, val); + } + + F32 getFogMod() const + { + return mSettings[SETTING_FOG_MOD].asReal(); + } + + void setFogMod(F32 val) + { + setValue(SETTING_FOG_MOD, val); + } + + F32 getFresnelOffset() const + { + return mSettings[SETTING_FRESNEL_OFFSET].asReal(); + } + + void setFresnelOffset(F32 val) + { + setValue(SETTING_FRESNEL_OFFSET, val); + } + + F32 getFresnelScale() const + { + return mSettings[SETTING_FRESNEL_SCALE].asReal(); + } + + void setFresnelScale(F32 val) + { + setValue(SETTING_FRESNEL_SCALE, val); + } + + LLUUID getNormalMapID() const + { + return mSettings[SETTING_NORMAL_MAP].asUUID(); + } + + void setNormalMapID(LLUUID val) + { + setValue(SETTING_NORMAL_MAP, val); + } + + LLVector3 getNormalScale() const + { + return LLVector3(mSettings[SETTING_NORMAL_SCALE]); + } + + void setNormalScale(LLVector3 val) + { + setValue(SETTING_NORMAL_SCALE, val); + } + + F32 getScaleAbove() const + { + return mSettings[SETTING_SCALE_ABOVE].asReal(); + } + + void setScaleAbove(F32 val) + { + setValue(SETTING_SCALE_ABOVE, val); + } + + F32 getScaleBelow() const + { + return mSettings[SETTING_SCALE_BELOW].asReal(); + } + + void setScaleBelow(F32 val) + { + setValue(SETTING_SCALE_BELOW, val); + } + + LLVector2 getWave1Dir() const + { + return LLVector2(mSettings[SETTING_WAVE1_DIR]); + } + + void setWave1Dir(LLVector2 val) + { + setValue(SETTING_WAVE1_DIR, val); + } + + LLVector2 getWave2Dir() const + { + return LLVector2(mSettings[SETTING_WAVE2_DIR]); + } + + void setWave2Dir(LLVector2 val) + { + setValue(SETTING_WAVE2_DIR, val); + } + + //------------------------------------------- + LLVector4 getWaterPlane() const + { + update(); + return mWaterPlane; + } + + F32 getWaterFogKS() const + { + update(); + return mWaterFogKS; + } + +protected: + LLSettingsWater(); + + virtual validation_list_t getValidationList() const; + + static LLSD translateLegacySettings(LLSD legacy); + + LLVector4 mWaterPlane; + F32 mWaterFogKS; + +private: + static const std::string SETTING_LEGACY_BLUR_MULTIPILER; + static const std::string SETTING_LEGACY_FOG_COLOR; + static const std::string SETTING_LEGACY_FOG_DENSITY; + static const std::string SETTING_LEGACY_FOG_MOD; + static const std::string SETTING_LEGACY_FRESNEL_OFFSET; + static const std::string SETTING_LEGACY_FRESNEL_SCALE; + static const std::string SETTING_LEGACY_NORMAL_MAP; + static const std::string SETTING_LEGACY_NORMAL_SCALE; + static const std::string SETTING_LEGACY_SCALE_ABOVE; + static const std::string SETTING_LEGACY_SCALE_BELOW; + static const std::string SETTING_LEGACY_WAVE1_DIR; + static const std::string SETTING_LEGACY_WAVE2_DIR; + +}; + +#endif diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index bbe32866f6..4579ef14e2 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -532,10 +532,7 @@ set(viewer_SOURCE_FILES llsecapi.cpp llsechandler_basic.cpp llselectmgr.cpp - llsettingsbase.cpp - llsettingsdaycycle.cpp - llsettingssky.cpp - llsettingswater.cpp + llsettingsvo.cpp llshareavatarhandler.cpp llsidepanelappearance.cpp llsidepanelinventory.cpp @@ -1141,10 +1138,7 @@ set(viewer_HEADER_FILES llsecapi.h llsechandler_basic.h llselectmgr.h - llsettingsbase.h - llsettingsdaycycle.h - llsettingssky.h - llsettingswater.h + llsettingsvo.h llsidepanelappearance.h llsidepanelinventory.h llsidepanelinventorysubpanel.h diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index 8b879710da..e8c9db045c 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -44,6 +44,8 @@ #include "llsdserialize.h" #include "lldiriterator.h" +#include "llsettingsvo.h" + #include //========================================================================= namespace @@ -82,15 +84,15 @@ LLEnvironment::LLEnvironment(): void LLEnvironment::initSingleton() { - LLSettingsSky::ptr_t p_default_sky = LLSettingsSky::buildDefaultSky(); + LLSettingsSky::ptr_t p_default_sky = LLSettingsVOSky::buildDefaultSky(); addSky(p_default_sky); mCurrentSky = p_default_sky; - LLSettingsWater::ptr_t p_default_water = LLSettingsWater::buildDefaultWater(); + LLSettingsWater::ptr_t p_default_water = LLSettingsVOWater::buildDefaultWater(); addWater(p_default_water); mCurrentWater = p_default_water; - LLSettingsDay::ptr_t p_default_day = LLSettingsDay::buildDefaultDayCycle(); + LLSettingsDay::ptr_t p_default_day = LLSettingsVODay::buildDefaultDayCycle(); addDayCycle(p_default_day); mCurrentDay.reset(); @@ -155,7 +157,7 @@ void LLEnvironment::onLegacyRegionSettings(LLSD data) if (data[1].isUndefined()) regionday = LLEnvironment::findDayCycleByName("Default"); else - regionday = LLSettingsDay::buildFromLegacyMessage(regionId, data[1], data[2], data[3]); + regionday = LLSettingsVODay::buildFromLegacyMessage(regionId, data[1], data[2], data[3]); setSkyFor(ENV_REGION, LLSettingsSky::ptr_t()); setWaterFor(ENV_REGION, LLSettingsWater::ptr_t()); @@ -826,7 +828,7 @@ void LLEnvironment::legacyLoadAllPresets() { std::string name(gDirUtilp->getBaseFileName(LLURI::unescape(path), true)); - LLSettingsSky::ptr_t sky = LLSettingsSky::buildFromLegacyPreset(name, data); + LLSettingsSky::ptr_t sky = LLSettingsVOSky::buildFromLegacyPreset(name, data); LLEnvironment::instance().addSky(sky); } } @@ -845,7 +847,7 @@ void LLEnvironment::legacyLoadAllPresets() { std::string name(gDirUtilp->getBaseFileName(LLURI::unescape(path), true)); - LLSettingsSky::ptr_t sky = LLSettingsSky::buildFromLegacyPreset(name, data); + LLSettingsSky::ptr_t sky = LLSettingsVOSky::buildFromLegacyPreset(name, data); LLEnvironment::instance().addSky(sky); } } @@ -864,7 +866,7 @@ void LLEnvironment::legacyLoadAllPresets() { std::string name(gDirUtilp->getBaseFileName(LLURI::unescape(path), true)); - LLSettingsWater::ptr_t water = LLSettingsWater::buildFromLegacyPreset(name, data); + LLSettingsWater::ptr_t water = LLSettingsVOWater::buildFromLegacyPreset(name, data); LLEnvironment::instance().addWater(water); } } @@ -883,7 +885,7 @@ void LLEnvironment::legacyLoadAllPresets() { std::string name(gDirUtilp->getBaseFileName(LLURI::unescape(path), true)); - LLSettingsWater::ptr_t water = LLSettingsWater::buildFromLegacyPreset(name, data); + LLSettingsWater::ptr_t water = LLSettingsVOWater::buildFromLegacyPreset(name, data); LLEnvironment::instance().addWater(water); } } @@ -902,7 +904,7 @@ void LLEnvironment::legacyLoadAllPresets() { std::string name(gDirUtilp->getBaseFileName(LLURI::unescape(path), true)); - LLSettingsDay::ptr_t day = LLSettingsDay::buildFromLegacyPreset(name, data); + LLSettingsDay::ptr_t day = LLSettingsVODay::buildFromLegacyPreset(name, data); LLEnvironment::instance().addDayCycle(day); } } @@ -921,7 +923,7 @@ void LLEnvironment::legacyLoadAllPresets() { std::string name(gDirUtilp->getBaseFileName(LLURI::unescape(path), true)); - LLSettingsDay::ptr_t day = LLSettingsDay::buildFromLegacyPreset(name, data); + LLSettingsDay::ptr_t day = LLSettingsVODay::buildFromLegacyPreset(name, data); LLEnvironment::instance().addDayCycle(day); } } diff --git a/indra/newview/llenvironment.h b/indra/newview/llenvironment.h index ce8c08f692..4d3d1f6a57 100644 --- a/indra/newview/llenvironment.h +++ b/indra/newview/llenvironment.h @@ -27,6 +27,7 @@ #ifndef LL_ENVIRONMENT_H #define LL_ENVIRONMENT_H +#include "llsingleton.h" #include "llmemory.h" #include "llsd.h" @@ -35,6 +36,8 @@ #include "llsettingswater.h" #include "llsettingsdaycycle.h" +#include + //------------------------------------------------------------------------- class LLViewerCamera; class LLGLSLShader; diff --git a/indra/newview/llsettingsbase.cpp b/indra/newview/llsettingsbase.cpp deleted file mode 100644 index e36c6d4a84..0000000000 --- a/indra/newview/llsettingsbase.cpp +++ /dev/null @@ -1,617 +0,0 @@ -/** -* @file llsettingsbase.cpp -* @author optional -* @brief A base class for asset based settings groups. -* -* $LicenseInfo:2011&license=viewerlgpl$ -* Second Life Viewer Source Code -* Copyright (C) 2017, 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 "llviewerprecompiledheaders.h" -#include "llsettingsbase.h" - -#include "llmath.h" -#include - -#include "llsdserialize.h" - -//========================================================================= -namespace -{ - const F32 BREAK_POINT = 0.5; -} - -//========================================================================= -const std::string LLSettingsBase::SETTING_ID("id"); -const std::string LLSettingsBase::SETTING_NAME("name"); - -const F32Seconds LLSettingsBlender::DEFAULT_THRESHOLD(0.01); - -//========================================================================= -LLSettingsBase::LLSettingsBase(): - mSettings(LLSD::emptyMap()), - mDirty(true), - mHashValue(0) -{ -} - -LLSettingsBase::LLSettingsBase(const LLSD setting) : - mSettings(setting), - mDirty(true), - mHashValue(0) -{ -} - -//========================================================================= -void LLSettingsBase::lerpSettings(const LLSettingsBase &other, F32 mix) -{ - mSettings = interpolateSDMap(mSettings, other.mSettings, mix); - setDirtyFlag(true); -} - -LLSD LLSettingsBase::combineSDMaps(const LLSD &settings, const LLSD &other) const -{ - LLSD newSettings; - - for (LLSD::map_const_iterator it = settings.beginMap(); it != settings.endMap(); ++it) - { - std::string key_name = (*it).first; - LLSD value = (*it).second; - - LLSD::Type setting_type = value.type(); - switch (setting_type) - { - case LLSD::TypeMap: - newSettings[key_name] = combineSDMaps(value, LLSD()); - break; - case LLSD::TypeArray: - newSettings[key_name] = LLSD::emptyArray(); - for (LLSD::array_const_iterator ita = value.beginArray(); ita != value.endArray(); ++ita) - { - newSettings[key_name].append(*ita); - } - break; - //case LLSD::TypeInteger: - //case LLSD::TypeReal: - //case LLSD::TypeBoolean: - //case LLSD::TypeString: - //case LLSD::TypeUUID: - //case LLSD::TypeURI: - //case LLSD::TypeDate: - //case LLSD::TypeBinary: - default: - newSettings[key_name] = value; - break; - } - } - - if (!other.isUndefined()) - { - for (LLSD::map_const_iterator it = other.beginMap(); it != other.endMap(); ++it) - { - std::string key_name = (*it).first; - LLSD value = (*it).second; - - LLSD::Type setting_type = value.type(); - switch (setting_type) - { - case LLSD::TypeMap: - newSettings[key_name] = combineSDMaps(value, LLSD()); - break; - case LLSD::TypeArray: - newSettings[key_name] = LLSD::emptyArray(); - for (LLSD::array_const_iterator ita = value.beginArray(); ita != value.endArray(); ++ita) - { - newSettings[key_name].append(*ita); - } - break; - //case LLSD::TypeInteger: - //case LLSD::TypeReal: - //case LLSD::TypeBoolean: - //case LLSD::TypeString: - //case LLSD::TypeUUID: - //case LLSD::TypeURI: - //case LLSD::TypeDate: - //case LLSD::TypeBinary: - default: - newSettings[key_name] = value; - break; - } - } - } - - return newSettings; -} - -LLSD LLSettingsBase::interpolateSDMap(const LLSD &settings, const LLSD &other, F32 mix) const -{ - LLSD newSettings; - - stringset_t skip = getSkipInterpolateKeys(); - stringset_t slerps = getSlerpKeys(); - - for (LLSD::map_const_iterator it = settings.beginMap(); it != settings.endMap(); ++it) - { - std::string key_name = (*it).first; - LLSD value = (*it).second; - - 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; - } - - switch (setting_type) - { - 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: - { - LLSD newvalue(LLSD::emptyArray()); - - if (slerps.find(key_name) != slerps.end()) - { - LLQuaternion q = slerp(mix, LLQuaternion(value), LLQuaternion(other_value)); - 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; - } - - break; - -// case LLSD::TypeBoolean: -// case LLSD::TypeString: -// case LLSD::TypeUUID: -// case LLSD::TypeURI: -// case LLSD::TypeBinary: -// case LLSD::TypeDate: - default: - /* TODO: If the UUID points to an image ID, blend the images. */ - // 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; - } - } - - // Now add anything that is in other but not in the settings - 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; - - if (!settings.has((*it).first)) - continue; - - newSettings[(*it).first] = (*it).second; - } - - return newSettings; -} - -LLSD LLSettingsBase::cloneSettings() const -{ - return combineSDMaps(mSettings, LLSD()); -} - -void LLSettingsBase::exportSettings(std::string name) const -{ - LLSD exprt = LLSDMap("type", LLSD::String(getSettingType())) - ("name", LLSD::String(name)) - ("settings", mSettings); - - std::string path_name = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, name + ".settings"); - - // write to file - llofstream presetsXML(path_name.c_str()); - if (presetsXML.is_open()) - { - LLPointer formatter = new LLSDXMLFormatter(); - formatter->format(exprt, presetsXML, LLSDFormatter::OPTIONS_PRETTY); - presetsXML.close(); - - LL_DEBUGS() << "saved preset '" << name << "'; " << mSettings.size() << " settings" << LL_ENDL; - } - else - { - LL_WARNS("Presets") << "Cannot open for output preset file " << path_name << LL_ENDL; - } -} - -#ifdef VALIDATION_DEBUG -namespace -{ - LLSD clone_llsd(LLSD value) - { - LLSD clone; - - switch (value.type()) - { -// case LLSD::TypeMap: -// newSettings[key_name] = combineSDMaps(value, LLSD()); -// break; - case LLSD::TypeArray: - clone = LLSD::emptyArray(); - for (LLSD::array_const_iterator ita = value.beginArray(); ita != value.endArray(); ++ita) - { - clone.append( clone_llsd(*ita) ); - } - break; - case LLSD::TypeInteger: - clone = LLSD::Integer(value.asInteger()); - break; - case LLSD::TypeReal: - clone = LLSD::Real(value.asReal()); - break; - case LLSD::TypeBoolean: - clone = LLSD::Boolean(value.asBoolean()); - break; - case LLSD::TypeString: - clone = LLSD::String(value.asString()); - break; - case LLSD::TypeUUID: - clone = LLSD::UUID(value.asUUID()); - break; - case LLSD::TypeURI: - clone = LLSD::URI(value.asURI()); - break; - case LLSD::TypeDate: - clone = LLSD::Date(value.asDate()); - break; - //case LLSD::TypeBinary: - // break; - //default: - // newSettings[key_name] = value; - // break; - } - - return clone; - } - - bool compare_llsd(LLSD valA, LLSD valB) - { - if (valA.type() != valB.type()) - return false; - - switch (valA.type()) - { - // case LLSD::TypeMap: - // newSettings[key_name] = combineSDMaps(value, LLSD()); - // break; - case LLSD::TypeArray: - if (valA.size() != valB.size()) - return false; - - for (S32 idx = 0; idx < valA.size(); ++idx) - { - if (!compare_llsd(valA[idx], valB[idx])) - return false; - } - return true; - - case LLSD::TypeInteger: - return valA.asInteger() == valB.asInteger(); - - case LLSD::TypeReal: - return is_approx_equal(valA.asReal(), valB.asReal()); - - case LLSD::TypeBoolean: - return valA.asBoolean() == valB.asBoolean(); - - case LLSD::TypeString: - return valA.asString() == valB.asString(); - - case LLSD::TypeUUID: - return valA.asUUID() == valB.asUUID(); - - case LLSD::TypeURI: - return valA.asString() == valB.asString(); - - case LLSD::TypeDate: - return valA.asDate() == valB.asDate(); - } - - return true; - } -} -#endif - -bool LLSettingsBase::validate() -{ - static Validator validateName(SETTING_NAME, false, LLSD::TypeString); - static Validator validateId(SETTING_ID, false, LLSD::TypeUUID); - validation_list_t validations = getValidationList(); - stringset_t validated; - stringset_t strip; - - // Fields common to all settings. - if (!validateName.verify(mSettings)) - { - LL_WARNS("SETTINGS") << "Unable to validate name." << LL_ENDL; - mIsValid = false; - return false; - } - validated.insert(validateName.getName()); - - if (!validateId.verify(mSettings)) - { - LL_WARNS("SETTINGS") << "Unable to validate Id." << LL_ENDL; - mIsValid = false; - return false; - } - validated.insert(validateId.getName()); - - // Fields for specific settings. - for (validation_list_t::iterator itv = validations.begin(); itv != validations.end(); ++itv) - { -#ifdef VALIDATION_DEBUG - LLSD oldvalue; - if (mSettings.has((*itv).getName())) - { - oldvalue = clone_llsd(mSettings[(*itv).getName()]); - } -#endif - - if (!(*itv).verify(mSettings)) - { - LL_WARNS("SETTINGS") << "Settings LLSD fails validation and could not be corrected!" << LL_ENDL; - mIsValid = false; - return false; - } - validated.insert((*itv).getName()); - -#ifdef VALIDATION_DEBUG - if (!oldvalue.isUndefined()) - { - if (!compare_llsd(mSettings[(*itv).getName()], oldvalue)) - { - LL_WARNS("SETTINGS") << "Setting '" << (*itv).getName() << "' was changed: " << oldvalue << " -> " << mSettings[(*itv).getName()] << LL_ENDL; - } - } -#endif - } - - // strip extra entries - for (LLSD::map_iterator itm = mSettings.beginMap(); itm != mSettings.endMap(); ++itm) - { - if (validated.find((*itm).first) == validated.end()) - { - LL_WARNS("SETTINGS") << "Stripping setting '" << (*itm).first << "'" << LL_ENDL; - strip.insert((*itm).first); - } - } - - for (stringset_t::iterator its = strip.begin(); its != strip.end(); ++its) - { - mSettings.erase(*its); - } - - return true; -} - -//========================================================================= -bool LLSettingsBase::Validator::verify(LLSD &data) -{ - if (!data.has(mName)) - { - if (mRequired) - LL_WARNS("SETTINGS") << "Missing required setting '" << mName << "'" << LL_ENDL; - return !mRequired; - } - - if (data[mName].type() != mType) - { - LL_WARNS("SETTINGS") << "Setting '" << mName << "' is incorrect type." << LL_ENDL; - return false; - } - - if (!mVerify.empty() && !mVerify(data[mName])) - { - LL_WARNS("SETTINGS") << "Setting '" << mName << "' fails validation." << LL_ENDL; - return false; - } - - return true; -} - -bool LLSettingsBase::Validator::verifyColor(LLSD &value) -{ - return (value.size() == 3 || value.size() == 4); -} - -bool LLSettingsBase::Validator::verifyVector(LLSD &value, S32 length) -{ - return (value.size() == length); -} - -bool LLSettingsBase::Validator::verifyVectorNormalized(LLSD &value, S32 length) -{ - if (value.size() != length) - return false; - - LLSD newvector; - - switch (length) - { - case 2: - { - LLVector2 vect(value); - - if (is_approx_equal(vect.normalize(), 1.0f)) - return true; - newvector = vect.getValue(); - break; - } - case 3: - { - LLVector3 vect(value); - - if (is_approx_equal(vect.normalize(), 1.0f)) - return true; - newvector = vect.getValue(); - break; - } - case 4: - { - LLVector4 vect(value); - - if (is_approx_equal(vect.normalize(), 1.0f)) - return true; - newvector = vect.getValue(); - break; - } - default: - return false; - } - - return true; -} - -bool LLSettingsBase::Validator::verifyVectorMinMax(LLSD &value, LLSD minvals, LLSD maxvals) -{ - for (S32 index = 0; index < value.size(); ++index) - { - if (minvals[index].asString() != "*") - { - if (minvals[index].asReal() > value[index].asReal()) - { - value[index] = minvals[index].asReal(); - } - } - if (maxvals[index].asString() != "*") - { - if (maxvals[index].asReal() < value[index].asReal()) - { - value[index] = maxvals[index].asReal(); - } - } - } - - return true; -} - -bool LLSettingsBase::Validator::verifyQuaternion(LLSD &value) -{ - return (value.size() == 4); -} - -bool LLSettingsBase::Validator::verifyQuaternionNormal(LLSD &value) -{ - if (value.size() != 4) - return false; - - LLQuaternion quat(value); - - if (is_approx_equal(quat.normalize(), 1.0f)) - return true; - - LLSD newquat = quat.getValue(); - for (S32 index = 0; index < 4; ++index) - { - value[index] = newquat[index]; - } - return true; -} - -bool LLSettingsBase::Validator::verifyFloatRange(LLSD &value, LLSD range) -{ - F32 real = value.asReal(); - - F32 clampedval = llclamp(LLSD::Real(real), range[0].asReal(), range[1].asReal()); - - if (is_approx_equal(clampedval, real)) - return true; - - value = LLSD::Real(clampedval); - return true; -} - -bool LLSettingsBase::Validator::verifyIntegerRange(LLSD &value, LLSD range) -{ - S32 ival = value.asInteger(); - - S32 clampedval = llclamp(LLSD::Integer(ival), range[0].asInteger(), range[1].asInteger()); - - if (clampedval == ival) - return true; - - value = LLSD::Integer(clampedval); - return true; -} - -//========================================================================= - -void LLSettingsBlender::update(F32Seconds timedelta) -{ - mTimeSpent += timedelta; - - if (mTimeSpent >= mSeconds) - { - LLSettingsBlender::ptr_t hold = shared_from_this(); // prevents this from deleting too soon - mOnFinished(shared_from_this()); - mOnFinished.disconnect_all_slots(); // prevent from firing more than once. - return; - } - - F32 blendf = fmod(mTimeSpent.value(), mSeconds.value()) / mSeconds.value(); - - mTarget->replaceSettings(mInitial->getSettings()); - mTarget->blend(mFinal, blendf); -} - diff --git a/indra/newview/llsettingsbase.h b/indra/newview/llsettingsbase.h deleted file mode 100644 index d304b8702a..0000000000 --- a/indra/newview/llsettingsbase.h +++ /dev/null @@ -1,312 +0,0 @@ -/** -* @file llsettingsbase.h -* @author optional -* @brief A base class for asset based settings groups. -* -* $LicenseInfo:2011&license=viewerlgpl$ -* Second Life Viewer Source Code -* Copyright (C) 2017, 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$ -*/ - -#ifndef LL_SETTINGS_BASE_H -#define LL_SETTINGS_BASE_H - -#include -#include -#include -#include - -#include "llsd.h" -#include "llsdutil.h" -#include "v2math.h" -#include "v3math.h" -#include "v4math.h" -#include "llquaternion.h" -#include "v4color.h" - -class LLSettingsBase : - public boost::enable_shared_from_this, - private boost::noncopyable -{ - friend class LLEnvironment; - friend class LLSettingsDay; - -public: - static const std::string SETTING_ID; - static const std::string SETTING_NAME; - - typedef std::map parammapping_t; - - typedef boost::shared_ptr ptr_t; - - virtual ~LLSettingsBase() { }; - - //--------------------------------------------------------------------- - virtual std::string getSettingType() const = 0; - - //--------------------------------------------------------------------- - // Settings status - inline bool hasSetting(const std::string ¶m) const { return mSettings.has(param); } - inline bool isDirty() const { return mDirty; } - inline void setDirtyFlag(bool dirty) { mDirty = dirty; } - - inline size_t getHash() const - { - return boost::hash{}(mSettings); - } - - inline LLUUID getId() const - { - return getValue(SETTING_ID).asUUID(); - } - - inline std::string getName() const - { - return getValue(SETTING_NAME).asString(); - } - - inline void setName(std::string val) - { - setValue(SETTING_NAME, val); - } - - inline void replaceSettings(LLSD settings) - { - mSettings = settings; - setDirtyFlag(true); - } - - inline LLSD getSettings() const - { - return mSettings; - } - - //--------------------------------------------------------------------- - // - inline void setValue(const std::string &name, const LLSD &value) - { - mSettings[name] = value; - mDirty = true; - } - - inline LLSD getValue(const std::string &name, const LLSD &deflt = LLSD()) const - { - if (!mSettings.has(name)) - return deflt; - return mSettings[name]; - } - - inline void setValue(const std::string &name, const LLVector2 &value) - { - setValue(name, value.getValue()); - } - - inline void setValue(const std::string &name, const LLVector3 &value) - { - setValue(name, value.getValue()); - } - - inline void setValue(const std::string &name, const LLVector4 &value) - { - setValue(name, value.getValue()); - } - - inline void setValue(const std::string &name, const LLQuaternion &value) - { - setValue(name, value.getValue()); - } - - inline void setValue(const std::string &name, const LLColor3 &value) - { - setValue(name, value.getValue()); - } - - inline void setValue(const std::string &name, const LLColor4 &value) - { - setValue(name, value.getValue()); - } - - // Note this method is marked const but may modify the settings object. - // (note the internal const cast). This is so that it may be called without - // special consideration from getters. - inline void update() const - { - if (!mDirty) - return; - (const_cast(this))->updateSettings(); - } - - // TODO: This is temporary - virtual void exportSettings(std::string name) const; - - virtual void blend(const ptr_t &end, F32 blendf) = 0; - - virtual bool validate(); - -protected: - class Validator - { - public: - typedef boost::function verify_pr; - - Validator(std::string name, bool required, LLSD::Type type, verify_pr verify = verify_pr()) : - mName(name), - mRequired(required), - mType(type), - mVerify(verify) - { } - - std::string getName() const { return mName; } - bool isRequired() const { return mRequired; } - LLSD::Type getType() const { return mType; } - - bool verify(LLSD &data); - - // Some basic verifications - static bool verifyColor(LLSD &value); - static bool verifyVector(LLSD &value, S32 length); - static bool verifyVectorMinMax(LLSD &value, LLSD minvals, LLSD maxvals); - static bool verifyVectorNormalized(LLSD &value, S32 length); - static bool verifyQuaternion(LLSD &value); - static bool verifyQuaternionNormal(LLSD &value); - static bool verifyFloatRange(LLSD &value, LLSD range); - static bool verifyIntegerRange(LLSD &value, LLSD range); - - private: - std::string mName; - bool mRequired; - LLSD::Type mType; - verify_pr mVerify; - }; - typedef std::vector validation_list_t; - - LLSettingsBase(); - LLSettingsBase(const LLSD setting); - - typedef std::set stringset_t; - - // combining settings objects. Customize for specific setting types - virtual void lerpSettings(const LLSettingsBase &other, F32 mix); - LLSD interpolateSDMap(const LLSD &settings, const LLSD &other, F32 mix) const; - - /// when lerping between settings, some may require special handling. - /// Get a list of these key to be skipped by the default settings lerp. - /// (handling should be performed in the override of lerpSettings. - virtual stringset_t getSkipInterpolateKeys() const { return stringset_t(); } - - // A list of settings that represent quaternions and should be slerped - // rather than lerped. - virtual stringset_t getSlerpKeys() const { return stringset_t(); } - - // Calculate any custom settings that may need to be cached. - virtual void updateSettings() { mDirty = false; }; - - virtual validation_list_t getValidationList() const = 0; - - // Apply any settings that need special handling. - virtual void applySpecial(void *) { }; - - virtual parammapping_t getParameterMap() const { return parammapping_t(); } - - LLSD mSettings; - bool mIsValid; - - LLSD cloneSettings() const; - -private: - bool mDirty; - size_t mHashValue; - - LLSD combineSDMaps(const LLSD &first, const LLSD &other) const; - -}; - - -class LLSettingsBlender : public boost::enable_shared_from_this -{ -public: - typedef boost::shared_ptr ptr_t; - typedef boost::signals2::signal finish_signal_t; - typedef boost::signals2::connection connection_t; - - static const F32Seconds DEFAULT_THRESHOLD; - - LLSettingsBlender(const LLSettingsBase::ptr_t &target, - const LLSettingsBase::ptr_t &initsetting, const LLSettingsBase::ptr_t &endsetting, F32Seconds seconds) : - mTarget(target), - mInitial(initsetting), - mFinal(endsetting), - mSeconds(seconds), - mOnFinished(), - mBlendThreshold(DEFAULT_THRESHOLD), - mLastUpdate(0.0f), - mTimeSpent(0.0f) - { - mTarget->replaceSettings(mInitial->getSettings()); - mTimeStart = F32Seconds(LLDate::now().secondsSinceEpoch()); - mLastUpdate = mTimeStart; - } - - ~LLSettingsBlender() {} - - connection_t setOnFinished(const finish_signal_t::slot_type &onfinished) - { - return mOnFinished.connect(onfinished); - } - - void setUpdateThreshold(F32Seconds threshold) - { - mBlendThreshold = threshold; - } - - F32Seconds getUpdateThreshold() const - { - return mBlendThreshold; - } - - LLSettingsBase::ptr_t getTarget() const - { - return mTarget; - } - - LLSettingsBase::ptr_t getInitial() const - { - return mInitial; - } - - LLSettingsBase::ptr_t getFinal() const - { - return mFinal; - } - - void update(F32Seconds time); -private: - LLSettingsBase::ptr_t mTarget; - LLSettingsBase::ptr_t mInitial; - LLSettingsBase::ptr_t mFinal; - F32Seconds mSeconds; - finish_signal_t mOnFinished; - F32Seconds mBlendThreshold; - F32Seconds mLastUpdate; - F32Seconds mTimeSpent; - F32Seconds mTimeStart; -}; - -#endif diff --git a/indra/newview/llsettingsdaycycle.cpp b/indra/newview/llsettingsdaycycle.cpp deleted file mode 100644 index a579f99182..0000000000 --- a/indra/newview/llsettingsdaycycle.cpp +++ /dev/null @@ -1,613 +0,0 @@ -/** -* @file llsettingsdaycycle.cpp -* @author optional -* @brief A base class for asset based settings groups. -* -* $LicenseInfo:2011&license=viewerlgpl$ -* Second Life Viewer Source Code -* Copyright (C) 2017, 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 "llviewerprecompiledheaders.h" -#include "llviewercontrol.h" -#include "llsettingsdaycycle.h" -#include -#include -#include "lltrace.h" -#include "llfasttimer.h" -#include "v3colorutil.h" - -#include "llglslshader.h" -#include "llviewershadermgr.h" - -#include "llenvironment.h" - -#include "llagent.h" -#include "pipeline.h" - -#include "llsettingssky.h" -#include "llsettingswater.h" - -#include "llenvironment.h" - -#include "llworld.h" - -//========================================================================= -namespace -{ - LLTrace::BlockTimerStatHandle FTM_BLEND_WATERVALUES("Blending Water Environment"); - LLTrace::BlockTimerStatHandle FTM_UPDATE_WATERVALUES("Update Water Environment"); - - inline F32 get_wrapping_distance(F32 begin, F32 end) - { - if (begin < end) - { - return end - begin; - } - else if (begin > end) - { - return 1.0 - (begin - end); - } - - return 0; - } - - LLSettingsDay::CycleTrack_t::iterator get_wrapping_atafter(LLSettingsDay::CycleTrack_t &collection, F32 key) - { - if (collection.empty()) - return collection.end(); - - LLSettingsDay::CycleTrack_t::iterator it = collection.upper_bound(key); - - if (it == collection.end()) - { // wrap around - it = collection.begin(); - } - - return it; - } - - LLSettingsDay::CycleTrack_t::iterator get_wrapping_atbefore(LLSettingsDay::CycleTrack_t &collection, F32 key) - { - if (collection.empty()) - return collection.end(); - - LLSettingsDay::CycleTrack_t::iterator it = collection.lower_bound(key); - - if (it == collection.end()) - { // all keyframes are lower, take the last one. - --it; // we know the range is not empty - } - else if ((*it).first > key) - { // the keyframe we are interested in is smaller than the found. - if (it == collection.begin()) - it = collection.end(); - --it; - } - - return it; - } - - -} - -//========================================================================= -const std::string LLSettingsDay::SETTING_DAYLENGTH("day_length"); -const std::string LLSettingsDay::SETTING_KEYID("key_id"); -const std::string LLSettingsDay::SETTING_KEYNAME("key_name"); -const std::string LLSettingsDay::SETTING_KEYKFRAME("key_keyframe"); -const std::string LLSettingsDay::SETTING_TRACKS("tracks"); - -const S64 LLSettingsDay::MINIMUM_DAYLENGTH( 300); // 5 mins - -//const S64 LLSettingsDay::MINIMUM_DAYLENGTH( 14400); // 4 hours -const S64 LLSettingsDay::MAXIMUM_DAYLENGTH(604800); // 7 days - -const S32 LLSettingsDay::TRACK_WATER(0); // water track is 0 -const S32 LLSettingsDay::TRACK_MAX(5); // 5 tracks, 4 skys, 1 water -const S32 LLSettingsDay::FRAME_MAX(56); - -//========================================================================= -LLSettingsDay::LLSettingsDay(const LLSD &data) : - LLSettingsBase(data), - mHasParsed(false) -{ - mDayTracks.resize(TRACK_MAX); -} - -LLSettingsDay::LLSettingsDay() : - LLSettingsBase(), - mHasParsed(false) -{ - mDayTracks.resize(TRACK_MAX); -} - -//========================================================================= -LLSD LLSettingsDay::defaults() -{ - LLSD dfltsetting; - - dfltsetting[SETTING_NAME] = "_default_"; - dfltsetting[SETTING_DAYLENGTH] = static_cast(MINIMUM_DAYLENGTH); - dfltsetting[SETTING_TRACKS] = LLSDArray( - LLSDArray(LLSDMap(SETTING_KEYKFRAME, LLSD::Real(0.0f))(SETTING_KEYNAME, "_default_")) - (LLSDMap(SETTING_KEYKFRAME, LLSD::Real(0.0f))(SETTING_KEYNAME, "_default_"))); - - return dfltsetting; -} - -LLSettingsDay::ptr_t LLSettingsDay::buildFromLegacyPreset(const std::string &name, const LLSD &oldsettings) -{ - LLSD newsettings(defaults()); - - newsettings[SETTING_NAME] = name; - newsettings[SETTING_DAYLENGTH] = static_cast(MINIMUM_DAYLENGTH); - - LLSD watertrack = LLSDArray( - LLSDMap ( SETTING_KEYKFRAME, LLSD::Real(0.0f) ) - ( SETTING_KEYNAME, "Default" )); - - LLSD skytrack = LLSD::emptyArray(); - - for (LLSD::array_const_iterator it = oldsettings.beginArray(); it != oldsettings.endArray(); ++it) - { - LLSD entry = LLSDMap(SETTING_KEYKFRAME, (*it)[0].asReal()) - (SETTING_KEYNAME, (*it)[1].asString()); - skytrack.append(entry); - } - - newsettings[SETTING_TRACKS] = LLSDArray(watertrack)(skytrack); - - LLSettingsDay::ptr_t dayp = boost::make_shared(newsettings); - dayp->parseFromLLSD(dayp->mSettings); - - if (dayp->validate()) - return dayp; - - return LLSettingsDay::ptr_t(); -} - -LLSettingsDay::ptr_t LLSettingsDay::buildFromLegacyMessage(const LLUUID ®ionId, LLSD daycycle, LLSD skydefs, LLSD waterdef) -{ - LLSettingsWater::ptr_t water = LLSettingsWater::buildFromLegacyPreset("Region", waterdef); - LLEnvironment::namedSettingMap_t skys; - - for (LLSD::map_iterator itm = skydefs.beginMap(); itm != skydefs.endMap(); ++itm) - { - std::string name = (*itm).first; - LLSettingsSky::ptr_t sky = LLSettingsSky::buildFromLegacyPreset(name, (*itm).second); - - skys[name] = sky; - LL_WARNS("WindlightCaps") << "created region sky '" << name << "'" << LL_ENDL; - } - - LLSettingsDay::ptr_t dayp = buildFromLegacyPreset("Region (legacy)", daycycle); - - dayp->setWaterAtKeyframe(water, 0.0f); - - for (LLSD::array_iterator ita = daycycle.beginArray(); ita != daycycle.endArray(); ++ita) - { - F32 frame = (*ita)[0].asReal(); - std::string name = (*ita)[1].asString(); - - LLEnvironment::namedSettingMap_t::iterator it = skys.find(name); - - if (it == skys.end()) - continue; - dayp->setSkyAtKeyframe(boost::static_pointer_cast((*it).second), frame, 1); - - LL_WARNS("WindlightCaps") << "Added '" << name << "' to region day cycle at " << frame << LL_ENDL; - } - - dayp->mHasParsed = true; - - if (dayp->validate()) - return dayp; - - return LLSettingsDay::ptr_t(); -} - -LLSettingsDay::ptr_t LLSettingsDay::buildDefaultDayCycle() -{ - LLSD settings = LLSettingsDay::defaults(); - - LLSettingsDay::ptr_t dayp = boost::make_shared(settings); - dayp->parseFromLLSD(dayp->mSettings); - - if (dayp->validate()) - return dayp; - - return LLSettingsDay::ptr_t(); -} - -void LLSettingsDay::parseFromLLSD(LLSD &data) -{ - LLEnvironment &environment(LLEnvironment::instance()); - LLSD tracks = data[SETTING_TRACKS]; - - for (S32 i = 0; (i < tracks.size()) && (i < TRACK_MAX); ++i) - { - mDayTracks[i].clear(); - LLSD curtrack = tracks[i]; - for (LLSD::array_const_iterator it = curtrack.beginArray(); it != curtrack.endArray(); ++it) - { - F32 keyframe = (*it)[SETTING_KEYKFRAME].asReal(); - keyframe = llclamp(keyframe, 0.0f, 1.0f); - LLSettingsBase::ptr_t setting; - - if ((*it).has(SETTING_KEYNAME)) - { - if (i == TRACK_WATER) - setting = environment.findWaterByName((*it)[SETTING_KEYNAME]); - else - setting = environment.findSkyByName((*it)[SETTING_KEYNAME]); - } - else if ((*it).has(SETTING_KEYID)) - { - - } - - if (setting) - mDayTracks[i][keyframe] = setting; - } - } - mHasParsed = true; -} - - -LLSettingsDay::ptr_t LLSettingsDay::buildClone() -{ - LLSD settings = cloneSettings(); - - LLSettingsDay::ptr_t dayp = boost::make_shared(settings); - - return dayp; -} - -void LLSettingsDay::blend(const LLSettingsBase::ptr_t &other, F32 mix) -{ - LL_ERRS("DAYCYCLE") << "Day cycles are not blendable!" << LL_ENDL; -} - -namespace -{ - bool validateDayCycleTrack(LLSD &value) - { - // Trim extra tracks. - while (value.size() > LLSettingsDay::TRACK_MAX) - { - value.erase(value.size() - 1); - } - - for (LLSD::array_iterator track = value.beginArray(); track != value.endArray(); ++track) - { - S32 index = 0; - while (index < (*track).size()) - { - if (index >= LLSettingsDay::FRAME_MAX) - { - (*track).erase(index); - continue; - } - - if (!(*track)[index].has(LLSettingsDay::SETTING_KEYKFRAME) || - !(*track)[index][LLSettingsDay::SETTING_KEYKFRAME].isReal()) - { - (*track).erase(index); - continue; - } - - if (!(*track)[index].has(LLSettingsDay::SETTING_KEYNAME) && - !(*track)[index].has(LLSettingsDay::SETTING_KEYID)) - { - (*track).erase(index); - continue; - } - - F32 frame = (*track)[index][LLSettingsDay::SETTING_KEYKFRAME].asReal(); - if ((frame < 0.0) || (frame > 1.0)) - { - frame = llclamp(frame, 0.0f, 1.0f); - (*track)[index][LLSettingsDay::SETTING_KEYKFRAME] = frame; - } - ++index; - } - - } - return true; - } -} - -LLSettingsDay::validation_list_t LLSettingsDay::getValidationList() const -{ - static validation_list_t validation; - - if (validation.empty()) - { - validation.push_back(Validator(SETTING_TRACKS, true, LLSD::TypeArray, - &validateDayCycleTrack)); - validation.push_back(Validator(SETTING_DAYLENGTH, false, LLSD::TypeInteger, - boost::bind(&Validator::verifyIntegerRange, _1, - LLSD(LLSDArray(LLSD::Integer(MINIMUM_DAYLENGTH))(LLSD::Integer(MAXIMUM_DAYLENGTH)))))); - } - - return validation; -} - -//========================================================================= -F32 LLSettingsDay::secondsToKeyframe(S64Seconds seconds) -{ - S64Seconds daylength = getDayLength(); - - return llclamp(static_cast(seconds.value() % daylength.value()) / static_cast(daylength.value()), 0.0f, 1.0f); -} - -F64Seconds LLSettingsDay::keyframeToSeconds(F32 keyframe) -{ - S64Seconds daylength = getDayLength(); - - return F64Seconds(static_cast(keyframe * static_cast(daylength.value()))); -} - -//========================================================================= -void LLSettingsDay::startDayCycle() -{ - F64Seconds now(LLDate::now().secondsSinceEpoch()); - - if (!mHasParsed) - parseFromLLSD(mSettings); - - // water - if (mDayTracks[0].empty()) - { - mBlendedWater.reset(); - mWaterBlender.reset(); - } - else if (mDayTracks[0].size() == 1) - { - mBlendedWater = boost::static_pointer_cast((*(mDayTracks[0].begin())).second); - mWaterBlender.reset(); - } - else - { - TrackBound_t bounds = getBoundingEntries(mDayTracks[0], now); - - F64Seconds timespan = F64Seconds( getDayLength() * get_wrapping_distance((*bounds.first).first, (*bounds.second).first)); - - mBlendedWater = LLSettingsWater::buildDefaultWater(); - mWaterBlender = boost::make_shared(mBlendedWater, - (*bounds.first).second, (*bounds.second).second, timespan); - mWaterBlender->setOnFinished(boost::bind(&LLSettingsDay::onWaterTransitionDone, this, _1)); - } - - // sky - if (mDayTracks[1].empty()) - { - mBlendedSky.reset(); - mSkyBlender.reset(); - } - else if (mDayTracks[1].size() == 1) - { - mBlendedSky = boost::static_pointer_cast( (*(mDayTracks[1].begin())).second); - mSkyBlender.reset(); - } - else - { - TrackBound_t bounds = getBoundingEntries(mDayTracks[1], now); - F64Seconds timespan = F64Seconds(getDayLength() * get_wrapping_distance((*bounds.first).first, (*bounds.second).first)); - - mBlendedSky = LLSettingsSky::buildDefaultSky(); - mSkyBlender = boost::make_shared(mBlendedSky, - (*bounds.first).second, (*bounds.second).second, timespan); - mSkyBlender->setOnFinished(boost::bind(&LLSettingsDay::onSkyTransitionDone, this, 1, _1)); - } -} - - -void LLSettingsDay::updateSettings() -{ - static LLFrameTimer timer; - - - F64Seconds delta(timer.getElapsedTimeAndResetF32()); - - if (mSkyBlender) - mSkyBlender->update(delta); - if (mWaterBlender) - mWaterBlender->update(delta); - -#if 0 - //F64Seconds time_now(LLWorld::instance().getSpaceTimeUSec()); - F64Seconds time_now(LLDate::now().secondsSinceEpoch()); - - // base class clears dirty flag so as to not trigger recursive update - LLSettingsBase::updateSettings(); - - if (!mBlendedWater) - { - mBlendedWater = LLEnvironment::instance().getCurrentWater()->buildClone(); - LLEnvironment::instance().selectWater(mBlendedWater); - } - - if (!mBlendedSky) - { - mBlendedSky = LLEnvironment::instance().getCurrentSky()->buildClone(); - LLEnvironment::instance().selectSky(mBlendedSky); - } - - - if ((time_now < mLastUpdateTime) || ((time_now - mLastUpdateTime) > static_cast(0.1))) - { - F64Seconds daylength = static_cast(getDayLength()); - F32 frame = fmod(time_now.value(), daylength.value()) / daylength.value(); - - CycleList_t::iterator itTrack = mDayTracks.begin(); - TrackBound_t bounds = getBoundingEntries(*itTrack, frame); - - mBlendedWater->replaceSettings((*bounds.first).second->getSettings()); - if (bounds.first != bounds.second) - { - F32 blendf = get_wrapping_distance((*bounds.first).first, frame) / get_wrapping_distance((*bounds.first).first, (*bounds.second).first); - - mBlendedWater->blend((*bounds.second).second, blendf); - } - - ++itTrack; - bounds = getBoundingEntries(*itTrack, frame); - - //_WARNS("RIDER") << "Sky blending: frame=" << frame << " start=" << F64Seconds((*bounds.first).first) << " end=" << F64Seconds((*bounds.second).first) << LL_ENDL; - - mBlendedSky->replaceSettings((*bounds.first).second->getSettings()); - if (bounds.first != bounds.second) - { - F32 blendf = get_wrapping_distance((*bounds.first).first, frame) / get_wrapping_distance((*bounds.first).first, (*bounds.second).first); - //_WARNS("RIDER") << "Distance=" << get_wrapping_distance((*bounds.first).first, frame) << "/" << get_wrapping_distance((*bounds.first).first, (*bounds.second).first) << " Blend factor=" << blendf << LL_ENDL; - - mBlendedSky->blend((*bounds.second).second, blendf); - } - - mLastUpdateTime = time_now; - } - - // Always mark the day cycle as dirty.So that the blend check can be handled. - setDirtyFlag(true); -#endif -} - -//========================================================================= -void LLSettingsDay::setDayLength(S64Seconds seconds) -{ - S32 val = llclamp(seconds.value(), MINIMUM_DAYLENGTH, MAXIMUM_DAYLENGTH); - - setValue(SETTING_DAYLENGTH, val); -} - -LLSettingsDay::KeyframeList_t LLSettingsDay::getTrackKeyframes(S32 trackno) -{ - if ((trackno < 1) || (trackno >= TRACK_MAX)) - { - LL_WARNS("DAYCYCLE") << "Attempt get track (#" << trackno << ") out of range!" << LL_ENDL; - return KeyframeList_t(); - } - - KeyframeList_t keyframes; - CycleTrack_t &track = mDayTracks[trackno]; - - keyframes.reserve(track.size()); - - for (CycleTrack_t::iterator it = track.begin(); it != track.end(); ++it) - { - keyframes.push_back((*it).first); - } - - return keyframes; -} - -LLSettingsDay::TimeList_t LLSettingsDay::getTrackTimes(S32 trackno) -{ - KeyframeList_t keyframes = getTrackKeyframes(trackno); - - if (keyframes.empty()) - return TimeList_t(); - - TimeList_t times; - - times.reserve(keyframes.size()); - for (KeyframeList_t::iterator it = keyframes.begin(); it != keyframes.end(); ++it) - { - times.push_back(keyframeToSeconds(*it)); - } - - return times; -} - -void LLSettingsDay::setWaterAtTime(const LLSettingsWaterPtr_t &water, S64Seconds seconds) -{ - F32 keyframe = secondsToKeyframe(seconds); - setWaterAtKeyframe(water, keyframe); -} - -void LLSettingsDay::setWaterAtKeyframe(const LLSettingsWaterPtr_t &water, F32 keyframe) -{ - mDayTracks[TRACK_WATER][llclamp(keyframe, 0.0f, 1.0f)] = water; - setDirtyFlag(true); -} - - -void LLSettingsDay::setSkyAtTime(const LLSettingsSkyPtr_t &sky, S64Seconds seconds, S32 track) -{ - F32 keyframe = secondsToKeyframe(seconds); - setSkyAtKeyframe(sky, keyframe, track); -} - -void LLSettingsDay::setSkyAtKeyframe(const LLSettingsSkyPtr_t &sky, F32 keyframe, S32 track) -{ - if ((track < 1) || (track >= TRACK_MAX)) - { - LL_WARNS("DAYCYCLE") << "Attempt to set sky track (#" << track << ") out of range!" << LL_ENDL; - return; - } - - mDayTracks[track][llclamp(keyframe, 0.0f, 1.0f)] = sky; - setDirtyFlag(true); -} - -LLSettingsDay::TrackBound_t LLSettingsDay::getBoundingEntries(LLSettingsDay::CycleTrack_t &track, F32 keyframe) -{ - return TrackBound_t(get_wrapping_atbefore(track, keyframe), get_wrapping_atafter(track, keyframe)); -} - -LLSettingsDay::TrackBound_t LLSettingsDay::getBoundingEntries(LLSettingsDay::CycleTrack_t &track, F64Seconds time) -{ - F32 frame = secondsToKeyframe(time); - - return getBoundingEntries(track, frame); -} - -//========================================================================= -void LLSettingsDay::onSkyTransitionDone(S32 track, const LLSettingsBlender::ptr_t &blender) -{ - F64Seconds now(LLDate::now().secondsSinceEpoch()); - TrackBound_t bounds = getBoundingEntries(mDayTracks[track], now); - - F32 distance = get_wrapping_distance((*bounds.first).first, (*bounds.second).first); - F64Seconds timespan = F64Seconds(distance * getDayLength()); - - LL_WARNS("RIDER") << "New sky blender. now=" << now << - " start=" << (*bounds.first).first << " end=" << (*bounds.second).first << - " span=" << timespan << LL_ENDL; - - mSkyBlender = boost::make_shared(mBlendedSky, - (*bounds.first).second, (*bounds.second).second, timespan); - mSkyBlender->setOnFinished(boost::bind(&LLSettingsDay::onSkyTransitionDone, this, track, _1)); -} - -void LLSettingsDay::onWaterTransitionDone(const LLSettingsBlender::ptr_t &blender) -{ - F64Seconds now(LLDate::now().secondsSinceEpoch()); - TrackBound_t bounds = getBoundingEntries(mDayTracks[0], now); - - F32 distance = get_wrapping_distance((*bounds.first).first, (*bounds.second).first); - F64Seconds timespan = F64Seconds(distance * getDayLength()); - - mWaterBlender = boost::make_shared(mBlendedWater, - (*bounds.first).second, (*bounds.second).second, timespan); - mWaterBlender->setOnFinished(boost::bind(&LLSettingsDay::onWaterTransitionDone, this, _1)); -} diff --git a/indra/newview/llsettingsdaycycle.h b/indra/newview/llsettingsdaycycle.h deleted file mode 100644 index 804d7aee26..0000000000 --- a/indra/newview/llsettingsdaycycle.h +++ /dev/null @@ -1,143 +0,0 @@ -/** -* @file llsettingsdaycycle.h -* @author optional -* @brief A base class for asset based settings groups. -* -* $LicenseInfo:2011&license=viewerlgpl$ -* Second Life Viewer Source Code -* Copyright (C) 2017, 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$ -*/ - -#ifndef LL_SETTINGS_DAYCYCLE_H -#define LL_SETTINGS_DAYCYCLE_H - -#include "llsettingsbase.h" - -class LLSettingsWater; -class LLSettingsSky; - -typedef boost::shared_ptr LLSettingsWaterPtr_t; -typedef boost::shared_ptr LLSettingsSkyPtr_t; - -class LLSettingsDay : public LLSettingsBase -{ -public: - static const std::string SETTING_DAYLENGTH; - static const std::string SETTING_KEYID; - static const std::string SETTING_KEYNAME; - static const std::string SETTING_KEYKFRAME; - static const std::string SETTING_TRACKS; - - static const S64 MINIMUM_DAYLENGTH; - static const S64 MAXIMUM_DAYLENGTH; - - static const S32 TRACK_WATER; - static const S32 TRACK_MAX; - static const S32 FRAME_MAX; - - typedef std::map CycleTrack_t; - typedef std::vector CycleList_t; - typedef boost::shared_ptr ptr_t; - typedef std::vector TimeList_t; - typedef std::vector KeyframeList_t; - typedef std::pair TrackBound_t; - - //--------------------------------------------------------------------- - LLSettingsDay(const LLSD &data); - virtual ~LLSettingsDay() { }; - - static ptr_t buildFromLegacyPreset(const std::string &name, const LLSD &oldsettings); - static ptr_t buildFromLegacyMessage(const LLUUID ®ionId, LLSD daycycle, LLSD skys, LLSD water); - static ptr_t buildDefaultDayCycle(); - ptr_t buildClone(); - - //--------------------------------------------------------------------- - virtual std::string getSettingType() const { return std::string("daycycle"); } - - // Settings status - virtual void blend(const LLSettingsBase::ptr_t &other, F32 mix); - - static LLSD defaults(); - - //--------------------------------------------------------------------- - S64Seconds getDayLength() const - { - return S64Seconds(mSettings[SETTING_DAYLENGTH].asInteger()); - } - - void setDayLength(S64Seconds seconds); - - KeyframeList_t getTrackKeyframes(S32 track); - TimeList_t getTrackTimes(S32 track); - - void setWaterAtTime(const LLSettingsWaterPtr_t &water, S64Seconds seconds); - void setWaterAtKeyframe(const LLSettingsWaterPtr_t &water, F32 keyframe); - - void setSkyAtTime(const LLSettingsSkyPtr_t &sky, S64Seconds seconds, S32 track); - void setSkyAtKeyframe(const LLSettingsSkyPtr_t &sky, F32 keyframe, S32 track); - //--------------------------------------------------------------------- - void startDayCycle(); - - LLSettingsSkyPtr_t getCurrentSky() const - { - return mBlendedSky; - } - - LLSettingsWaterPtr_t getCurrentWater() const - { - return mBlendedWater; - } - -protected: - LLSettingsDay(); - - virtual void updateSettings(); - - virtual validation_list_t getValidationList() const; - -private: - LLSettingsBlender::ptr_t mSkyBlender; // convert to [] for altitudes - LLSettingsBlender::ptr_t mWaterBlender; - - LLSettingsSkyPtr_t mBlendedSky; - LLSettingsWaterPtr_t mBlendedWater; - - CycleList_t mDayTracks; - - bool mHasParsed; - F64Seconds mLastUpdateTime; - - F32 secondsToKeyframe(S64Seconds seconds); - F64Seconds keyframeToSeconds(F32 keyframe); - - void parseFromLLSD(LLSD &data); - - static CycleTrack_t::iterator getEntryAtOrBefore(CycleTrack_t &track, F32 keyframe); - static CycleTrack_t::iterator getEntryAtOrAfter(CycleTrack_t &track, F32 keyframe); - - TrackBound_t getBoundingEntries(CycleTrack_t &track, F32 keyframe); - TrackBound_t getBoundingEntries(CycleTrack_t &track, F64Seconds time); - - void onSkyTransitionDone(S32 track, const LLSettingsBlender::ptr_t &blender); - void onWaterTransitionDone(const LLSettingsBlender::ptr_t &blender); - -}; - -#endif diff --git a/indra/newview/llsettingssky.cpp b/indra/newview/llsettingssky.cpp deleted file mode 100644 index f1825792d9..0000000000 --- a/indra/newview/llsettingssky.cpp +++ /dev/null @@ -1,655 +0,0 @@ -/** -* @file llsettingssky.cpp -* @author optional -* @brief A base class for asset based settings groups. -* -* $LicenseInfo:2011&license=viewerlgpl$ -* Second Life Viewer Source Code -* Copyright (C) 2017, 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 "llviewerprecompiledheaders.h" -#include "llviewercontrol.h" -#include "llsettingssky.h" -#include -#include -#include "lltrace.h" -#include "llfasttimer.h" -#include "v3colorutil.h" - -#include "llglslshader.h" -#include "llviewershadermgr.h" - -#include "llenvironment.h" -#include "llsky.h" - -//========================================================================= -namespace -{ - const LLVector3 DUE_EAST(0.0f, 0.0f, 1.0); - const LLVector3 VECT_ZENITH(0.f, 1.f, 0.f); - const LLVector3 VECT_NORTHSOUTH(1.f, 0.f, 0.f); - - LLTrace::BlockTimerStatHandle FTM_BLEND_SKYVALUES("Blending Sky Environment"); - LLTrace::BlockTimerStatHandle FTM_UPDATE_SKYVALUES("Update Sky Environment"); - - LLQuaternion body_position_from_angles(F32 azimuth, F32 altitude); - void angles_from_rotation(LLQuaternion quat, F32 &azimuth, F32 &altitude); -} - -const F32 LLSettingsSky::DOME_OFFSET(0.96f); -const F32 LLSettingsSky::DOME_RADIUS(15000.f); - -//========================================================================= -const std::string LLSettingsSky::SETTING_AMBIENT("ambient"); -const std::string LLSettingsSky::SETTING_BLOOM_TEXTUREID("bloom_id"); -const std::string LLSettingsSky::SETTING_BLUE_DENSITY("blue_density"); -const std::string LLSettingsSky::SETTING_BLUE_HORIZON("blue_horizon"); -const std::string LLSettingsSky::SETTING_CLOUD_COLOR("cloud_color"); -const std::string LLSettingsSky::SETTING_CLOUD_POS_DENSITY1("cloud_pos_density1"); -const std::string LLSettingsSky::SETTING_CLOUD_POS_DENSITY2("cloud_pos_density2"); -const std::string LLSettingsSky::SETTING_CLOUD_SCALE("cloud_scale"); -const std::string LLSettingsSky::SETTING_CLOUD_SCROLL_RATE("cloud_scroll_rate"); -const std::string LLSettingsSky::SETTING_CLOUD_SHADOW("cloud_shadow"); -const std::string LLSettingsSky::SETTING_CLOUD_TEXTUREID("cloud_id"); -const std::string LLSettingsSky::SETTING_DENSITY_MULTIPLIER("density_multiplier"); -const std::string LLSettingsSky::SETTING_DISTANCE_MULTIPLIER("distance_multiplier"); -const std::string LLSettingsSky::SETTING_DOME_OFFSET("dome_offset"); -const std::string LLSettingsSky::SETTING_DOME_RADIUS("dome_radius"); -const std::string LLSettingsSky::SETTING_GAMMA("gamma"); -const std::string LLSettingsSky::SETTING_GLOW("glow"); -const std::string LLSettingsSky::SETTING_HAZE_DENSITY("haze_density"); -const std::string LLSettingsSky::SETTING_HAZE_HORIZON("haze_horizon"); -const std::string LLSettingsSky::SETTING_LIGHT_NORMAL("lightnorm"); -const std::string LLSettingsSky::SETTING_MAX_Y("max_y"); -const std::string LLSettingsSky::SETTING_MOON_ROTATION("moon_rotation"); -const std::string LLSettingsSky::SETTING_MOON_TEXTUREID("moon_id"); -const std::string LLSettingsSky::SETTING_STAR_BRIGHTNESS("star_brightness"); -const std::string LLSettingsSky::SETTING_SUNLIGHT_COLOR("sunlight_color"); -const std::string LLSettingsSky::SETTING_SUN_ROTATION("sun_rotation"); -const std::string LLSettingsSky::SETTING_SUN_TEXUTUREID("sun_id"); - -const std::string LLSettingsSky::SETTING_LEGACY_EAST_ANGLE("east_angle"); -const std::string LLSettingsSky::SETTING_LEGACY_ENABLE_CLOUD_SCROLL("enable_cloud_scroll"); -const std::string LLSettingsSky::SETTING_LEGACY_SUN_ANGLE("sun_angle"); - -//========================================================================= -LLSettingsSky::LLSettingsSky(const LLSD &data) : - LLSettingsBase(data) -{ -} - -LLSettingsSky::LLSettingsSky(): - LLSettingsBase() -{ -} - -void LLSettingsSky::blend(const LLSettingsBase::ptr_t &end, F32 blendf) -{ - LLSettingsSky::ptr_t other = boost::static_pointer_cast(end); - LLSD blenddata = interpolateSDMap(mSettings, other->mSettings, blendf); - - replaceSettings(blenddata); -} - - -void LLSettingsSky::setMoonRotation(F32 azimuth, F32 altitude) -{ - setValue(SETTING_MOON_ROTATION, ::body_position_from_angles(azimuth, altitude)); -} - -LLSettingsSky::azimalt_t LLSettingsSky::getMoonRotationAzAl() const -{ - azimalt_t res; - ::angles_from_rotation(getMoonRotation(), res.first, res.second); - - return res; -} - -void LLSettingsSky::setSunRotation(F32 azimuth, F32 altitude) -{ - setValue(SETTING_SUN_ROTATION, ::body_position_from_angles(azimuth, altitude)); -} - -LLSettingsSky::azimalt_t LLSettingsSky::getSunRotationAzAl() const -{ - azimalt_t res; - ::angles_from_rotation(getSunRotation(), res.first, res.second); - - return res; -} - -LLSettingsSky::stringset_t LLSettingsSky::getSlerpKeys() const -{ - static stringset_t slepSet; - - if (slepSet.empty()) - { - slepSet.insert(SETTING_SUN_ROTATION); - slepSet.insert(SETTING_MOON_ROTATION); - } - - return slepSet; -} - -LLSettingsSky::validation_list_t LLSettingsSky::getValidationList() const -{ - static validation_list_t validation; - - if (validation.empty()) - { // Note the use of LLSD(LLSDArray()()()...) This is due to an issue with the - // copy constructor for LLSDArray. Directly binding the LLSDArray as - // a parameter without first wrapping it in a pure LLSD object will result - // in deeply nested arrays like this [[[[[[[[[[v1,v2,v3]]]]]]]]]] - - validation.push_back(Validator(SETTING_AMBIENT, true, LLSD::TypeArray, - boost::bind(&Validator::verifyVectorMinMax, _1, - LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")), - LLSD(LLSDArray(3.0f)(3.0f)(3.0f)("*"))))); - validation.push_back(Validator(SETTING_BLOOM_TEXTUREID, true, LLSD::TypeUUID)); - validation.push_back(Validator(SETTING_BLUE_DENSITY, true, LLSD::TypeArray, - boost::bind(&Validator::verifyVectorMinMax, _1, - LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")), - LLSD(LLSDArray(2.0f)(2.0f)(2.0f)("*"))))); - validation.push_back(Validator(SETTING_BLUE_HORIZON, true, LLSD::TypeArray, - boost::bind(&Validator::verifyVectorMinMax, _1, - LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")), - LLSD(LLSDArray(2.0f)(2.0f)(2.0f)("*"))))); - validation.push_back(Validator(SETTING_CLOUD_COLOR, true, LLSD::TypeArray, - boost::bind(&Validator::verifyVectorMinMax, _1, - LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")), - LLSD(LLSDArray(1.0f)(1.0f)(1.0f)("*"))))); - validation.push_back(Validator(SETTING_CLOUD_POS_DENSITY1, true, LLSD::TypeArray, - boost::bind(&Validator::verifyVectorMinMax, _1, - LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")), - LLSD(LLSDArray(1.68841f)(1.0f)(1.0f)("*"))))); - validation.push_back(Validator(SETTING_CLOUD_POS_DENSITY2, true, LLSD::TypeArray, - boost::bind(&Validator::verifyVectorMinMax, _1, - LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")), - LLSD(LLSDArray(1.68841f)(1.0f)(1.0f)("*"))))); - validation.push_back(Validator(SETTING_CLOUD_SCALE, true, LLSD::TypeReal, - boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.001f)(0.999f))))); - validation.push_back(Validator(SETTING_CLOUD_SCROLL_RATE, true, LLSD::TypeArray, - boost::bind(&Validator::verifyVectorMinMax, _1, - LLSD(LLSDArray(0.0f)(0.0f)), - LLSD(LLSDArray(20.0f)(20.0f))))); - validation.push_back(Validator(SETTING_CLOUD_SHADOW, true, LLSD::TypeReal, - boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f))))); - validation.push_back(Validator(SETTING_CLOUD_TEXTUREID, false, LLSD::TypeUUID)); - validation.push_back(Validator(SETTING_DENSITY_MULTIPLIER, true, LLSD::TypeReal, - boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(0.0009f))))); - validation.push_back(Validator(SETTING_DISTANCE_MULTIPLIER, true, LLSD::TypeReal, - boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(100.0f))))); - validation.push_back(Validator(SETTING_DOME_OFFSET, false, LLSD::TypeReal, - boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f))))); - validation.push_back(Validator(SETTING_DOME_RADIUS, false, LLSD::TypeReal, - boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(1000.0f)(2000.0f))))); - validation.push_back(Validator(SETTING_GAMMA, true, LLSD::TypeReal, - boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(10.0f))))); - validation.push_back(Validator(SETTING_GLOW, true, LLSD::TypeArray, - boost::bind(&Validator::verifyVectorMinMax, _1, - LLSD(LLSDArray(0.2f)("*")(-2.5f)("*")), - LLSD(LLSDArray(20.0f)("*")(0.0f)("*"))))); - validation.push_back(Validator(SETTING_HAZE_DENSITY, true, LLSD::TypeReal, - boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(4.0f))))); - validation.push_back(Validator(SETTING_HAZE_HORIZON, true, LLSD::TypeReal, - boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f))))); - validation.push_back(Validator(SETTING_LIGHT_NORMAL, false, LLSD::TypeArray, - boost::bind(&Validator::verifyVectorNormalized, _1, 3))); - validation.push_back(Validator(SETTING_MAX_Y, true, LLSD::TypeReal, - boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(4000.0f))))); - validation.push_back(Validator(SETTING_MOON_ROTATION, true, LLSD::TypeArray, &Validator::verifyQuaternionNormal)); - validation.push_back(Validator(SETTING_MOON_TEXTUREID, false, LLSD::TypeUUID)); - validation.push_back(Validator(SETTING_STAR_BRIGHTNESS, true, LLSD::TypeReal, - boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(2.0f))))); - validation.push_back(Validator(SETTING_SUNLIGHT_COLOR, true, LLSD::TypeArray, - boost::bind(&Validator::verifyVectorMinMax, _1, - LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")), - LLSD(LLSDArray(3.0f)(3.0f)(3.0f)("*"))))); - validation.push_back(Validator(SETTING_SUN_ROTATION, true, LLSD::TypeArray, &Validator::verifyQuaternionNormal)); - validation.push_back(Validator(SETTING_SUN_TEXUTUREID, false, LLSD::TypeUUID)); - } - - return validation; -} - -LLSettingsSky::ptr_t LLSettingsSky::buildFromLegacyPreset(const std::string &name, const LLSD &oldsettings) -{ - LLSD newsettings(defaults()); - - newsettings[SETTING_NAME] = name; - - - if (oldsettings.has(SETTING_AMBIENT)) - { - newsettings[SETTING_AMBIENT] = LLColor3(oldsettings[SETTING_AMBIENT]).getValue(); - } - if (oldsettings.has(SETTING_BLUE_DENSITY)) - { - newsettings[SETTING_BLUE_DENSITY] = LLColor3(oldsettings[SETTING_BLUE_DENSITY]).getValue(); - } - if (oldsettings.has(SETTING_BLUE_HORIZON)) - { - newsettings[SETTING_BLUE_HORIZON] = LLColor3(oldsettings[SETTING_BLUE_HORIZON]).getValue(); - } - if (oldsettings.has(SETTING_CLOUD_COLOR)) - { - newsettings[SETTING_CLOUD_COLOR] = LLColor3(oldsettings[SETTING_CLOUD_COLOR]).getValue(); - } - if (oldsettings.has(SETTING_CLOUD_POS_DENSITY1)) - { - newsettings[SETTING_CLOUD_POS_DENSITY1] = LLColor3(oldsettings[SETTING_CLOUD_POS_DENSITY1]).getValue(); - } - if (oldsettings.has(SETTING_CLOUD_POS_DENSITY2)) - { - newsettings[SETTING_CLOUD_POS_DENSITY2] = LLColor3(oldsettings[SETTING_CLOUD_POS_DENSITY2]).getValue(); - } - if (oldsettings.has(SETTING_CLOUD_SCALE)) - { - newsettings[SETTING_CLOUD_SCALE] = LLSD::Real(oldsettings[SETTING_CLOUD_SCALE][0].asReal()); - } - if (oldsettings.has(SETTING_CLOUD_SCROLL_RATE)) - { - LLVector2 cloud_scroll(oldsettings[SETTING_CLOUD_SCROLL_RATE]); - - if (oldsettings.has(SETTING_LEGACY_ENABLE_CLOUD_SCROLL)) - { - LLSD enabled = oldsettings[SETTING_LEGACY_ENABLE_CLOUD_SCROLL]; - if (!enabled[0].asBoolean()) - cloud_scroll.mV[0] = 0.0f; - if (!enabled[1].asBoolean()) - cloud_scroll.mV[1] = 0.0f; - } - - newsettings[SETTING_CLOUD_SCROLL_RATE] = cloud_scroll.getValue(); - } - if (oldsettings.has(SETTING_CLOUD_SHADOW)) - { - newsettings[SETTING_CLOUD_SHADOW] = LLSD::Real(oldsettings[SETTING_CLOUD_SHADOW][0].asReal()); - } - if (oldsettings.has(SETTING_DENSITY_MULTIPLIER)) - { - newsettings[SETTING_DENSITY_MULTIPLIER] = LLSD::Real(oldsettings[SETTING_DENSITY_MULTIPLIER][0].asReal()); - } - if (oldsettings.has(SETTING_DISTANCE_MULTIPLIER)) - { - newsettings[SETTING_DISTANCE_MULTIPLIER] = LLSD::Real(oldsettings[SETTING_DISTANCE_MULTIPLIER][0].asReal()); - } - if (oldsettings.has(SETTING_GAMMA)) - { - newsettings[SETTING_GAMMA] = oldsettings[SETTING_GAMMA][0].asReal(); - } - if (oldsettings.has(SETTING_GLOW)) - { - newsettings[SETTING_GLOW] = LLColor3(oldsettings[SETTING_GLOW]).getValue(); - } - if (oldsettings.has(SETTING_HAZE_DENSITY)) - { - newsettings[SETTING_HAZE_DENSITY] = LLSD::Real(oldsettings[SETTING_HAZE_DENSITY][0].asReal()); - } - if (oldsettings.has(SETTING_HAZE_HORIZON)) - { - newsettings[SETTING_HAZE_HORIZON] = LLSD::Real(oldsettings[SETTING_HAZE_HORIZON][0].asReal()); - } - if (oldsettings.has(SETTING_LIGHT_NORMAL)) - { - newsettings[SETTING_LIGHT_NORMAL] = LLVector3(oldsettings[SETTING_LIGHT_NORMAL]).getValue(); - } - if (oldsettings.has(SETTING_MAX_Y)) - { - newsettings[SETTING_MAX_Y] = LLSD::Real(oldsettings[SETTING_MAX_Y][0].asReal()); - } - if (oldsettings.has(SETTING_STAR_BRIGHTNESS)) - { - newsettings[SETTING_STAR_BRIGHTNESS] = LLSD::Real(oldsettings[SETTING_STAR_BRIGHTNESS].asReal()); - } - if (oldsettings.has(SETTING_SUNLIGHT_COLOR)) - { - newsettings[SETTING_SUNLIGHT_COLOR] = LLColor4(oldsettings[SETTING_SUNLIGHT_COLOR]).getValue(); - } - - if (oldsettings.has(SETTING_LEGACY_EAST_ANGLE) && oldsettings.has(SETTING_LEGACY_SUN_ANGLE)) - { // convert the east and sun angles into a quaternion. - F32 azimuth = oldsettings[SETTING_LEGACY_EAST_ANGLE].asReal(); - F32 altitude = oldsettings[SETTING_LEGACY_SUN_ANGLE].asReal(); - - LLQuaternion sunquat = ::body_position_from_angles(azimuth, altitude); - LLQuaternion moonquat = ::body_position_from_angles(azimuth + F_PI, -altitude); - - F32 az(0), al(0); - ::angles_from_rotation(sunquat, az, al); - - newsettings[SETTING_SUN_ROTATION] = sunquat.getValue(); - newsettings[SETTING_MOON_ROTATION] = moonquat.getValue(); - } - - LLSettingsSky::ptr_t skyp = boost::make_shared(newsettings); - - if (skyp->validate()) - return skyp; - - return LLSettingsSky::ptr_t(); -} - -LLSettingsSky::ptr_t LLSettingsSky::buildDefaultSky() -{ - LLSD settings = LLSettingsSky::defaults(); - - LLSettingsSky::ptr_t skyp = boost::make_shared(settings); - if (skyp->validate()) - return skyp; - - return LLSettingsSky::ptr_t(); -} - -LLSettingsSky::ptr_t LLSettingsSky::buildClone() -{ - LLSD settings = cloneSettings(); - - LLSettingsSky::ptr_t skyp = boost::make_shared(settings); - - if (skyp->validate()) - return skyp; - - return LLSettingsSky::ptr_t(); -} - - -LLSD LLSettingsSky::defaults() -{ - LLSD dfltsetting; - - - LLQuaternion sunquat; - sunquat.setEulerAngles(1.39626, 0.0, 0.0); // 80deg Azumith/0deg East - LLQuaternion moonquat = ~sunquat; - - // Magic constants copied form dfltsetting.xml - dfltsetting[SETTING_AMBIENT] = LLColor4::white.getValue(); - dfltsetting[SETTING_BLUE_DENSITY] = LLColor4(0.2447, 0.4487, 0.7599, 0.0).getValue(); - dfltsetting[SETTING_BLUE_HORIZON] = LLColor4(0.4954, 0.4954, 0.6399, 0.0).getValue(); - dfltsetting[SETTING_CLOUD_COLOR] = LLColor4(0.4099, 0.4099, 0.4099, 0.0).getValue(); - dfltsetting[SETTING_CLOUD_POS_DENSITY1] = LLColor4(1.0000, 0.5260, 1.0000, 0.0).getValue(); - dfltsetting[SETTING_CLOUD_POS_DENSITY2] = LLColor4(1.0000, 0.5260, 1.0000, 0.0).getValue(); - dfltsetting[SETTING_CLOUD_SCALE] = LLSD::Real(0.4199); - dfltsetting[SETTING_CLOUD_SCROLL_RATE] = LLSDArray(10.1999)(10.0109); - dfltsetting[SETTING_CLOUD_SHADOW] = LLSD::Real(0.2699); - dfltsetting[SETTING_DENSITY_MULTIPLIER] = LLSD::Real(0.0001); - dfltsetting[SETTING_DISTANCE_MULTIPLIER] = LLSD::Real(0.8000); - dfltsetting[SETTING_DOME_OFFSET] = LLSD::Real(0.96f); - dfltsetting[SETTING_DOME_RADIUS] = LLSD::Real(15000.f); - dfltsetting[SETTING_GAMMA] = LLSD::Real(1.0); - dfltsetting[SETTING_GLOW] = LLColor4(5.000, 0.0010, -0.4799, 1.0).getValue(); - dfltsetting[SETTING_HAZE_DENSITY] = LLSD::Real(0.6999); - dfltsetting[SETTING_HAZE_HORIZON] = LLSD::Real(0.1899); - dfltsetting[SETTING_LIGHT_NORMAL] = LLVector3(0.0000, 0.9126, -0.4086).getValue(); - dfltsetting[SETTING_MAX_Y] = LLSD::Real(1605); - dfltsetting[SETTING_MOON_ROTATION] = moonquat.getValue(); - dfltsetting[SETTING_NAME] = std::string("_default_"); - dfltsetting[SETTING_STAR_BRIGHTNESS] = LLSD::Real(0.0000); - dfltsetting[SETTING_SUNLIGHT_COLOR] = LLColor4(0.7342, 0.7815, 0.8999, 0.0).getValue(); - dfltsetting[SETTING_SUN_ROTATION] = sunquat.getValue(); - - dfltsetting[SETTING_BLOOM_TEXTUREID] = LLUUID::null; - dfltsetting[SETTING_CLOUD_TEXTUREID] = LLUUID::null; - dfltsetting[SETTING_MOON_TEXTUREID] = IMG_MOON; // gMoonTextureID; // These two are returned by the login... wow! - dfltsetting[SETTING_SUN_TEXUTUREID] = IMG_SUN; // gSunTextureID; - - return dfltsetting; -} - -void LLSettingsSky::updateSettings() -{ - LL_RECORD_BLOCK_TIME(FTM_UPDATE_SKYVALUES); - //LL_INFOS("WINDLIGHT", "SKY", "EEP") << "WL Parameters are dirty. Reticulating Splines..." << LL_ENDL; - - // base class clears dirty flag so as to not trigger recursive update - LLSettingsBase::updateSettings(); - - calculateHeavnlyBodyPositions(); - calculateLightSettings(); -} - -void LLSettingsSky::calculateHeavnlyBodyPositions() -{ - mSunDirection = DUE_EAST * getSunRotation(); - mSunDirection.normalize(); - mMoonDirection = DUE_EAST * getMoonRotation(); - mMoonDirection.normalize(); - - { // set direction (in CRF) and don't allow overriding - LLVector3 crf_sunDirection(mSunDirection.mV[2], mSunDirection.mV[0], mSunDirection.mV[1]); - LLVector3 crf_moonDirection(mMoonDirection.mV[2], mMoonDirection.mV[0], mMoonDirection.mV[1]); - - gSky.setSunDirection(crf_sunDirection, crf_moonDirection); - } - - // is the normal from the sun or the moon - if (mSunDirection.mV[1] >= 0.0) - { - mLightDirection = mSunDirection; - } - else if (mSunDirection.mV[1] < 0.0 && mSunDirection.mV[1] > LLSky::NIGHTTIME_ELEVATION_COS) - { - // clamp v1 to 0 so sun never points up and causes weirdness on some machines - LLVector3 vec(mSunDirection); - vec.mV[1] = 0.0; - vec.normalize(); - mLightDirection = vec; - } - else - { - mLightDirection = mMoonDirection; - } - - // calculate the clamp lightnorm for sky (to prevent ugly banding in sky - // when haze goes below the horizon - mClampedLightDirection = mLightDirection; - - if (mClampedLightDirection.mV[1] < -0.1f) - { - mClampedLightDirection.mV[1] = -0.1f; - mClampedLightDirection.normalize(); - } -} - -void LLSettingsSky::calculateLightSettings() -{ - LLColor3 vary_HazeColor; - LLColor3 vary_SunlightColor; - LLColor3 vary_AmbientColor; - { - // Initialize temp variables - LLColor3 sunlight = getSunlightColor(); - LLColor3 ambient = getAmbientColor(); - F32 gamma = getGamma(); - LLColor3 blue_density = getBlueDensity(); - LLColor3 blue_horizon = getBlueHorizon(); - F32 haze_density = getHazeDensity(); - F32 haze_horizon = getHazeHorizon(); - F32 density_multiplier = getDensityMultiplier(); - F32 max_y = getMaxY(); - F32 cloud_shadow = getCloudShadow(); - LLVector3 lightnorm = getLightDirection(); - - // Sunlight attenuation effect (hue and brightness) due to atmosphere - // this is used later for sunlight modulation at various altitudes - LLColor3 light_atten = - (blue_density * 1.0 + smear(haze_density * 0.25f)) * (density_multiplier * max_y); - - // Calculate relative weights - LLColor3 temp2(0.f, 0.f, 0.f); - LLColor3 temp1 = blue_density + smear(haze_density); - LLColor3 blue_weight = componentDiv(blue_density, temp1); - LLColor3 haze_weight = componentDiv(smear(haze_density), temp1); - - // Compute sunlight from P & lightnorm (for long rays like sky) - /// USE only lightnorm. - // temp2[1] = llmax(0.f, llmax(0.f, Pn[1]) * 1.0f + lightnorm[1] ); - - // and vary_sunlight will work properly with moon light - F32 lighty = lightnorm[1]; - if (lighty < LLSky::NIGHTTIME_ELEVATION_COS) - { - lighty = -lighty; - } - - temp2.mV[1] = llmax(0.f, lighty); - if(temp2.mV[1] > 0.f) - { - temp2.mV[1] = 1.f / temp2.mV[1]; - } - componentMultBy(sunlight, componentExp((light_atten * -1.f) * temp2.mV[1])); - - // Distance - temp2.mV[2] = density_multiplier; - - // Transparency (-> temp1) - temp1 = componentExp((temp1 * -1.f) * temp2.mV[2]); - - // vary_AtmosAttenuation = temp1; - - //increase ambient when there are more clouds - LLColor3 tmpAmbient = ambient + (smear(1.f) - ambient) * cloud_shadow * 0.5f; - - //haze color - vary_HazeColor = - (blue_horizon * blue_weight * (sunlight*(1.f - cloud_shadow) + tmpAmbient) - + componentMult(haze_horizon * haze_weight, sunlight*(1.f - cloud_shadow) * temp2.mV[0] + tmpAmbient) - ); - - //brightness of surface both sunlight and ambient - vary_SunlightColor = componentMult(sunlight, temp1) * 1.f; - vary_SunlightColor.clamp(); - vary_SunlightColor = smear(1.0f) - vary_SunlightColor; - vary_SunlightColor = componentPow(vary_SunlightColor, gamma); - vary_SunlightColor = smear(1.0f) - vary_SunlightColor; - vary_AmbientColor = componentMult(tmpAmbient, temp1) * 0.5; - vary_AmbientColor.clamp(); - vary_AmbientColor = smear(1.0f) - vary_AmbientColor; - vary_AmbientColor = componentPow(vary_AmbientColor, gamma); - vary_AmbientColor = smear(1.0f) - vary_AmbientColor; - - componentMultBy(vary_HazeColor, LLColor3(1.f, 1.f, 1.f) - temp1); - - } - - mSunDiffuse = vary_SunlightColor; - mSunAmbient = vary_AmbientColor; - mMoonDiffuse = vary_SunlightColor; - mMoonAmbient = vary_AmbientColor; - - mTotalAmbient = LLColor4(vary_AmbientColor, 1.0f); - - mFadeColor = mTotalAmbient + (mSunDiffuse + mMoonDiffuse) * 0.5f; - mFadeColor.setAlpha(0); -} - -LLSettingsSky::parammapping_t LLSettingsSky::getParameterMap() const -{ - static parammapping_t param_map; - - if (param_map.empty()) - { - param_map[SETTING_AMBIENT] = LLShaderMgr::AMBIENT; - param_map[SETTING_BLUE_DENSITY] = LLShaderMgr::BLUE_DENSITY; - param_map[SETTING_BLUE_HORIZON] = LLShaderMgr::BLUE_HORIZON; - param_map[SETTING_CLOUD_COLOR] = LLShaderMgr::CLOUD_COLOR; - - param_map[SETTING_CLOUD_POS_DENSITY2] = LLShaderMgr::CLOUD_POS_DENSITY2; - param_map[SETTING_CLOUD_SCALE] = LLShaderMgr::CLOUD_SCALE; - param_map[SETTING_CLOUD_SHADOW] = LLShaderMgr::CLOUD_SHADOW; - param_map[SETTING_DENSITY_MULTIPLIER] = LLShaderMgr::DENSITY_MULTIPLIER; - param_map[SETTING_DISTANCE_MULTIPLIER] = LLShaderMgr::DISTANCE_MULTIPLIER; - param_map[SETTING_GLOW] = LLShaderMgr::GLOW; - param_map[SETTING_HAZE_DENSITY] = LLShaderMgr::HAZE_DENSITY; - param_map[SETTING_HAZE_HORIZON] = LLShaderMgr::HAZE_HORIZON; - param_map[SETTING_MAX_Y] = LLShaderMgr::MAX_Y; - param_map[SETTING_SUNLIGHT_COLOR] = LLShaderMgr::SUNLIGHT_COLOR; - } - - return param_map; -} - -//========================================================================= -namespace -{ - LLQuaternion body_position_from_angles(F32 azimuth, F32 altitude) - { - // Azimuth is traditionally calculated from North, we are going from East. - LLQuaternion rot_azi; - LLQuaternion rot_alt; - - rot_azi.setAngleAxis(azimuth, VECT_ZENITH); - rot_alt.setAngleAxis(-altitude, VECT_NORTHSOUTH); - - LLQuaternion body_quat = rot_alt * rot_azi; - body_quat.normalize(); - - //LLVector3 sun_vector = (DUE_EAST * body_quat); - //_WARNS("RIDER") << "Azimuth=" << azimuth << " Altitude=" << altitude << " Body Vector=" << sun_vector.getValue() << LL_ENDL; - return body_quat; - } - - void angles_from_rotation(LLQuaternion quat, F32 &azimuth, F32 &altitude) - { - LLVector3 body_vector = (DUE_EAST * quat); - - LLVector3 body_az(body_vector[0], 0.f, body_vector[2]); - LLVector3 body_al(0.f, body_vector[1], body_vector[2]); - - if (fabs(body_az.normalize()) > 0.001) - azimuth = angle_between(DUE_EAST, body_az); - else - azimuth = 0.0f; - - if (fabs(body_al.normalize()) > 0.001) - altitude = angle_between(DUE_EAST, body_al); - else - altitude = 0.0f; - } -} - -//========================================================================= -LLSettingsVOSky::LLSettingsVOSky(const LLSD &data): - LLSettingsSky(data) -{ -} - -LLSettingsVOSky::LLSettingsVOSky(): - LLSettingsSky() -{ -} - -void LLSettingsVOSky::applySpecial(void *ptarget) -{ - LLGLSLShader *shader = (LLGLSLShader *)ptarget; - - shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, getClampedLightDirection().mV); - - shader->uniform4f(LLShaderMgr::GAMMA, getGamma(), 0.0, 0.0, 1.0); - - { - LLVector4 vect_c_p_d1(mSettings[SETTING_CLOUD_POS_DENSITY1]); - vect_c_p_d1 += LLVector4(LLEnvironment::instance().getCloudScrollDelta()); - shader->uniform4fv(LLShaderMgr::CLOUD_POS_DENSITY1, 1, vect_c_p_d1.mV); - } -} - diff --git a/indra/newview/llsettingssky.h b/indra/newview/llsettingssky.h deleted file mode 100644 index 3f564d2605..0000000000 --- a/indra/newview/llsettingssky.h +++ /dev/null @@ -1,463 +0,0 @@ -/** -* @file llsettingssky.h -* @author optional -* @brief A base class for asset based settings groups. -* -* $LicenseInfo:2011&license=viewerlgpl$ -* Second Life Viewer Source Code -* Copyright (C) 2017, 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$ -*/ - -#ifndef LL_SETTINGS_SKY_H -#define LL_SETTINGS_SKY_H - -#include "llsettingsbase.h" - -class LLSettingsSky: public LLSettingsBase -{ -public: - static const std::string SETTING_AMBIENT; - static const std::string SETTING_BLOOM_TEXTUREID; - static const std::string SETTING_BLUE_DENSITY; - static const std::string SETTING_BLUE_HORIZON; - static const std::string SETTING_CLOUD_COLOR; - static const std::string SETTING_CLOUD_POS_DENSITY1; - static const std::string SETTING_CLOUD_POS_DENSITY2; - static const std::string SETTING_CLOUD_SCALE; - static const std::string SETTING_CLOUD_SCROLL_RATE; - static const std::string SETTING_CLOUD_SHADOW; - static const std::string SETTING_CLOUD_TEXTUREID; - static const std::string SETTING_DENSITY_MULTIPLIER; - static const std::string SETTING_DISTANCE_MULTIPLIER; - static const std::string SETTING_DOME_OFFSET; - static const std::string SETTING_DOME_RADIUS; - static const std::string SETTING_GAMMA; - static const std::string SETTING_GLOW; - static const std::string SETTING_HAZE_DENSITY; - static const std::string SETTING_HAZE_HORIZON; - static const std::string SETTING_LIGHT_NORMAL; - static const std::string SETTING_MAX_Y; - static const std::string SETTING_MOON_ROTATION; - static const std::string SETTING_MOON_TEXTUREID; - static const std::string SETTING_STAR_BRIGHTNESS; - static const std::string SETTING_SUNLIGHT_COLOR; - static const std::string SETTING_SUN_ROTATION; - static const std::string SETTING_SUN_TEXUTUREID; - - typedef boost::shared_ptr ptr_t; - typedef std::pair azimalt_t; - - //--------------------------------------------------------------------- - LLSettingsSky(const LLSD &data); - virtual ~LLSettingsSky() { }; - - static ptr_t buildFromLegacyPreset(const std::string &name, const LLSD &oldsettings); - static ptr_t buildDefaultSky(); - ptr_t buildClone(); - - //--------------------------------------------------------------------- - virtual std::string getSettingType() const { return std::string("sky"); } - - // Settings status - virtual void blend(const LLSettingsBase::ptr_t &end, F32 blendf); - - static LLSD defaults(); - - //--------------------------------------------------------------------- - LLColor3 getAmbientColor() const - { - return LLColor3(mSettings[SETTING_AMBIENT]); - } - - void setAmbientColor(const LLColor3 &val) - { - setValue(SETTING_AMBIENT, val); - } - - LLUUID getBloomTextureId() const - { - return mSettings[SETTING_BLOOM_TEXTUREID].asUUID(); - } - - LLColor3 getBlueDensity() const - { - return LLColor3(mSettings[SETTING_BLUE_DENSITY]); - } - - void setBlueDensity(const LLColor3 &val) - { - setValue(SETTING_BLUE_DENSITY, val); - } - - LLColor3 getBlueHorizon() const - { - return LLColor3(mSettings[SETTING_BLUE_HORIZON]); - } - - void setBlueHorizon(const LLColor3 &val) - { - setValue(SETTING_BLUE_HORIZON, val); - } - - LLColor3 getCloudColor() const - { - return LLColor3(mSettings[SETTING_CLOUD_COLOR]); - } - - void setCloudColor(const LLColor3 &val) - { - setValue(SETTING_CLOUD_COLOR, val); - } - - LLUUID getCloudNoiseTextureId() const - { - return mSettings[SETTING_CLOUD_TEXTUREID].asUUID(); - } - - LLColor3 getCloudPosDensity1() const - { - return LLColor3(mSettings[SETTING_CLOUD_POS_DENSITY1]); - } - - void setCloudPosDensity1(const LLColor3 &val) - { - setValue(SETTING_CLOUD_POS_DENSITY1, val); - } - - LLColor3 getCloudPosDensity2() const - { - return LLColor3(mSettings[SETTING_CLOUD_POS_DENSITY2]); - } - - void setCloudPosDensity2(const LLColor3 &val) - { - setValue(SETTING_CLOUD_POS_DENSITY2, val); - } - - F32 getCloudScale() const - { - return mSettings[SETTING_CLOUD_SCALE].asReal(); - } - - void setCloudScale(F32 val) - { - setValue(SETTING_CLOUD_SCALE, val); - } - - LLVector2 getCloudScrollRate() const - { - return LLVector2(mSettings[SETTING_CLOUD_SCROLL_RATE]); - } - - void setCloudScrollRate(const LLVector2 &val) - { - setValue(SETTING_CLOUD_SCROLL_RATE, val); - } - - void setCloudScrollRateX(F32 val) - { - mSettings[SETTING_CLOUD_SCROLL_RATE][0] = val; - setDirtyFlag(true); - } - - void setCloudScrollRateY(F32 val) - { - mSettings[SETTING_CLOUD_SCROLL_RATE][1] = val; - setDirtyFlag(true); - } - - F32 getCloudShadow() const - { - return mSettings[SETTING_CLOUD_SHADOW].asReal(); - } - - void setCloudShadow(F32 val) - { - setValue(SETTING_CLOUD_SHADOW, val); - } - - F32 getDensityMultiplier() const - { - return mSettings[SETTING_DENSITY_MULTIPLIER].asReal(); - } - - void setDensityMultiplier(F32 val) - { - setValue(SETTING_DENSITY_MULTIPLIER, val); - } - - F32 getDistanceMultiplier() const - { - return mSettings[SETTING_DISTANCE_MULTIPLIER].asReal(); - } - - void setDistanceMultiplier(F32 val) - { - setValue(SETTING_DISTANCE_MULTIPLIER, val); - } - - F32 getDomeOffset() const - { - return DOME_OFFSET; - //return mSettings[SETTING_DOME_OFFSET].asReal(); - } - - F32 getDomeRadius() const - { - return DOME_RADIUS; - //return mSettings[SETTING_DOME_RADIUS].asReal(); - } - - F32 getGamma() const - { - return mSettings[SETTING_GAMMA].asReal(); - } - - void setGamma(F32 val) - { - mSettings[SETTING_GAMMA] = LLSD::Real(val); - setDirtyFlag(true); - } - - LLColor3 getGlow() const - { - return LLColor3(mSettings[SETTING_GLOW]); - } - - void setGlow(const LLColor3 &val) - { - setValue(SETTING_GLOW, val); - } - - F32 getHazeDensity() const - { - return mSettings[SETTING_HAZE_DENSITY].asReal(); - } - - void setHazeDensity(F32 val) - { - setValue(SETTING_HAZE_DENSITY, val); - } - - F32 getHazeHorizon() const - { - return mSettings[SETTING_HAZE_HORIZON].asReal(); - } - - void setHazeHorizon(F32 val) - { - setValue(SETTING_HAZE_HORIZON, val); - } - - LLVector3 getLightNormal() const - { - return LLVector3(mSettings[SETTING_LIGHT_NORMAL]); - } - - void setLightNormal(const LLVector3 &val) - { - setValue(SETTING_LIGHT_NORMAL, val); - } - - F32 getMaxY() const - { - return mSettings[SETTING_MAX_Y].asReal(); - } - - LLQuaternion getMoonRotation() const - { - return LLQuaternion(mSettings[SETTING_MOON_ROTATION]); - } - - void setMoonRotation(const LLQuaternion &val) - { - setValue(SETTING_MOON_ROTATION, val); - } - - azimalt_t getMoonRotationAzAl() const; - - void setMoonRotation(F32 azimuth, F32 altitude); - - void setMoonRotation(const azimalt_t &azialt) - { - setMoonRotation(azialt.first, azialt.second); - } - - LLUUID getMoonTextureId() const - { - return mSettings[SETTING_MOON_TEXTUREID].asUUID(); - } - - F32 getStarBrightness() const - { - return mSettings[SETTING_STAR_BRIGHTNESS].asReal(); - } - - void setStarBrightness(F32 val) - { - setValue(SETTING_STAR_BRIGHTNESS, val); - } - - LLColor3 getSunlightColor() const - { - return LLColor3(mSettings[SETTING_SUNLIGHT_COLOR]); - } - - void setSunlightColor(const LLColor3 &val) - { - setValue(SETTING_SUNLIGHT_COLOR, val); - } - - LLQuaternion getSunRotation() const - { - return LLQuaternion(mSettings[SETTING_SUN_ROTATION]); - } - - azimalt_t getSunRotationAzAl() const; - - void setSunRotation(const LLQuaternion &val) - { - setValue(SETTING_SUN_ROTATION, val); - } - - void setSunRotation(F32 azimuth, F32 altitude); - - void setSunRotation(const azimalt_t & azimalt) - { - setSunRotation(azimalt.first, azimalt.second); - } - - LLUUID getSunTextureId() const - { - return mSettings[SETTING_SUN_TEXUTUREID].asUUID(); - } - - // Internal/calculated settings - LLVector3 getLightDirection() const - { - update(); - return mLightDirection; - }; - - LLVector3 getClampedLightDirection() const - { - update(); - return mClampedLightDirection; - }; - - LLVector3 getSunDirection() const - { - update(); - return mSunDirection; - } - - LLVector3 getMoonDirection() const - { - update(); - return mMoonDirection; - } - - LLColor4U getFadeColor() const - { - update(); - return mFadeColor; - } - - LLColor4 getMoonAmbient() const - { - update(); - return mMoonAmbient; - } - - LLColor3 getMoonDiffuse() const - { - update(); - return mMoonDiffuse; - } - - LLColor4 getSunAmbient() const - { - update(); - return mSunAmbient; - } - - LLColor3 getSunDiffuse() const - { - update(); - return mSunDiffuse; - } - - LLColor4 getTotalAmbient() const - { - update(); - return mTotalAmbient; - } - -protected: - LLSettingsSky(); - - virtual stringset_t getSlerpKeys() const; - - virtual validation_list_t getValidationList() const; - - virtual void updateSettings(); - - virtual parammapping_t getParameterMap() const; - -private: - static const std::string SETTING_LEGACY_EAST_ANGLE; - static const std::string SETTING_LEGACY_ENABLE_CLOUD_SCROLL; - static const std::string SETTING_LEGACY_SUN_ANGLE; - - void calculateHeavnlyBodyPositions(); - void calculateLightSettings(); - - LLVector3 mSunDirection; - LLVector3 mMoonDirection; - LLVector3 mLightDirection; - LLVector3 mClampedLightDirection; - - static const F32 DOME_RADIUS; - static const F32 DOME_OFFSET; - - LLColor4U mFadeColor; - LLColor4 mMoonAmbient; - LLColor3 mMoonDiffuse; - LLColor4 mSunAmbient; - LLColor3 mSunDiffuse; - - LLColor4 mTotalAmbient; - - typedef std::map mapNameToUniformId_t; - - static mapNameToUniformId_t sNameToUniformMapping; -}; - -class LLSettingsVOSky : public LLSettingsSky -{ -public: - LLSettingsVOSky(const LLSD &data); -protected: - LLSettingsVOSky(); - - virtual void applySpecial(void *); -}; - -#endif diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp new file mode 100644 index 0000000000..76a6754573 --- /dev/null +++ b/indra/newview/llsettingsvo.cpp @@ -0,0 +1,420 @@ +/** +* @file llsettingsvo.cpp +* @author Rider Linden +* @brief Subclasses for viewer specific settings behaviors. +* +* $LicenseInfo:2011&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2017, 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 "llviewerprecompiledheaders.h" +#include "llviewercontrol.h" +#include "llsettingsvo.h" + +#include "pipeline.h" + +#include +#include +#include "lltrace.h" +#include "llfasttimer.h" +#include "v3colorutil.h" + +#include "llglslshader.h" +#include "llviewershadermgr.h" + +#include "llenvironment.h" +#include "llsky.h" + +//========================================================================= +LLSettingsVOSky::LLSettingsVOSky(const LLSD &data): + LLSettingsSky(data) +{ +} + +LLSettingsVOSky::LLSettingsVOSky(): + LLSettingsSky() +{ +} + +//------------------------------------------------------------------------- +LLSettingsSky::ptr_t LLSettingsVOSky::buildFromLegacyPreset(const std::string &name, const LLSD &legacy) +{ + + LLSD newsettings = LLSettingsSky::translateLegacySettings(legacy); + + newsettings[SETTING_NAME] = name; + + LLSettingsSky::ptr_t skyp = boost::make_shared(newsettings); + + if (skyp->validate()) + return skyp; + + return LLSettingsSky::ptr_t(); +} + +LLSettingsSky::ptr_t LLSettingsVOSky::buildDefaultSky() +{ + LLSD settings = LLSettingsSky::defaults(); + settings[SETTING_NAME] = std::string("_default_"); + + + LLSettingsSky::ptr_t skyp = boost::make_shared(settings); + if (skyp->validate()) + return skyp; + + return LLSettingsSky::ptr_t(); +} + +LLSettingsSky::ptr_t LLSettingsVOSky::buildClone() +{ + LLSD settings = cloneSettings(); + + LLSettingsSky::ptr_t skyp = boost::make_shared(settings); + + if (skyp->validate()) + return skyp; + + return LLSettingsSky::ptr_t(); +} + +//------------------------------------------------------------------------- +void LLSettingsVOSky::updateSettings() +{ + LLSettingsSky::updateSettings(); + + LLVector3 sun_direction = getSunDirection(); + LLVector3 moon_direction = getMoonDirection(); + + // set direction (in CRF) and don't allow overriding + LLVector3 crf_sunDirection(sun_direction.mV[2], sun_direction.mV[0], sun_direction.mV[1]); + LLVector3 crf_moonDirection(moon_direction.mV[2], moon_direction.mV[0], moon_direction.mV[1]); + + gSky.setSunDirection(crf_sunDirection, crf_moonDirection); +} + +void LLSettingsVOSky::applySpecial(void *ptarget) +{ + LLGLSLShader *shader = (LLGLSLShader *)ptarget; + + shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, getClampedLightDirection().mV); + + shader->uniform4f(LLShaderMgr::GAMMA, getGamma(), 0.0, 0.0, 1.0); + + { + LLVector4 vect_c_p_d1(mSettings[SETTING_CLOUD_POS_DENSITY1]); + vect_c_p_d1 += LLVector4(LLEnvironment::instance().getCloudScrollDelta()); + shader->uniform4fv(LLShaderMgr::CLOUD_POS_DENSITY1, 1, vect_c_p_d1.mV); + } +} + +LLSettingsSky::parammapping_t LLSettingsVOSky::getParameterMap() const +{ + static parammapping_t param_map; + + if (param_map.empty()) + { + param_map[SETTING_AMBIENT] = LLShaderMgr::AMBIENT; + param_map[SETTING_BLUE_DENSITY] = LLShaderMgr::BLUE_DENSITY; + param_map[SETTING_BLUE_HORIZON] = LLShaderMgr::BLUE_HORIZON; + param_map[SETTING_CLOUD_COLOR] = LLShaderMgr::CLOUD_COLOR; + + param_map[SETTING_CLOUD_POS_DENSITY2] = LLShaderMgr::CLOUD_POS_DENSITY2; + param_map[SETTING_CLOUD_SCALE] = LLShaderMgr::CLOUD_SCALE; + param_map[SETTING_CLOUD_SHADOW] = LLShaderMgr::CLOUD_SHADOW; + param_map[SETTING_DENSITY_MULTIPLIER] = LLShaderMgr::DENSITY_MULTIPLIER; + param_map[SETTING_DISTANCE_MULTIPLIER] = LLShaderMgr::DISTANCE_MULTIPLIER; + param_map[SETTING_GLOW] = LLShaderMgr::GLOW; + param_map[SETTING_HAZE_DENSITY] = LLShaderMgr::HAZE_DENSITY; + param_map[SETTING_HAZE_HORIZON] = LLShaderMgr::HAZE_HORIZON; + param_map[SETTING_MAX_Y] = LLShaderMgr::MAX_Y; + param_map[SETTING_SUNLIGHT_COLOR] = LLShaderMgr::SUNLIGHT_COLOR; + } + + return param_map; +} + +//========================================================================= +const F32 LLSettingsVOWater::WATER_FOG_LIGHT_CLAMP(0.3f); + +//------------------------------------------------------------------------- +LLSettingsVOWater::LLSettingsVOWater(const LLSD &data) : + LLSettingsWater(data) +{ + +} + +LLSettingsVOWater::LLSettingsVOWater() : + LLSettingsWater() +{ + +} + +//------------------------------------------------------------------------- +LLSettingsWater::ptr_t LLSettingsVOWater::buildFromLegacyPreset(const std::string &name, const LLSD &legacy) +{ + LLSD newsettings(LLSettingsWater::translateLegacySettings(legacy)); + + newsettings[SETTING_NAME] = name; + + LLSettingsWater::ptr_t waterp = boost::make_shared(newsettings); + + if (waterp->validate()) + return waterp; + + return LLSettingsWater::ptr_t(); +} + +LLSettingsWater::ptr_t LLSettingsVOWater::buildDefaultWater() +{ + LLSD settings = LLSettingsWater::defaults(); + settings[SETTING_NAME] = std::string("_default_"); + + LLSettingsWater::ptr_t waterp = boost::make_shared(settings); + + if (waterp->validate()) + return waterp; + + return LLSettingsWater::ptr_t(); +} + +LLSettingsWater::ptr_t LLSettingsVOWater::buildClone() +{ + LLSD settings = cloneSettings(); + + LLSettingsWater::ptr_t waterp = boost::make_shared(settings); + + if (waterp->validate()) + return waterp; + + return LLSettingsWater::ptr_t(); +} + +//------------------------------------------------------------------------- +void LLSettingsVOWater::applySpecial(void *ptarget) +{ + LLGLSLShader *shader = (LLGLSLShader *)ptarget; + + shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, getWaterPlane().mV); + shader->uniform1f(LLShaderMgr::WATER_FOGKS, getWaterFogKS()); + + shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, LLEnvironment::instance().getRotatedLight().mV); + shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV); + shader->uniform1f(LLViewerShaderMgr::DISTANCE_MULTIPLIER, 0); +} + +void LLSettingsVOWater::updateSettings() +{ + // LL_RECORD_BLOCK_TIME(FTM_UPDATE_WATERVALUES); + // LL_INFOS("WINDLIGHT", "WATER", "EEP") << "Water Parameters are dirty. Reticulating Splines..." << LL_ENDL; + + // base class clears dirty flag so as to not trigger recursive update + LLSettingsBase::updateSettings(); + + // only do this if we're dealing with shaders + if (gPipeline.canUseVertexShaders()) + { + //transform water plane to eye space + glh::vec3f norm(0.f, 0.f, 1.f); + glh::vec3f p(0.f, 0.f, LLEnvironment::instance().getWaterHeight() + 0.1f); + + F32 modelView[16]; + for (U32 i = 0; i < 16; i++) + { + modelView[i] = (F32)gGLModelView[i]; + } + + glh::matrix4f mat(modelView); + glh::matrix4f invtrans = mat.inverse().transpose(); + glh::vec3f enorm; + glh::vec3f ep; + invtrans.mult_matrix_vec(norm, enorm); + enorm.normalize(); + mat.mult_matrix_vec(p, ep); + + mWaterPlane = LLVector4(enorm.v[0], enorm.v[1], enorm.v[2], -ep.dot(enorm)); + + LLVector4 light_direction = LLEnvironment::instance().getLightDirection(); + + mWaterFogKS = 1.f / llmax(light_direction.mV[2], WATER_FOG_LIGHT_CLAMP); + } +} + +LLSettingsWater::parammapping_t LLSettingsVOWater::getParameterMap() const +{ + static parammapping_t param_map; + + if (param_map.empty()) + { + param_map[SETTING_FOG_COLOR] = LLShaderMgr::WATER_FOGCOLOR; + param_map[SETTING_FOG_DENSITY] = LLShaderMgr::WATER_FOGDENSITY; + } + return param_map; +} + +//========================================================================= +LLSettingsVODay::LLSettingsVODay(const LLSD &data): + LLSettingsDay(data) +{} + +LLSettingsVODay::LLSettingsVODay(): + LLSettingsDay() +{} + +//------------------------------------------------------------------------- +LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyPreset(const std::string &name, const LLSD &oldsettings) +{ + LLSD newsettings(defaults()); + + newsettings[SETTING_NAME] = name; + newsettings[SETTING_DAYLENGTH] = static_cast(MINIMUM_DAYLENGTH); + + LLSD watertrack = LLSDArray( + LLSDMap(SETTING_KEYKFRAME, LLSD::Real(0.0f)) + (SETTING_KEYNAME, "Default")); + + LLSD skytrack = LLSD::emptyArray(); + + for (LLSD::array_const_iterator it = oldsettings.beginArray(); it != oldsettings.endArray(); ++it) + { + LLSD entry = LLSDMap(SETTING_KEYKFRAME, (*it)[0].asReal()) + (SETTING_KEYNAME, (*it)[1].asString()); + skytrack.append(entry); + } + + newsettings[SETTING_TRACKS] = LLSDArray(watertrack)(skytrack); + + LLSettingsDay::ptr_t dayp = boost::make_shared(newsettings); + + if (dayp->validate()) + { + dayp->initialize(); + return dayp; + } + + return LLSettingsDay::ptr_t(); +} + +LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyMessage(const LLUUID ®ionId, LLSD daycycle, LLSD skydefs, LLSD waterdef) +{ + LLSettingsWater::ptr_t water = LLSettingsVOWater::buildFromLegacyPreset("Region", waterdef); + LLEnvironment::namedSettingMap_t skys; + + for (LLSD::map_iterator itm = skydefs.beginMap(); itm != skydefs.endMap(); ++itm) + { + std::string name = (*itm).first; + LLSettingsSky::ptr_t sky = LLSettingsVOSky::buildFromLegacyPreset(name, (*itm).second); + + skys[name] = sky; + LL_WARNS("WindlightCaps") << "created region sky '" << name << "'" << LL_ENDL; + } + + LLSettingsDay::ptr_t dayp = buildFromLegacyPreset("Region (legacy)", daycycle); + + dayp->setWaterAtKeyframe(water, 0.0f); + + for (LLSD::array_iterator ita = daycycle.beginArray(); ita != daycycle.endArray(); ++ita) + { + F32 frame = (*ita)[0].asReal(); + std::string name = (*ita)[1].asString(); + + LLEnvironment::namedSettingMap_t::iterator it = skys.find(name); + + if (it == skys.end()) + continue; + dayp->setSkyAtKeyframe(boost::static_pointer_cast((*it).second), frame, 1); + + LL_WARNS("WindlightCaps") << "Added '" << name << "' to region day cycle at " << frame << LL_ENDL; + } + + dayp->setInitialized(); + + if (dayp->validate()) + { + return dayp; + } + + return LLSettingsDay::ptr_t(); +} + +LLSettingsDay::ptr_t LLSettingsVODay::buildDefaultDayCycle() +{ + LLSD settings = LLSettingsDay::defaults(); + settings[SETTING_NAME] = std::string("_default_"); + + LLSettingsDay::ptr_t dayp = boost::make_shared(settings); + + if (dayp->validate()) + { + dayp->initialize(); + return dayp; + } + + return LLSettingsDay::ptr_t(); +} + +LLSettingsDay::ptr_t LLSettingsVODay::buildClone() +{ + LLSD settings = cloneSettings(); + + LLSettingsDay::ptr_t dayp = boost::make_shared(settings); + + return dayp; +} + +LLSettingsSkyPtr_t LLSettingsVODay::getDefaultSky() const +{ + return LLSettingsVOSky::buildDefaultSky(); +} + +LLSettingsWaterPtr_t LLSettingsVODay::getDefaultWater() const +{ + return LLSettingsVOWater::buildDefaultWater(); +} + +LLSettingsSkyPtr_t LLSettingsVODay::buildSky(LLSD settings) const +{ + LLSettingsSky::ptr_t skyp = boost::make_shared(settings); + + if (skyp->validate()) + return skyp; + + return LLSettingsSky::ptr_t(); +} + +LLSettingsWaterPtr_t LLSettingsVODay::buildWater(LLSD settings) const +{ + LLSettingsWater::ptr_t waterp = boost::make_shared(settings); + + if (waterp->validate()) + return waterp; + + return LLSettingsWater::ptr_t(); +} + +LLSettingsSkyPtr_t LLSettingsVODay::getNamedSky(const std::string &name) const +{ + return LLEnvironment::instance().findSkyByName(name); +} + +LLSettingsWaterPtr_t LLSettingsVODay::getNamedWater(const std::string &name) const +{ + return LLEnvironment::instance().findWaterByName(name); +} diff --git a/indra/newview/llsettingsvo.h b/indra/newview/llsettingsvo.h new file mode 100644 index 0000000000..6ef7290ba4 --- /dev/null +++ b/indra/newview/llsettingsvo.h @@ -0,0 +1,103 @@ +/** +* @file llsettingsvo.h +* @author Rider Linden +* @brief Subclasses for viewer specific settings behaviors. +* +* $LicenseInfo:2011&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2017, 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$ +*/ + +#ifndef LL_SETTINGS_VO_H +#define LL_SETTINGS_VO_H + +#include "llsettingsbase.h" +#include "llsettingssky.h" +#include "llsettingswater.h" +#include "llsettingsdaycycle.h" + +class LLSettingsVOSky : public LLSettingsSky +{ +public: + LLSettingsVOSky(const LLSD &data); + + static ptr_t buildFromLegacyPreset(const std::string &name, const LLSD &oldsettings); + static ptr_t buildDefaultSky(); + virtual ptr_t buildClone(); + +protected: + LLSettingsVOSky(); + + virtual void updateSettings(); + + virtual void applySpecial(void *); + + virtual parammapping_t getParameterMap() const; + +}; + +//========================================================================= +class LLSettingsVOWater : public LLSettingsWater +{ +public: + LLSettingsVOWater(const LLSD &data); + + static ptr_t buildFromLegacyPreset(const std::string &name, const LLSD &oldsettings); + static ptr_t buildDefaultWater(); + virtual ptr_t buildClone(); + +protected: + LLSettingsVOWater(); + + virtual void updateSettings(); + virtual void applySpecial(void *); + + virtual parammapping_t getParameterMap() const; + + +private: + static const F32 WATER_FOG_LIGHT_CLAMP; + +}; + +//========================================================================= +class LLSettingsVODay : public LLSettingsDay +{ +public: + LLSettingsVODay(const LLSD &data); + + static ptr_t buildFromLegacyPreset(const std::string &name, const LLSD &oldsettings); + static ptr_t buildFromLegacyMessage(const LLUUID ®ionId, LLSD daycycle, LLSD skys, LLSD water); + static ptr_t buildDefaultDayCycle(); + virtual ptr_t buildClone(); + + virtual LLSettingsSkyPtr_t getDefaultSky() const; + virtual LLSettingsWaterPtr_t getDefaultWater() const; + virtual LLSettingsSkyPtr_t buildSky(LLSD) const; + virtual LLSettingsWaterPtr_t buildWater(LLSD) const; + virtual LLSettingsSkyPtr_t getNamedSky(const std::string &) const; + virtual LLSettingsWaterPtr_t getNamedWater(const std::string &) const; + +protected: + LLSettingsVODay(); +}; + + +#endif diff --git a/indra/newview/llsettingswater.cpp b/indra/newview/llsettingswater.cpp deleted file mode 100644 index caf7a4b7cc..0000000000 --- a/indra/newview/llsettingswater.cpp +++ /dev/null @@ -1,340 +0,0 @@ -/** -* @file llsettingswater.h -* @author optional -* @brief A base class for asset based settings groups. -* -* $LicenseInfo:2011&license=viewerlgpl$ -* Second Life Viewer Source Code -* Copyright (C) 2017, 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 "llviewerprecompiledheaders.h" -#include "llviewercontrol.h" -#include "llsettingswater.h" -#include -#include -#include "lltrace.h" -#include "llfasttimer.h" -#include "v3colorutil.h" - -#include "llglslshader.h" -#include "llviewershadermgr.h" - -#include "llenvironment.h" - -#include "llagent.h" -#include "pipeline.h" - -//========================================================================= -namespace -{ - LLTrace::BlockTimerStatHandle FTM_BLEND_WATERVALUES("Blending Water Environment"); - LLTrace::BlockTimerStatHandle FTM_UPDATE_WATERVALUES("Update Water Environment"); -} - -//========================================================================= -const std::string LLSettingsWater::SETTING_BLUR_MULTIPILER("blur_multiplier"); -const std::string LLSettingsWater::SETTING_FOG_COLOR("water_fog_color"); -const std::string LLSettingsWater::SETTING_FOG_DENSITY("water_fog_density"); -const std::string LLSettingsWater::SETTING_FOG_MOD("underwater_fog_mod"); -const std::string LLSettingsWater::SETTING_FRESNEL_OFFSET("fresnel_offset"); -const std::string LLSettingsWater::SETTING_FRESNEL_SCALE("fresnel_scale"); -const std::string LLSettingsWater::SETTING_NORMAL_MAP("normal_map"); -const std::string LLSettingsWater::SETTING_NORMAL_SCALE("normal_scale"); -const std::string LLSettingsWater::SETTING_SCALE_ABOVE("scale_above"); -const std::string LLSettingsWater::SETTING_SCALE_BELOW("scale_below"); -const std::string LLSettingsWater::SETTING_WAVE1_DIR("wave1_direction"); -const std::string LLSettingsWater::SETTING_WAVE2_DIR("wave2_direction"); - -const std::string LLSettingsWater::SETTING_LEGACY_BLUR_MULTIPILER("blurMultiplier"); -const std::string LLSettingsWater::SETTING_LEGACY_FOG_COLOR("waterFogColor"); -const std::string LLSettingsWater::SETTING_LEGACY_FOG_DENSITY("waterFogDensity"); -const std::string LLSettingsWater::SETTING_LEGACY_FOG_MOD("underWaterFogMod"); -const std::string LLSettingsWater::SETTING_LEGACY_FRESNEL_OFFSET("fresnelOffset"); -const std::string LLSettingsWater::SETTING_LEGACY_FRESNEL_SCALE("fresnelScale"); -const std::string LLSettingsWater::SETTING_LEGACY_NORMAL_MAP("normalMap"); -const std::string LLSettingsWater::SETTING_LEGACY_NORMAL_SCALE("normScale"); -const std::string LLSettingsWater::SETTING_LEGACY_SCALE_ABOVE("scaleAbove"); -const std::string LLSettingsWater::SETTING_LEGACY_SCALE_BELOW("scaleBelow"); -const std::string LLSettingsWater::SETTING_LEGACY_WAVE1_DIR("wave1Dir"); -const std::string LLSettingsWater::SETTING_LEGACY_WAVE2_DIR("wave2Dir"); - -const LLUUID LLSettingsWater::DEFAULT_WATER_NORMAL_ID(DEFAULT_WATER_NORMAL); - - -//========================================================================= -LLSettingsWater::LLSettingsWater(const LLSD &data) : - LLSettingsBase(data) -{ -} - -LLSettingsWater::LLSettingsWater() : - LLSettingsBase() -{ -} - -//========================================================================= -LLSD LLSettingsWater::defaults() -{ - LLSD dfltsetting; - - // Magic constants copied form defaults.xml - dfltsetting[SETTING_BLUR_MULTIPILER] = LLSD::Real(0.04000f); - dfltsetting[SETTING_FOG_COLOR] = LLColor3(0.0156f, 0.1490f, 0.2509f).getValue(); - dfltsetting[SETTING_FOG_DENSITY] = LLSD::Real(2.0f); - dfltsetting[SETTING_FOG_MOD] = LLSD::Real(0.25f); - dfltsetting[SETTING_FRESNEL_OFFSET] = LLSD::Real(0.5f); - dfltsetting[SETTING_FRESNEL_SCALE] = LLSD::Real(0.3999); - dfltsetting[SETTING_NORMAL_MAP] = LLSD::UUID(DEFAULT_WATER_NORMAL_ID); - dfltsetting[SETTING_NORMAL_SCALE] = LLVector3(2.0f, 2.0f, 2.0f).getValue(); - dfltsetting[SETTING_SCALE_ABOVE] = LLSD::Real(0.0299f); - dfltsetting[SETTING_SCALE_BELOW] = LLSD::Real(0.2000f); - dfltsetting[SETTING_WAVE1_DIR] = LLVector2(1.04999f, -0.42000f).getValue(); - dfltsetting[SETTING_WAVE2_DIR] = LLVector2(1.10999f, -1.16000f).getValue(); - - return dfltsetting; -} - -LLSettingsWater::ptr_t LLSettingsWater::buildFromLegacyPreset(const std::string &name, const LLSD &oldsettings) -{ - LLSD newsettings(defaults()); - - newsettings[SETTING_NAME] = name; - - - if (oldsettings.has(SETTING_LEGACY_BLUR_MULTIPILER)) - { - newsettings[SETTING_BLUR_MULTIPILER] = LLSD::Real(oldsettings[SETTING_LEGACY_BLUR_MULTIPILER].asReal()); - } - if (oldsettings.has(SETTING_LEGACY_FOG_COLOR)) - { - newsettings[SETTING_FOG_COLOR] = LLColor3(oldsettings[SETTING_LEGACY_FOG_COLOR]).getValue(); - } - if (oldsettings.has(SETTING_LEGACY_FOG_DENSITY)) - { - newsettings[SETTING_FOG_DENSITY] = LLSD::Real(oldsettings[SETTING_LEGACY_FOG_DENSITY]); - } - if (oldsettings.has(SETTING_LEGACY_FOG_MOD)) - { - newsettings[SETTING_FOG_MOD] = LLSD::Real(oldsettings[SETTING_LEGACY_FOG_MOD].asReal()); - } - if (oldsettings.has(SETTING_LEGACY_FRESNEL_OFFSET)) - { - newsettings[SETTING_FRESNEL_OFFSET] = LLSD::Real(oldsettings[SETTING_LEGACY_FRESNEL_OFFSET].asReal()); - } - if (oldsettings.has(SETTING_LEGACY_FRESNEL_SCALE)) - { - newsettings[SETTING_FRESNEL_SCALE] = LLSD::Real(oldsettings[SETTING_LEGACY_FRESNEL_SCALE].asReal()); - } - if (oldsettings.has(SETTING_LEGACY_NORMAL_MAP)) - { - newsettings[SETTING_NORMAL_MAP] = LLSD::UUID(oldsettings[SETTING_LEGACY_NORMAL_MAP].asUUID()); - } - if (oldsettings.has(SETTING_LEGACY_NORMAL_SCALE)) - { - newsettings[SETTING_NORMAL_SCALE] = LLVector3(oldsettings[SETTING_LEGACY_NORMAL_SCALE]).getValue(); - } - if (oldsettings.has(SETTING_LEGACY_SCALE_ABOVE)) - { - newsettings[SETTING_SCALE_ABOVE] = LLSD::Real(oldsettings[SETTING_LEGACY_SCALE_ABOVE].asReal()); - } - if (oldsettings.has(SETTING_LEGACY_SCALE_BELOW)) - { - newsettings[SETTING_SCALE_BELOW] = LLSD::Real(oldsettings[SETTING_LEGACY_SCALE_BELOW].asReal()); - } - if (oldsettings.has(SETTING_LEGACY_WAVE1_DIR)) - { - newsettings[SETTING_WAVE1_DIR] = LLVector2(oldsettings[SETTING_LEGACY_WAVE1_DIR]).getValue(); - } - if (oldsettings.has(SETTING_LEGACY_WAVE2_DIR)) - { - newsettings[SETTING_WAVE2_DIR] = LLVector2(oldsettings[SETTING_LEGACY_WAVE2_DIR]).getValue(); - } - - LLSettingsWater::ptr_t waterp = boost::make_shared(newsettings); - - if (waterp->validate()) - return waterp; - - return LLSettingsWater::ptr_t(); -} - -LLSettingsWater::ptr_t LLSettingsWater::buildDefaultWater() -{ - LLSD settings = LLSettingsWater::defaults(); - - LLSettingsWater::ptr_t waterp = boost::make_shared(settings); - - if (waterp->validate()) - return waterp; - - return LLSettingsWater::ptr_t(); -} - -LLSettingsWater::ptr_t LLSettingsWater::buildClone() -{ - LLSD settings = cloneSettings(); - - LLSettingsWater::ptr_t waterp = boost::make_shared(settings); - - if (waterp->validate()) - return waterp; - - return LLSettingsWater::ptr_t(); -} - -void LLSettingsWater::blend(const LLSettingsBase::ptr_t &end, F32 blendf) -{ - LLSettingsWater::ptr_t other = boost::static_pointer_cast(end); - LLSD blenddata = interpolateSDMap(mSettings, other->mSettings, blendf); - - replaceSettings(blenddata); -} - -LLSettingsWater::validation_list_t LLSettingsWater::getValidationList() const -{ - static validation_list_t validation; - - if (validation.empty()) - { // Note the use of LLSD(LLSDArray()()()...) This is due to an issue with the - // copy constructor for LLSDArray. Directly binding the LLSDArray as - // a parameter without first wrapping it in a pure LLSD object will result - // in deeply nested arrays like this [[[[[[[[[[v1,v2,v3]]]]]]]]]] - - validation.push_back(Validator(SETTING_BLUR_MULTIPILER, true, LLSD::TypeReal, - boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(0.16f))))); - validation.push_back(Validator(SETTING_FOG_COLOR, true, LLSD::TypeArray, - boost::bind(&Validator::verifyVectorMinMax, _1, - LLSD(LLSDArray(0.0f)(0.0f)(0.0f)(1.0f)), - LLSD(LLSDArray(1.0f)(1.0f)(1.0f)(1.0f))))); - validation.push_back(Validator(SETTING_FOG_DENSITY, true, LLSD::TypeReal, - boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(1.0f)(1024.0f))))); - validation.push_back(Validator(SETTING_FOG_MOD, true, LLSD::TypeReal, - boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(1.0f)(1024.0f))))); - validation.push_back(Validator(SETTING_FRESNEL_OFFSET, true, LLSD::TypeReal, - boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f))))); - validation.push_back(Validator(SETTING_FRESNEL_SCALE, true, LLSD::TypeReal, - boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f))))); - validation.push_back(Validator(SETTING_NORMAL_MAP, true, LLSD::TypeUUID)); - validation.push_back(Validator(SETTING_NORMAL_SCALE, true, LLSD::TypeArray, - boost::bind(&Validator::verifyVectorMinMax, _1, - LLSD(LLSDArray(0.0f)(0.0f)(0.0f)), - LLSD(LLSDArray(10.0f)(10.0f)(10.0f))))); - validation.push_back(Validator(SETTING_SCALE_ABOVE, true, LLSD::TypeReal, - boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f))))); - validation.push_back(Validator(SETTING_SCALE_BELOW, true, LLSD::TypeReal, - boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f))))); - validation.push_back(Validator(SETTING_WAVE1_DIR, true, LLSD::TypeArray, - boost::bind(&Validator::verifyVectorMinMax, _1, - LLSD(LLSDArray(-4.0f)(-4.0f)), - LLSD(LLSDArray(4.0f)(4.0f))))); - validation.push_back(Validator(SETTING_WAVE2_DIR, true, LLSD::TypeArray, - boost::bind(&Validator::verifyVectorMinMax, _1, - LLSD(LLSDArray(-4.0f)(-4.0f)), - LLSD(LLSDArray(4.0f)(4.0f))))); - } - - return validation; -} - -//========================================================================= - -LLSettingsWater::parammapping_t LLSettingsWater::getParameterMap() const -{ - static parammapping_t param_map; - - if (param_map.empty()) - { - param_map[SETTING_FOG_COLOR] = LLShaderMgr::WATER_FOGCOLOR; - param_map[SETTING_FOG_DENSITY] = LLShaderMgr::WATER_FOGDENSITY; - - - } - return param_map; -} - -//========================================================================= -const F32 LLSettingsVOWater::WATER_FOG_LIGHT_CLAMP(0.3f); - -//========================================================================= -LLSettingsVOWater::LLSettingsVOWater(const LLSD &data): - LLSettingsWater(data) -{ - -} - -LLSettingsVOWater::LLSettingsVOWater() : - LLSettingsWater() -{ - -} - -void LLSettingsVOWater::applySpecial(void *ptarget) -{ - LLGLSLShader *shader = (LLGLSLShader *)ptarget; - - shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, getWaterPlane().mV); - shader->uniform1f(LLShaderMgr::WATER_FOGKS, getWaterFogKS()); - - shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, LLEnvironment::instance().getRotatedLight().mV); - shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV); - shader->uniform1f(LLViewerShaderMgr::DISTANCE_MULTIPLIER, 0); - - -} - -void LLSettingsVOWater::updateSettings() -{ - // LL_RECORD_BLOCK_TIME(FTM_UPDATE_WATERVALUES); - // LL_INFOS("WINDLIGHT", "WATER", "EEP") << "Water Parameters are dirty. Reticulating Splines..." << LL_ENDL; - - // base class clears dirty flag so as to not trigger recursive update - LLSettingsBase::updateSettings(); - - // only do this if we're dealing with shaders - if (gPipeline.canUseVertexShaders()) - { - //transform water plane to eye space - glh::vec3f norm(0.f, 0.f, 1.f); - glh::vec3f p(0.f, 0.f, LLEnvironment::instance().getWaterHeight() + 0.1f); - - F32 modelView[16]; - for (U32 i = 0; i < 16; i++) - { - modelView[i] = (F32)gGLModelView[i]; - } - - glh::matrix4f mat(modelView); - glh::matrix4f invtrans = mat.inverse().transpose(); - glh::vec3f enorm; - glh::vec3f ep; - invtrans.mult_matrix_vec(norm, enorm); - enorm.normalize(); - mat.mult_matrix_vec(p, ep); - - mWaterPlane = LLVector4(enorm.v[0], enorm.v[1], enorm.v[2], -ep.dot(enorm)); - - LLVector4 light_direction = LLEnvironment::instance().getLightDirection(); - - mWaterFogKS = 1.f / llmax(light_direction.mV[2], WATER_FOG_LIGHT_CLAMP); - } - -} - diff --git a/indra/newview/llsettingswater.h b/indra/newview/llsettingswater.h deleted file mode 100644 index aa60861bd4..0000000000 --- a/indra/newview/llsettingswater.h +++ /dev/null @@ -1,243 +0,0 @@ -/** -* @file llsettingssky.h -* @author optional -* @brief A base class for asset based settings groups. -* -* $LicenseInfo:2011&license=viewerlgpl$ -* Second Life Viewer Source Code -* Copyright (C) 2017, 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$ -*/ - -#ifndef LL_SETTINGS_WATER_H -#define LL_SETTINGS_WATER_H - -#include "llsettingsbase.h" - -class LLSettingsWater : public LLSettingsBase -{ -public: - static const std::string SETTING_BLUR_MULTIPILER; - static const std::string SETTING_FOG_COLOR; - static const std::string SETTING_FOG_DENSITY; - static const std::string SETTING_FOG_MOD; - static const std::string SETTING_FRESNEL_OFFSET; - static const std::string SETTING_FRESNEL_SCALE; - static const std::string SETTING_NORMAL_MAP; - static const std::string SETTING_NORMAL_SCALE; - static const std::string SETTING_SCALE_ABOVE; - static const std::string SETTING_SCALE_BELOW; - static const std::string SETTING_WAVE1_DIR; - static const std::string SETTING_WAVE2_DIR; - - static const LLUUID DEFAULT_WATER_NORMAL_ID; - - typedef boost::shared_ptr ptr_t; - - //--------------------------------------------------------------------- - LLSettingsWater(const LLSD &data); - virtual ~LLSettingsWater() { }; - - static ptr_t buildFromLegacyPreset(const std::string &name, const LLSD &oldsettings); - static ptr_t buildDefaultWater(); - ptr_t buildClone(); - - //--------------------------------------------------------------------- - virtual std::string getSettingType() const { return std::string("water"); } - - // Settings status - virtual void blend(const LLSettingsBase::ptr_t &end, F32 blendf); - - static LLSD defaults(); - - //--------------------------------------------------------------------- - F32 getBlurMultiplier() const - { - return mSettings[SETTING_BLUR_MULTIPILER].asReal(); - } - - void setBlurMultiplier(F32 val) - { - setValue(SETTING_BLUR_MULTIPILER, val); - } - - LLColor3 getFogColor() const - { - return LLColor3(mSettings[SETTING_FOG_COLOR]); - } - - void setFogColor(LLColor3 val) - { - setValue(SETTING_FOG_COLOR, val); - } - - F32 getFogDensity() const - { - return mSettings[SETTING_FOG_DENSITY].asReal(); - } - - void setFogDensity(F32 val) - { - setValue(SETTING_FOG_DENSITY, val); - } - - F32 getFogMod() const - { - return mSettings[SETTING_FOG_MOD].asReal(); - } - - void setFogMod(F32 val) - { - setValue(SETTING_FOG_MOD, val); - } - - F32 getFresnelOffset() const - { - return mSettings[SETTING_FRESNEL_OFFSET].asReal(); - } - - void setFresnelOffset(F32 val) - { - setValue(SETTING_FRESNEL_OFFSET, val); - } - - F32 getFresnelScale() const - { - return mSettings[SETTING_FRESNEL_SCALE].asReal(); - } - - void setFresnelScale(F32 val) - { - setValue(SETTING_FRESNEL_SCALE, val); - } - - LLUUID getNormalMapID() const - { - return mSettings[SETTING_NORMAL_MAP].asUUID(); - } - - void setNormalMapID(LLUUID val) - { - setValue(SETTING_NORMAL_MAP, val); - } - - LLVector3 getNormalScale() const - { - return LLVector3(mSettings[SETTING_NORMAL_SCALE]); - } - - void setNormalScale(LLVector3 val) - { - setValue(SETTING_NORMAL_SCALE, val); - } - - F32 getScaleAbove() const - { - return mSettings[SETTING_SCALE_ABOVE].asReal(); - } - - void setScaleAbove(F32 val) - { - setValue(SETTING_SCALE_ABOVE, val); - } - - F32 getScaleBelow() const - { - return mSettings[SETTING_SCALE_BELOW].asReal(); - } - - void setScaleBelow(F32 val) - { - setValue(SETTING_SCALE_BELOW, val); - } - - LLVector2 getWave1Dir() const - { - return LLVector2(mSettings[SETTING_WAVE1_DIR]); - } - - void setWave1Dir(LLVector2 val) - { - setValue(SETTING_WAVE1_DIR, val); - } - - LLVector2 getWave2Dir() const - { - return LLVector2(mSettings[SETTING_WAVE2_DIR]); - } - - void setWave2Dir(LLVector2 val) - { - setValue(SETTING_WAVE2_DIR, val); - } - - //------------------------------------------- - LLVector4 getWaterPlane() const - { - update(); - return mWaterPlane; - } - - F32 getWaterFogKS() const - { - update(); - return mWaterFogKS; - } - -protected: - LLSettingsWater(); - - virtual parammapping_t getParameterMap() const; - - virtual validation_list_t getValidationList() const; - - LLVector4 mWaterPlane; - F32 mWaterFogKS; -private: - static const std::string SETTING_LEGACY_BLUR_MULTIPILER; - static const std::string SETTING_LEGACY_FOG_COLOR; - static const std::string SETTING_LEGACY_FOG_DENSITY; - static const std::string SETTING_LEGACY_FOG_MOD; - static const std::string SETTING_LEGACY_FRESNEL_OFFSET; - static const std::string SETTING_LEGACY_FRESNEL_SCALE; - static const std::string SETTING_LEGACY_NORMAL_MAP; - static const std::string SETTING_LEGACY_NORMAL_SCALE; - static const std::string SETTING_LEGACY_SCALE_ABOVE; - static const std::string SETTING_LEGACY_SCALE_BELOW; - static const std::string SETTING_LEGACY_WAVE1_DIR; - static const std::string SETTING_LEGACY_WAVE2_DIR; -}; - -class LLSettingsVOWater : public LLSettingsWater -{ -public: - LLSettingsVOWater(const LLSD &data); - -protected: - LLSettingsVOWater(); - - virtual void updateSettings(); - virtual void applySpecial(void *); - -private: - static const F32 WATER_FOG_LIGHT_CLAMP; - -}; - -#endif -- cgit v1.3 From b766466b3013e39831bcfcaef5d1089c07202afb Mon Sep 17 00:00:00 2001 From: Rider Linden Date: Mon, 26 Feb 2018 09:27:14 -0800 Subject: Added settings inventory object with subtype --- indra/llcommon/llassettype.h | 5 +- indra/llcommon/llsdserialize.cpp | 10 + indra/llcommon/llsdserialize.h | 2 +- indra/llinventory/CMakeLists.txt | 1 + indra/llinventory/llinventorysettings.h | 43 +++ indra/llinventory/llsettingsbase.cpp | 23 +- indra/llinventory/llsettingsbase.h | 29 +- indra/llinventory/llsettingsdaycycle.cpp | 1 + indra/llinventory/llsettingsdaycycle.h | 2 + indra/llinventory/llsettingssky.h | 4 +- indra/llinventory/llsettingswater.h | 3 +- indra/llmessage/llassetstorage.cpp | 34 ++- indra/llmessage/llassetstorage.h | 31 ++- indra/newview/llagentwearables.cpp | 11 +- indra/newview/llappearancemgr.cpp | 3 +- indra/newview/llfloatereditextdaycycle.cpp | 66 +++++ indra/newview/llfloatereditextdaycycle.h | 5 + indra/newview/llfloatergesture.cpp | 2 +- indra/newview/llfloaternamedesc.cpp | 4 +- indra/newview/llfriendcard.cpp | 2 +- indra/newview/lllandmarkactions.cpp | 2 +- indra/newview/lloutfitgallery.cpp | 2 +- indra/newview/llpanelsnapshotpostcard.cpp | 6 +- indra/newview/llpreviewgesture.cpp | 10 +- indra/newview/llpreviewnotecard.cpp | 13 +- indra/newview/llpreviewscript.cpp | 14 +- indra/newview/llsettingsvo.cpp | 307 +++++++++++++++++++++ indra/newview/llsettingsvo.h | 57 +++- indra/newview/llviewerassetstorage.h | 6 +- indra/newview/llviewerassetupload.cpp | 6 +- indra/newview/llviewerassetupload.h | 6 +- indra/newview/llviewerinventory.cpp | 35 ++- indra/newview/llviewerinventory.h | 22 +- indra/newview/llviewermenufile.cpp | 10 +- indra/newview/llviewermenufile.h | 2 +- indra/newview/llviewerregion.cpp | 6 +- .../default/xui/en/floater_edit_ext_day_cycle.xml | 16 +- 37 files changed, 705 insertions(+), 96 deletions(-) create mode 100644 indra/llinventory/llinventorysettings.h (limited to 'indra/llcommon') diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h index 3a660496e3..32502d5e33 100644 --- a/indra/llcommon/llassettype.h +++ b/indra/llcommon/llassettype.h @@ -124,10 +124,11 @@ public: AT_RESERVED_3 = 52, AT_RESERVED_4 = 53, AT_RESERVED_5 = 54, + AT_RESERVED_6 = 55, - AT_SETTINGS = 55, // Collection of settings + AT_SETTINGS = 56, // Collection of settings - AT_COUNT = 56, + AT_COUNT = 57, // +*********************************************************+ // | TO ADD AN ELEMENT TO THIS ENUM: | diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp index 3a219eb998..f6ba64f0a9 100644 --- a/indra/llcommon/llsdserialize.cpp +++ b/indra/llcommon/llsdserialize.cpp @@ -54,6 +54,7 @@ static const int MAX_HDR_LEN = 20; static const char LEGACY_NON_HEADER[] = ""; const std::string LLSD_BINARY_HEADER("LLSD/Binary"); const std::string LLSD_XML_HEADER("LLSD/XML"); +const std::string LLSD_NOTATION_HEADER("llsd/notation"); //used to deflate a gzipped asset (currently used for navmeshes) #define windowBits 15 @@ -80,6 +81,11 @@ void LLSDSerialize::serialize(const LLSD& sd, std::ostream& str, ELLSD_Serialize f = new LLSDXMLFormatter; break; + case LLSD_NOTATION: + str << "\n"; + f = new LLSDNotationFormatter; + break; + default: LL_WARNS() << "serialize request for unknown ELLSD_Serialize" << LL_ENDL; } @@ -167,6 +173,10 @@ bool LLSDSerialize::deserialize(LLSD& sd, std::istream& str, S32 max_bytes) { p = new LLSDXMLParser; } + else if (header == LLSD_NOTATION_HEADER) + { + p = new LLSDNotationParser; + } else { LL_WARNS() << "deserialize request for unknown ELLSD_Serialize" << LL_ENDL; diff --git a/indra/llcommon/llsdserialize.h b/indra/llcommon/llsdserialize.h index 23a0c8cfb1..cdca458e43 100644 --- a/indra/llcommon/llsdserialize.h +++ b/indra/llcommon/llsdserialize.h @@ -694,7 +694,7 @@ class LL_COMMON_API LLSDSerialize public: enum ELLSD_Serialize { - LLSD_BINARY, LLSD_XML + LLSD_BINARY, LLSD_XML, LLSD_NOTATION }; /** diff --git a/indra/llinventory/CMakeLists.txt b/indra/llinventory/CMakeLists.txt index 3eba746614..2d40dd6443 100644 --- a/indra/llinventory/CMakeLists.txt +++ b/indra/llinventory/CMakeLists.txt @@ -45,6 +45,7 @@ set(llinventory_HEADER_FILES llfoldertype.h llinventory.h llinventorydefines.h + llinventorysettings.h llinventorytype.h lllandmark.h llnotecard.h diff --git a/indra/llinventory/llinventorysettings.h b/indra/llinventory/llinventorysettings.h new file mode 100644 index 0000000000..0d15542fec --- /dev/null +++ b/indra/llinventory/llinventorysettings.h @@ -0,0 +1,43 @@ +/** +* @file llinventorysettings.h +* @author optional +* @brief A base class for asset based settings groups. +* +* $LicenseInfo:2011&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2017, 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$ +*/ + +#ifndef LL_INVENTORY_SETTINGS_H +#define LL_INVENTORY_SETTINGS_H + + +enum class LLSettingsType +{ + ST_SKY = 0, + ST_WATER = 1, + ST_DAYCYCLE = 2, + + ST_INVALID = 255, + ST_NONE = -1 +}; + + +#endif diff --git a/indra/llinventory/llsettingsbase.cpp b/indra/llinventory/llsettingsbase.cpp index 7ade345168..3382716577 100644 --- a/indra/llinventory/llsettingsbase.cpp +++ b/indra/llinventory/llsettingsbase.cpp @@ -38,6 +38,14 @@ namespace const F64 BREAK_POINT = 0.5; } +//========================================================================= +std::ostream &::operator <<(std::ostream& os, LLSettingsBase &settings) +{ + LLSDSerialize::serialize(settings.getSettings(), os, LLSDSerialize::LLSD_NOTATION); + + return os; +} + //========================================================================= const std::string LLSettingsBase::SETTING_ID("id"); const std::string LLSettingsBase::SETTING_NAME("name"); @@ -49,13 +57,15 @@ const F64Seconds LLSettingsBlender::DEFAULT_THRESHOLD(0.01); //========================================================================= LLSettingsBase::LLSettingsBase(): mSettings(LLSD::emptyMap()), - mDirty(true) + mDirty(true), + mAssetID() { } LLSettingsBase::LLSettingsBase(const LLSD setting) : mSettings(setting), - mDirty(true) + mDirty(true), + mAssetID() { } @@ -368,8 +378,14 @@ bool LLSettingsBase::Validator::verify(LLSD &data) { if (!data.has(mName) || (data.has(mName) && data[mName].isUndefined())) { + if (!mDefault.isUndefined()) + { + LL_INFOS("SETTINGS") << "Inserting missing default for '" << mName << "'." << LL_ENDL; + data[mName] = mDefault; + return true; + } if (mRequired) - LL_WARNS("SETTINGS") << "Missing required setting '" << mName << "'" << LL_ENDL; + LL_WARNS("SETTINGS") << "Missing required setting '" << mName << "' with no default." << LL_ENDL; return !mRequired; } @@ -514,7 +530,6 @@ bool LLSettingsBase::Validator::verifyIntegerRange(LLSD &value, LLSD range) } //========================================================================= - void LLSettingsBlender::update(F64Seconds timedelta) { mTimeSpent += timedelta; diff --git a/indra/llinventory/llsettingsbase.h b/indra/llinventory/llsettingsbase.h index 420bcb9943..c7ed9e9e21 100644 --- a/indra/llinventory/llsettingsbase.h +++ b/indra/llinventory/llsettingsbase.h @@ -42,6 +42,8 @@ #include "v4color.h" #include "v3color.h" +#include "llinventorysettings.h" + class LLSettingsBase : public std::enable_shared_from_this, private boost::noncopyable @@ -49,6 +51,8 @@ class LLSettingsBase : friend class LLEnvironment; friend class LLSettingsDay; + friend std::ostream &operator <<(std::ostream& os, LLSettingsBase &settings); + public: static const std::string SETTING_ID; static const std::string SETTING_NAME; @@ -64,6 +68,8 @@ public: //--------------------------------------------------------------------- virtual std::string getSettingType() const = 0; + virtual LLSettingsType getSettingTypeValue() const = 0; + //--------------------------------------------------------------------- // Settings status inline bool hasSetting(const std::string ¶m) const { return mSettings.has(param); } @@ -143,27 +149,28 @@ public: // Note this method is marked const but may modify the settings object. // (note the internal const cast). This is so that it may be called without // special consideration from getters. - inline void update() const + inline void update() const { if (!mDirty) return; (const_cast(this))->updateSettings(); } - virtual void blend(const ptr_t &end, F64 blendf) = 0; + virtual void blend(const ptr_t &end, F64 blendf) = 0; - virtual bool validate(); + virtual bool validate(); class Validator { public: typedef boost::function verify_pr; - Validator(std::string name, bool required, LLSD::Type type, verify_pr verify = verify_pr()) : + Validator(std::string name, bool required, LLSD::Type type, verify_pr verify = verify_pr(), LLSD defval = LLSD()) : mName(name), mRequired(required), mType(type), - mVerify(verify) + mVerify(verify), + mDefault(defval) { } std::string getName() const { return mName; } @@ -187,6 +194,7 @@ public: bool mRequired; LLSD::Type mType; verify_pr mVerify; + LLSD mDefault; }; typedef std::vector validation_list_t; @@ -223,15 +231,16 @@ protected: virtual parammapping_t getParameterMap() const { return parammapping_t(); } - LLSD mSettings; - bool mIsValid; + LLSD mSettings; + bool mIsValid; + LLAssetID mAssetID; - LLSD cloneSettings() const; + LLSD cloneSettings() const; private: - bool mDirty; + bool mDirty; - LLSD combineSDMaps(const LLSD &first, const LLSD &other) const; + LLSD combineSDMaps(const LLSD &first, const LLSD &other) const; }; diff --git a/indra/llinventory/llsettingsdaycycle.cpp b/indra/llinventory/llsettingsdaycycle.cpp index a689dd3710..18add703cb 100644 --- a/indra/llinventory/llsettingsdaycycle.cpp +++ b/indra/llinventory/llsettingsdaycycle.cpp @@ -273,6 +273,7 @@ LLSD LLSettingsDay::defaults() (LLSDMap(SETTING_KEYKFRAME, LLSD::Real(0.0f))(SETTING_KEYNAME, "_default_"))); dfltsetting[SETTING_FRAMES] = LLSD::emptyMap(); + dfltsetting[SETTING_TYPE] = "daycycle"; return dfltsetting; } diff --git a/indra/llinventory/llsettingsdaycycle.h b/indra/llinventory/llsettingsdaycycle.h index 4c7ce011a1..7703f7a0b4 100644 --- a/indra/llinventory/llsettingsdaycycle.h +++ b/indra/llinventory/llsettingsdaycycle.h @@ -72,6 +72,8 @@ public: virtual ptr_t buildClone() = 0; virtual LLSD getSettings() const; + virtual LLSettingsType getSettingTypeValue() const override { return LLSettingsType::ST_DAYCYCLE; } + //--------------------------------------------------------------------- virtual std::string getSettingType() const { return std::string("daycycle"); } diff --git a/indra/llinventory/llsettingssky.h b/indra/llinventory/llsettingssky.h index e9ffbdb32c..23daf0c5dc 100644 --- a/indra/llinventory/llsettingssky.h +++ b/indra/llinventory/llsettingssky.h @@ -72,7 +72,9 @@ public: virtual ptr_t buildClone() = 0; //--------------------------------------------------------------------- - virtual std::string getSettingType() const { return std::string("sky"); } + virtual std::string getSettingType() const override { return std::string("sky"); } + virtual LLSettingsType getSettingTypeValue() const override { return LLSettingsType::ST_SKY; } + // Settings status virtual void blend(const LLSettingsBase::ptr_t &end, F64 blendf); diff --git a/indra/llinventory/llsettingswater.h b/indra/llinventory/llsettingswater.h index 4d206a1be0..16d5b2353a 100644 --- a/indra/llinventory/llsettingswater.h +++ b/indra/llinventory/llsettingswater.h @@ -57,7 +57,8 @@ public: virtual ptr_t buildClone() = 0; //--------------------------------------------------------------------- - virtual std::string getSettingType() const { return std::string("water"); } + virtual std::string getSettingType() const override { return std::string("water"); } + virtual LLSettingsType getSettingTypeValue() const override { return LLSettingsType::ST_WATER; } // Settings status virtual void blend(const LLSettingsBase::ptr_t &end, F64 blendf); diff --git a/indra/llmessage/llassetstorage.cpp b/indra/llmessage/llassetstorage.cpp index 596d57c7b7..3d93f5aeb8 100644 --- a/indra/llmessage/llassetstorage.cpp +++ b/indra/llmessage/llassetstorage.cpp @@ -62,6 +62,24 @@ const LLUUID CATEGORIZE_LOST_AND_FOUND_ID(std::string("00000000-0000-0000-0000-0 const U64 TOXIC_ASSET_LIFETIME = (120 * 1000000); // microseconds +namespace +{ + template + bool operator == (const std::function &a, const std::function &b) + { + typedef T(fnType)(U...); + + auto fnPtrA = a.target(); + auto fnPtrB = b.target(); + if (fnPtrA && fnPtrB) + return (*fnPtrA == *fnPtrB); + else if (!fnPtrA && !fnPtrB) + return true; + return false; + } + +} + ///---------------------------------------------------------------------------- /// LLAssetInfo ///---------------------------------------------------------------------------- @@ -160,7 +178,7 @@ void LLAssetInfo::setFromNameValue( const LLNameValue& nv ) LLBaseDownloadRequest::LLBaseDownloadRequest(const LLUUID &uuid, const LLAssetType::EType type) : mUUID(uuid), mType(type), - mDownCallback(NULL), + mDownCallback(), mUserData(NULL), mHost(), mIsTemp(FALSE), @@ -191,7 +209,7 @@ LLBaseDownloadRequest* LLBaseDownloadRequest::getCopy() LLAssetRequest::LLAssetRequest(const LLUUID &uuid, const LLAssetType::EType type) : LLBaseDownloadRequest(uuid, type), - mUpCallback( NULL ), + mUpCallback(), mInfoCallback( NULL ), mIsLocal(FALSE), mIsUserWaiting(FALSE), @@ -496,7 +514,11 @@ void LLAssetStorage::getAssetData(const LLUUID uuid, BOOL exists = mVFS->getExists(uuid, type); LLVFile file(mVFS, uuid, type); U32 size = exists ? file.getSize() : 0; - + +// LAPRAS TESTING +// if (type == LLAssetType::AT_SETTINGS) +// size = 0; + if (size > 0) { // we've already got the file @@ -1326,9 +1348,13 @@ void LLAssetStorage::getAssetData(const LLUUID uuid, iter != mPendingDownloads.end(); ) { LLAssetRequest* tmp = *iter++; + + //void(*const* cbptr)(LLVFS *, const LLUUID &, LLAssetType::EType, void *, S32, LLExtStat) + auto cbptr = tmp->mDownCallback.target(); + if (type == tmp->getType() && uuid == tmp->getUUID() && - legacyGetDataCallback == tmp->mDownCallback && + (cbptr && (*cbptr == legacyGetDataCallback)) && callback == ((LLLegacyAssetRequest *)tmp->mUserData)->mDownCallback && user_data == ((LLLegacyAssetRequest *)tmp->mUserData)->mUserData) { diff --git a/indra/llmessage/llassetstorage.h b/indra/llmessage/llassetstorage.h index 33b88473b9..c799d8eefc 100644 --- a/indra/llmessage/llassetstorage.h +++ b/indra/llmessage/llassetstorage.h @@ -28,6 +28,7 @@ #ifndef LL_LLASSETSTORAGE_H #define LL_LLASSETSTORAGE_H #include +#include #include "lluuid.h" #include "lltimer.h" @@ -59,6 +60,14 @@ const int LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE = -4; const int LL_ERR_INSUFFICIENT_PERMISSIONS = -5; const int LL_ERR_PRICE_MISMATCH = -23018; +// *TODO: these typedefs are passed into the VFS via a legacy C function pointer +// future project would be to convert these to C++ callables (std::function<>) so that +// we can use bind and remove the userData parameter. +// +typedef std::function LLGetAssetCallback; +typedef std::function LLStoreAssetCallback; + + class LLAssetInfo { protected: @@ -110,7 +119,8 @@ protected: LLAssetType::EType mType; public: - void(*mDownCallback)(LLVFS*, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat); + LLGetAssetCallback mDownCallback; +// void(*mDownCallback)(LLVFS*, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat); void *mUserData; LLHost mHost; @@ -131,7 +141,8 @@ public: virtual LLBaseDownloadRequest* getCopy(); - void (*mUpCallback)(const LLUUID&, void *, S32, LLExtStat); + LLStoreAssetCallback mUpCallback; +// void (*mUpCallback)(const LLUUID&, void *, S32, LLExtStat); void (*mInfoCallback)(LLAssetInfo *, void *, S32); BOOL mIsLocal; @@ -182,12 +193,7 @@ protected: // Map of known bad assets typedef std::map toxic_asset_map_t; -// *TODO: these typedefs are passed into the VFS via a legacy C function pointer -// future project would be to convert these to C++ callables (std::function<>) so that -// we can use bind and remove the userData parameter. -// -typedef void (*LLGetAssetCallback)(LLVFS *vfs, const LLUUID &asset_id, - LLAssetType::EType asset_type, void *user_data, S32 status, LLExtStat ext_status); + class LLAssetStorage { @@ -195,7 +201,8 @@ public: // VFS member is public because static child methods need it :( LLVFS *mVFS; LLVFS *mStaticVFS; - typedef void (*LLStoreAssetCallback)(const LLUUID &asset_id, void *user_data, S32 status, LLExtStat ext_status); + typedef ::LLStoreAssetCallback LLStoreAssetCallback; + typedef ::LLGetAssetCallback LLGetAssetCallback; enum ERequestType { @@ -377,8 +384,8 @@ protected: void _cleanupRequests(BOOL all, S32 error); void _callUploadCallbacks(const LLUUID &uuid, const LLAssetType::EType asset_type, BOOL success, LLExtStat ext_status); - virtual void _queueDataRequest(const LLUUID& uuid, LLAssetType::EType type, - void (*callback)(LLVFS *vfs, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat), + virtual void _queueDataRequest(const LLUUID& uuid, LLAssetType::EType type, LLGetAssetCallback callback, +// void (*callback)(LLVFS *vfs, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat), void *user_data, BOOL duplicate, BOOL is_priority) = 0; @@ -424,7 +431,7 @@ class LLLegacyAssetRequest { public: void (*mDownCallback)(const char *, const LLUUID&, void *, S32, LLExtStat); - LLAssetStorage::LLStoreAssetCallback mUpCallback; + LLStoreAssetCallback mUpCallback; void *mUserData; }; diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 170e4063a1..2b865a1ae2 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -799,14 +799,13 @@ void LLAgentWearables::createStandardWearables() ((OnWearableItemCreatedCB*)(&(*cb)))->addPendingWearable(wearable); // no need to update here... LLUUID category_id = LLUUID::null; - create_inventory_item(gAgent.getID(), + create_inventory_wearable(gAgent.getID(), gAgent.getSessionID(), category_id, wearable->getTransactionID(), wearable->getName(), wearable->getDescription(), wearable->getAssetType(), - LLInventoryType::IT_WEARABLE, wearable->getType(), wearable->getPermissions().getMaskNextOwner(), cb); @@ -868,14 +867,13 @@ void LLAgentWearables::addWearableToAgentInventory(LLPointergetTransactionID(), wearable->getName(), wearable->getDescription(), wearable->getAssetType(), - LLInventoryType::IT_WEARABLE, wearable->getType(), wearable->getPermissions().getMaskNextOwner(), cb); @@ -1540,7 +1538,6 @@ void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, con LLViewerWearable* wearable = LLWearableList::instance().createNewWearable(type, gAgentAvatarp); LLAssetType::EType asset_type = wearable->getAssetType(); - LLInventoryType::EType inv_type = LLInventoryType::IT_WEARABLE; LLPointer cb; if(wear) { @@ -1563,13 +1560,13 @@ void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, con folder_id = gInventory.findCategoryUUIDForType(folder_type); } - create_inventory_item(gAgent.getID(), + create_inventory_wearable(gAgent.getID(), gAgent.getSessionID(), folder_id, wearable->getTransactionID(), wearable->getName(), wearable->getDescription(), - asset_type, inv_type, + asset_type, wearable->getType(), LLFloaterPerms::getNextOwnerPerms("Wearables"), cb); diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 0fb811a386..534f3c7eb7 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -1026,14 +1026,13 @@ void LLWearableHoldingPattern::recoverMissingWearable(LLWearableType::EType type const LLUUID lost_and_found_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND); LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(recovered_item_cb,_1,type,wearable,this)); - create_inventory_item(gAgent.getID(), + create_inventory_wearable(gAgent.getID(), gAgent.getSessionID(), lost_and_found_id, wearable->getTransactionID(), wearable->getName(), wearable->getDescription(), wearable->getAssetType(), - LLInventoryType::IT_WEARABLE, wearable->getType(), wearable->getPermissions().getMaskNextOwner(), cb); diff --git a/indra/newview/llfloatereditextdaycycle.cpp b/indra/newview/llfloatereditextdaycycle.cpp index 0beb856456..c1063218fb 100644 --- a/indra/newview/llfloatereditextdaycycle.cpp +++ b/indra/newview/llfloatereditextdaycycle.cpp @@ -39,6 +39,8 @@ #include "llspinctrl.h" #include "lltimectrl.h" +#include "llsettingsvo.h" + // newview #include "llagent.h" #include "llregioninfomodel.h" @@ -73,12 +75,14 @@ BOOL LLFloaterEditExtDayCycle::postBuild() // mTimeCtrl = getChild("time"); mSaveButton = getChild("save_btn"); mCancelButton = getChild("cancel_btn"); + mUploadButton = getChild("upload_btn"); // mMakeDefaultCheckBox = getChild("make_default_cb"); mDayPresetsCombo->setCommitCallback(boost::bind(&LLFloaterEditExtDayCycle::onDayPresetChanged, this)); mSaveButton->setCommitCallback(boost::bind(&LLFloaterEditExtDayCycle::onBtnSave, this)); mCancelButton->setCommitCallback(boost::bind(&LLFloaterEditExtDayCycle::onBtnCancel, this)); + mUploadButton->setCommitCallback(boost::bind(&LLFloaterEditExtDayCycle::onUpload, this)); //initCallbacks(); @@ -90,6 +94,9 @@ BOOL LLFloaterEditExtDayCycle::postBuild() void LLFloaterEditExtDayCycle::onOpen(const LLSD& key) { + LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT); + LLEnvironment::instance().updateEnvironment(); + refreshSkyPresetsList(); } @@ -103,6 +110,65 @@ void LLFloaterEditExtDayCycle::onClose(bool app_quitting) } } + +void LLFloaterEditExtDayCycle::onUpload() +{ + LLSettingsVOBase::createInventoryItem( mEditDay ); + +#if 0 + LLSettingsVOBase::storeAsAsset(mEditDay); + + LLTransactionID tid; + tid.generate(); + LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); + + const std::string filename = asset_id_to_filename(mAssetID, LL_PATH_CACHE); + if (!exportFile(filename)) + { + std::string buffer = llformat("Unable to save '%s' to wearable file.", mName.c_str()); + LL_WARNS() << buffer << LL_ENDL; + + LLSD args; + args["NAME"] = mName; + LLNotificationsUtil::add("CannotSaveWearableOutOfSpace", args); + return; + } + + if (gSavedSettings.getBOOL("LogWearableAssetSave")) + { + const std::string log_filename = asset_id_to_filename(mAssetID, LL_PATH_LOGS); + exportFile(log_filename); + } + + // save it out to database + if (gAssetStorage) + { + /* + std::string url = gAgent.getRegion()->getCapability("NewAgentInventory"); + if (!url.empty()) + { + LL_INFOS() << "Update Agent Inventory via capability" << LL_ENDL; + LLSD body; + body["folder_id"] = gInventory.findCategoryUUIDForType(LLFolderType::assetToFolderType(getAssetType())); + body["asset_type"] = LLAssetType::lookup(getAssetType()); + body["inventory_type"] = LLInventoryType::lookup(LLInventoryType::IT_WEARABLE); + body["name"] = getName(); + body["description"] = getDescription(); + LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, filename)); + } + else + { + } + */ + LLWearableSaveData* data = new LLWearableSaveData; + data->mType = mType; + gAssetStorage->storeAssetData(filename, mTransactionID, getAssetType(), + &LLViewerWearable::onSaveNewAssetComplete, + (void*)data); + } +#endif +} + void LLFloaterEditExtDayCycle::onVisibilityChange(BOOL new_visibility) { if (new_visibility) diff --git a/indra/newview/llfloatereditextdaycycle.h b/indra/newview/llfloatereditextdaycycle.h index 8b5a087edb..18d0ce2259 100644 --- a/indra/newview/llfloatereditextdaycycle.h +++ b/indra/newview/llfloatereditextdaycycle.h @@ -54,6 +54,10 @@ public: void onOpen(const LLSD& key); void onClose(bool app_quitting); + + /*TEMP*/ + void onUpload(); + void onVisibilityChange(BOOL new_visibility); // /*virtual*/ void draw(); @@ -123,6 +127,7 @@ private: LLComboBox* mDayPresetsCombo; LLButton* mSaveButton; LLButton* mCancelButton; + LLButton* mUploadButton; edit_commit_signal_t mCommitSignal; diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp index b840d37c4d..57c010502e 100644 --- a/indra/newview/llfloatergesture.cpp +++ b/indra/newview/llfloatergesture.cpp @@ -470,7 +470,7 @@ void LLFloaterGesture::onClickNew() "", LLAssetType::AT_GESTURE, LLInventoryType::IT_GESTURE, - NOT_WEARABLE, + NO_INV_SUBTYPE, PERM_MOVE | LLFloaterPerms::getNextOwnerPerms("Gestures"), cb); } diff --git a/indra/newview/llfloaternamedesc.cpp b/indra/newview/llfloaternamedesc.cpp index c9a689281e..7cde061515 100644 --- a/indra/newview/llfloaternamedesc.cpp +++ b/indra/newview/llfloaternamedesc.cpp @@ -161,7 +161,7 @@ void LLFloaterNameDesc::onBtnOK( ) { getChildView("ok_btn")->setEnabled(FALSE); // don't allow inadvertent extra uploads - LLAssetStorage::LLStoreAssetCallback callback = NULL; + LLAssetStorage::LLStoreAssetCallback callback; S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass). if (can_afford_transaction(expected_upload_cost)) @@ -169,7 +169,7 @@ void LLFloaterNameDesc::onBtnOK( ) void *nruserdata = NULL; std::string display_name = LLStringUtil::null; - LLResourceUploadInfo::ptr_t uploadInfo(new LLNewFileResourceUploadInfo( + LLResourceUploadInfo::ptr_t uploadInfo(std::make_shared( mFilenameAndPath, getChild("name_form")->getValue().asString(), getChild("description_form")->getValue().asString(), 0, diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp index 62cbea6401..0be748ace9 100644 --- a/indra/newview/llfriendcard.cpp +++ b/indra/newview/llfriendcard.cpp @@ -504,7 +504,7 @@ void LLFriendCardsManager::syncFriendsFolder() gAgentID.asString(), LLAssetType::AT_CALLINGCARD, LLInventoryType::IT_CALLINGCARD, - NOT_WEARABLE, + NO_INV_SUBTYPE, PERM_MOVE | PERM_TRANSFER, NULL); } diff --git a/indra/newview/lllandmarkactions.cpp b/indra/newview/lllandmarkactions.cpp index 9c00243f44..c243f8b4f0 100644 --- a/indra/newview/lllandmarkactions.cpp +++ b/indra/newview/lllandmarkactions.cpp @@ -272,7 +272,7 @@ void LLLandmarkActions::createLandmarkHere( name, desc, LLAssetType::AT_LANDMARK, LLInventoryType::IT_LANDMARK, - NOT_WEARABLE, PERM_ALL, + NO_INV_SUBTYPE, PERM_ALL, NULL); } diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp index c38d3ab140..4df05ea408 100644 --- a/indra/newview/lloutfitgallery.cpp +++ b/indra/newview/lloutfitgallery.cpp @@ -1219,7 +1219,7 @@ void LLOutfitGallery::uploadPhoto(LLUUID outfit_id) checkRemovePhoto(outfit_id); std::string upload_pending_name = outfit_id.asString(); std::string upload_pending_desc = ""; - LLAssetStorage::LLStoreAssetCallback callback = NULL; + LLAssetStorage::LLStoreAssetCallback callback; LLUUID photo_id = upload_new_resource(filename, // file upload_pending_name, upload_pending_desc, diff --git a/indra/newview/llpanelsnapshotpostcard.cpp b/indra/newview/llpanelsnapshotpostcard.cpp index f3a4cf36ee..b8aa976657 100644 --- a/indra/newview/llpanelsnapshotpostcard.cpp +++ b/indra/newview/llpanelsnapshotpostcard.cpp @@ -170,14 +170,16 @@ void LLPanelSnapshotPostcard::sendPostcard() std::string url = gAgent.getRegion()->getCapability("SendPostcard"); if (!url.empty()) { - LLResourceUploadInfo::ptr_t uploadInfo(new LLPostcardUploadInfo( + LLResourceUploadInfo::ptr_t uploadInfo(std::make_shared( getChild("name_form")->getValue().asString(), getChild("to_form")->getValue().asString(), getChild("subject_form")->getValue().asString(), getChild("msg_form")->getValue().asString(), mSnapshotFloater->getPosTakenGlobal(), mSnapshotFloater->getImageData(), - boost::bind(&LLPanelSnapshotPostcard::sendPostcardFinished, _4))); + [](LLUUID, LLUUID, LLUUID, LLSD response) { + LLPanelSnapshotPostcard::sendPostcardFinished(response); + })); LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo); } diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index 787bd68e58..70ce275734 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -1091,7 +1091,7 @@ void LLPreviewGesture::saveIfNeeded() const LLViewerRegion* region = gAgent.getRegion(); if (!region) { - LL_WARNS() << "Not connected to a region, cannot save notecard." << LL_ENDL; + LL_WARNS() << "Not connected to a region, cannot save gesture." << LL_ENDL; return; } std::string agent_url = region->getCapability("UpdateGestureAgentInventory"); @@ -1111,13 +1111,15 @@ void LLPreviewGesture::saveIfNeeded() refresh(); item->setComplete(true); - uploadInfo = LLResourceUploadInfo::ptr_t(new LLBufferedAssetUploadInfo(mItemUUID, LLAssetType::AT_GESTURE, buffer, - boost::bind(&LLPreviewGesture::finishInventoryUpload, _1, _2))); + uploadInfo = std::make_shared(mItemUUID, LLAssetType::AT_GESTURE, buffer, + [](LLUUID itemId, LLUUID newAssetId, LLUUID, LLSD) { + LLPreviewGesture::finishInventoryUpload(itemId, newAssetId); + }); url = agent_url; } else if (!mObjectUUID.isNull() && !task_url.empty()) { - uploadInfo = LLResourceUploadInfo::ptr_t(new LLBufferedAssetUploadInfo(mObjectUUID, mItemUUID, LLAssetType::AT_GESTURE, buffer, NULL)); + uploadInfo = std::make_shared(mObjectUUID, mItemUUID, LLAssetType::AT_GESTURE, buffer, nullptr); url = task_url; } diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp index d4a8bbdf45..fec16998d6 100644 --- a/indra/newview/llpreviewnotecard.cpp +++ b/indra/newview/llpreviewnotecard.cpp @@ -508,14 +508,19 @@ bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem) if (mObjectUUID.isNull() && !agent_url.empty()) { - uploadInfo = LLResourceUploadInfo::ptr_t(new LLBufferedAssetUploadInfo(mItemUUID, LLAssetType::AT_NOTECARD, buffer, - boost::bind(&LLPreviewNotecard::finishInventoryUpload, _1, _2, _3))); + uploadInfo = std::make_shared(mItemUUID, LLAssetType::AT_NOTECARD, buffer, + [](LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD) { + LLPreviewNotecard::finishInventoryUpload(itemId, newAssetId, newItemId); + }); url = agent_url; } else if (!mObjectUUID.isNull() && !task_url.empty()) { - uploadInfo = LLResourceUploadInfo::ptr_t(new LLBufferedAssetUploadInfo(mObjectUUID, mItemUUID, LLAssetType::AT_NOTECARD, buffer, - boost::bind(&LLPreviewNotecard::finishTaskUpload, _1, _3, mObjectUUID))); + LLUUID object_uuid(mObjectUUID); + uploadInfo = std::make_shared(mObjectUUID, mItemUUID, LLAssetType::AT_NOTECARD, buffer, + [object_uuid](LLUUID itemId, LLUUID, LLUUID newAssetId, LLSD) { + LLPreviewNotecard::finishTaskUpload(itemId, newAssetId, object_uuid); + }); url = task_url; } diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 3795e043ba..72e6ba9609 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -1707,9 +1707,11 @@ void LLPreviewLSL::saveIfNeeded(bool sync /*= true*/) if (!url.empty()) { std::string buffer(mScriptEd->mEditor->getText()); - LLBufferedAssetUploadInfo::invnUploadFinish_f proc = boost::bind(&LLPreviewLSL::finishedLSLUpload, _1, _4); - LLResourceUploadInfo::ptr_t uploadInfo(new LLScriptAssetUpload(mItemUUID, buffer, proc)); + LLResourceUploadInfo::ptr_t uploadInfo(std::make_shared(mItemUUID, buffer, + [](LLUUID itemId, LLUUID, LLUUID, LLSD response) { + LLPreviewLSL::finishedLSLUpload(itemId, response); + })); LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo); } @@ -2241,11 +2243,13 @@ void LLLiveLSLEditor::saveIfNeeded(bool sync /*= true*/) if (!url.empty()) { std::string buffer(mScriptEd->mEditor->getText()); - LLBufferedAssetUploadInfo::taskUploadFinish_f proc = boost::bind(&LLLiveLSLEditor::finishLSLUpload, _1, _2, _3, _4, isRunning); - LLResourceUploadInfo::ptr_t uploadInfo(new LLScriptAssetUpload(mObjectUUID, mItemUUID, + LLResourceUploadInfo::ptr_t uploadInfo(std::make_shared(mObjectUUID, mItemUUID, monoChecked() ? LLScriptAssetUpload::MONO : LLScriptAssetUpload::LSL2, - isRunning, mScriptEd->getAssociatedExperience(), buffer, proc)); + isRunning, mScriptEd->getAssociatedExperience(), buffer, + [isRunning](LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response) { + LLLiveLSLEditor::finishLSLUpload(itemId, taskId, newAssetId, response, isRunning); + })); LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo); } diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp index 6b1c663357..aa3adfb8dd 100644 --- a/indra/newview/llsettingsvo.cpp +++ b/indra/newview/llsettingsvo.cpp @@ -32,6 +32,7 @@ #include "pipeline.h" #include +#include #include #include "lltrace.h" #include "llfasttimer.h" @@ -40,9 +41,21 @@ #include "llglslshader.h" #include "llviewershadermgr.h" +#include "llagent.h" +#include "llassettype.h" +#include "llnotificationsutil.h" + +#include "llviewerregion.h" +#include "llviewerassetupload.h" +#include "llviewerinventory.h" + #include "llenvironment.h" #include "llsky.h" +#include "llpermissions.h" + +#include "llinventorymodel.h" + #undef VERIFY_LEGACY_CONVERSION //========================================================================= @@ -66,7 +79,257 @@ LLSD ensureArray4(LLSD in, F32 fill) } return out; } + + +//------------------------------------------------------------------------- +class LLSettingsInventoryCB : public LLInventoryCallback +{ +public: + typedef std::function callback_t; + + LLSettingsInventoryCB(callback_t cbfn) : + mCbfn(cbfn) + { } + + void fire(const LLUUID& inv_item) override { if (mCbfn) mCbfn(inv_item); } + +private: + callback_t mCbfn; +}; + +} + + +//========================================================================= +#if 0 +void LLSettingsVOBase::storeAsAsset(const LLSettingsBase::ptr_t &settings) +{ + LLTransactionID tid; + tid.generate(); + + LLAssetID aid(tid.makeAssetID(gAgent.getSecureSessionID())); + + const std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, aid.asString()) + ".setting"; + + if (!exportFile(settings, filename)) + { + LL_WARNS("SETTINGS") << "Unable to save settings file named '" << filename << "'." << LL_ENDL; + + LLSD args; + args["NAME"] = aid.asString() + "setting"; + LLNotificationsUtil::add("CannotSaveWearableOutOfSpace", args); + return; + } + + SettingsSaveData::ptr_t psave = std::make_shared(); + psave->mType = settings->getSettingType(); + psave->mSettings = settings; + psave->mTempFile = filename; + psave->mTransId = tid; + + gAssetStorage->storeAssetData(filename, tid, LLAssetType::AT_SETTINGS, + [psave](const LLUUID &assetId, void *, S32 status, LLExtStat extstat) { + onSaveNewAssetComplete(assetId, psave, status, extstat); + }, + nullptr); + +} + +void testingOnGotAsset(LLVFS *vfs, const LLUUID &asset_id, LLAssetType::EType asset_type, void *user_data, S32 status, LLExtStat ext_status) +{ + LL_WARNS("SETTINGS") << "Got back stored setting with id '" << asset_id << "' status is " << status << ":" << ext_status << LL_ENDL; +} + + +void LLSettingsVOBase::onSaveNewAssetComplete(const LLUUID& new_asset_id, const LLSettingsVOBase::SettingsSaveData::ptr_t &savedata, + S32 status, LLExtStat ext_status) +{ + if (!status) + { + // Success + LL_INFOS("SETTINGS") << "Saved setting of type '" << savedata->mType << "' as " << new_asset_id << LL_ENDL; + } + else + { + LL_WARNS("SETTINGS") << "Unable to save '" << savedata->mType << "' to central asset store." << LL_ENDL; + LLSD args; + args["NAME"] = savedata->mType; + LLNotificationsUtil::add("CannotSaveToAssetStore", args); + } + + gAssetStorage->getAssetData(new_asset_id, LLAssetType::AT_SETTINGS, &testingOnGotAsset, nullptr); + + std::remove(savedata->mTempFile.c_str()); +} +#endif + + +void LLSettingsVOBase::createInventoryItem(const LLSettingsBase::ptr_t &settings) +{ + LLTransactionID tid; + LLUUID parentFolder = gInventory.findCategoryUUIDForType(LLFolderType::FT_OBJECT); + U32 nextOwnerPerm = LLPermissions::DEFAULT.getMaskNextOwner(); + + tid.generate(); + + LLPointer cb = new LLSettingsInventoryCB([settings](const LLUUID &inventoryId) { + LLSettingsVOBase::onInventoryItemCreated(inventoryId, settings); + }); + + create_inventory_settings(gAgent.getID(), gAgent.getSessionID(), + parentFolder, tid, + settings->getName(), "new settings collection.", + settings->getSettingTypeValue(), nextOwnerPerm, cb); +} + +void LLSettingsVOBase::onInventoryItemCreated(const LLUUID &inventoryId, LLSettingsBase::ptr_t settings) +{ + // We need to update some inventory stuff here.... maybe. + uploadSettingsAsset(settings, inventoryId); +} + + +void LLSettingsVOBase::uploadSettingsAsset(const LLSettingsBase::ptr_t &settings, LLUUID inv_item_id) +{ + const LLViewerRegion* region = gAgent.getRegion(); + if (!region) + { + LL_WARNS("SETTINGS") << "Not connected to a region, cannot save setting." << LL_ENDL; + return; + } + + std::string agent_url(region->getCapability("UpdateSettingsAgentInventory")); + + if (agent_url.empty()) + { + LL_WARNS("SETTINGS") << "Region does not support settings inventory objects." << LL_ENDL; + return; + } + + std::stringstream buffer; + LLSD settingdata(settings->getSettings()); + LLSDSerialize::serialize(settingdata, buffer, LLSDSerialize::LLSD_NOTATION); + + LLResourceUploadInfo::ptr_t uploadInfo = std::make_shared(inv_item_id, LLAssetType::AT_SETTINGS, buffer.str(), + [settings](LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD response) { + LLSettingsVOBase::onAgentAssetUploadComplete(itemId, newAssetId, newItemId, response, settings); + }); + + LLViewerAssetUpload::EnqueueInventoryUpload(agent_url, uploadInfo); +} + +void LLSettingsVOBase::uploadSettingsAsset(const LLSettingsBase::ptr_t &settings, LLUUID object_id, LLUUID inv_item_id) +{ + const LLViewerRegion* region = gAgent.getRegion(); + if (!region) + { + LL_WARNS("SETTINGS") << "Not connected to a region, cannot save setting." << LL_ENDL; + return; + } + + std::string agent_url(region->getCapability("UpdateSettingsAgentInventory")); + + if (agent_url.empty()) + { + LL_WARNS("SETTINGS") << "Region does not support settings inventory objects." << LL_ENDL; + return; + } + + std::stringstream buffer; + LLSD settingdata(settings->getSettings()); + LLSDSerialize::serialize(settingdata, buffer, LLSDSerialize::LLSD_NOTATION); + + LLResourceUploadInfo::ptr_t uploadInfo = std::make_shared(object_id, inv_item_id, LLAssetType::AT_SETTINGS, buffer.str(), + [settings](LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response) { + LLSettingsVOBase::onTaskAssetUploadComplete(itemId, taskId, newAssetId, response, settings); + }); + + LLViewerAssetUpload::EnqueueInventoryUpload(agent_url, uploadInfo); +} + +void LLSettingsVOBase::onAgentAssetUploadComplete(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD response, LLSettingsBase::ptr_t psettings) +{ + LL_WARNS("SETTINGS") << "Upload to inventory complete!" << LL_ENDL; +} + +void LLSettingsVOBase::onTaskAssetUploadComplete(LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response, LLSettingsBase::ptr_t psettings) +{ + LL_WARNS("SETTINGS") << "Upload to task complete!" << LL_ENDL; +} + +bool LLSettingsVOBase::exportFile(const LLSettingsBase::ptr_t &settings, const std::string &filename, LLSDSerialize::ELLSD_Serialize format) +{ + try + { + std::ofstream file(filename, std::ios::out | std::ios::trunc); + file.exceptions(std::ios_base::failbit | std::ios_base::badbit); + + if (!file) + { + LL_WARNS("SETTINGS") << "Unable to open '" << filename << "' for writing." << LL_ENDL; + return false; + } + + LLSDSerialize::serialize(settings->getSettings(), file, format); + } + catch (const std::ios_base::failure &e) + { + LL_WARNS("SETTINGS") << "Unable to save settings to file '" << filename << "': " << e.what() << LL_ENDL; + return false; + } + + return true; +} + +LLSettingsBase::ptr_t LLSettingsVOBase::importFile(const std::string &filename) +{ + LLSD settings; + + try + { + std::ifstream file(filename, std::ios::in); + file.exceptions(std::ios_base::failbit | std::ios_base::badbit); + + if (!file) + { + LL_WARNS("SETTINGS") << "Unable to open '" << filename << "' for reading." << LL_ENDL; + return LLSettingsBase::ptr_t(); + } + + if (!LLSDSerialize::deserialize(settings, file, -1)) + { + LL_WARNS("SETTINGS") << "Unable to deserialize settings from '" << filename << "'" << LL_ENDL; + return LLSettingsBase::ptr_t(); + } + } + catch (const std::ios_base::failure &e) + { + LL_WARNS("SETTINGS") << "Unable to save settings to file '" << filename << "': " << e.what() << LL_ENDL; + return false; + } + + std::string settingtype = settings[SETTING_NAME].asString(); + + LLSettingsBase::ptr_t psetting; + + if (settingtype == "water") + { + return LLSettingsVOWater::buildWater(settings); + } + else if (settingtype == "sky") + { + return LLSettingsVOSky::buildSky(settings); + } + else if (settingtype == "daycycle") + { + return LLSettingsVODay::buildDay(settings); + } + + LL_WARNS("SETTINGS") << "Unable to determine settings type for '" << filename << "'." << LL_ENDL; + return LLSettingsBase::ptr_t(); } + + //========================================================================= LLSettingsVOSky::LLSettingsVOSky(const LLSD &data): LLSettingsSky(data) @@ -79,6 +342,20 @@ LLSettingsVOSky::LLSettingsVOSky(): } //------------------------------------------------------------------------- +LLSettingsSky::ptr_t LLSettingsVOSky::buildSky(LLSD settings) +{ + LLSettingsSky::validation_list_t validations = LLSettingsSky::validationList(); + LLSD results = LLSettingsSky::settingValidation(settings, validations); + if (!results["success"].asBoolean()) + { + LL_WARNS("SETTINGS") << "Sky setting validation failed!\n" << results << LL_ENDL; + LLSettingsSky::ptr_t(); + } + + return std::make_shared(settings); +} + + LLSettingsSky::ptr_t LLSettingsVOSky::buildFromLegacyPreset(const std::string &name, const LLSD &legacy) { @@ -253,6 +530,19 @@ LLSettingsVOWater::LLSettingsVOWater() : } +LLSettingsWater::ptr_t LLSettingsVOWater::buildWater(LLSD settings) +{ + LLSettingsWater::validation_list_t validations = LLSettingsWater::validationList(); + LLSD results = LLSettingsWater::settingValidation(settings, validations); + if (!results["success"].asBoolean()) + { + LL_WARNS("SETTINGS") << "Water setting validation failed!\n" << results << LL_ENDL; + LLSettingsWater::ptr_t(); + } + + return std::make_shared(settings); +} + //------------------------------------------------------------------------- LLSettingsWater::ptr_t LLSettingsVOWater::buildFromLegacyPreset(const std::string &name, const LLSD &legacy) { @@ -410,6 +700,23 @@ LLSettingsVODay::LLSettingsVODay(): LLSettingsDay() {} +LLSettingsDay::ptr_t LLSettingsVODay::buildDay(LLSD settings) +{ + LLSettingsDay::validation_list_t validations = LLSettingsDay::validationList(); + LLSD results = LLSettingsDay::settingValidation(settings, validations); + if (!results["success"].asBoolean()) + { + LL_WARNS("SETTINGS") << "Day setting validation failed!\n" << results << LL_ENDL; + LLSettingsDay::ptr_t(); + } + + LLSettingsDay::ptr_t pday = std::make_shared(settings); + if (pday) + pday->initialize(); + + return pday; +} + //------------------------------------------------------------------------- LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyPreset(const std::string &name, const LLSD &oldsettings) { diff --git a/indra/newview/llsettingsvo.h b/indra/newview/llsettingsvo.h index ba96a19d3e..55e04b5f3a 100644 --- a/indra/newview/llsettingsvo.h +++ b/indra/newview/llsettingsvo.h @@ -33,11 +33,56 @@ #include "llsettingswater.h" #include "llsettingsdaycycle.h" +#include "llsdserialize.h" + +#include "llextendedstatus.h" + +//========================================================================= +class LLSettingsVOBase : public LLSettingsBase +{ +public: +#if 0 + static void storeAsAsset(const LLSettingsBase::ptr_t &settings); +#endif + + static void createInventoryItem(const LLSettingsBase::ptr_t &settings); + + static void uploadSettingsAsset(const LLSettingsBase::ptr_t &settings, LLUUID inv_item_id); + static void uploadSettingsAsset(const LLSettingsBase::ptr_t &settings, LLUUID object_id, LLUUID inv_item_id); + + + static bool exportFile(const LLSettingsBase::ptr_t &settings, const std::string &filename, LLSDSerialize::ELLSD_Serialize format = LLSDSerialize::LLSD_NOTATION); + static LLSettingsBase::ptr_t importFile(const std::string &filename); + +private: + struct SettingsSaveData + { + typedef std::shared_ptr ptr_t; + std::string mType; + std::string mTempFile; + LLSettingsBase::ptr_t mSettings; + LLTransactionID mTransId; + }; + + LLSettingsVOBase() {} + + static void onInventoryItemCreated(const LLUUID &inventoryId, LLSettingsBase::ptr_t settings); + +#if 0 + static void onSaveNewAssetComplete(const LLUUID& new_asset_id, const SettingsSaveData::ptr_t &savedata, S32 status, LLExtStat ext_status); +#endif + static void onAgentAssetUploadComplete(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD response, LLSettingsBase::ptr_t psettings); + static void onTaskAssetUploadComplete(LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response, LLSettingsBase::ptr_t psettings); +}; + +//========================================================================= class LLSettingsVOSky : public LLSettingsSky { public: LLSettingsVOSky(const LLSD &data); + static ptr_t buildSky(LLSD settings); + static ptr_t buildFromLegacyPreset(const std::string &name, const LLSD &oldsettings); static ptr_t buildDefaultSky(); virtual ptr_t buildClone(); @@ -46,9 +91,9 @@ public: protected: LLSettingsVOSky(); - virtual void updateSettings(); + virtual void updateSettings(); - virtual void applySpecial(void *); + virtual void applySpecial(void *); virtual parammapping_t getParameterMap() const; @@ -60,6 +105,8 @@ class LLSettingsVOWater : public LLSettingsWater public: LLSettingsVOWater(const LLSD &data); + static ptr_t buildWater(LLSD settings); + static ptr_t buildFromLegacyPreset(const std::string &name, const LLSD &oldsettings); static ptr_t buildDefaultWater(); virtual ptr_t buildClone(); @@ -68,8 +115,8 @@ public: protected: LLSettingsVOWater(); - virtual void updateSettings(); - virtual void applySpecial(void *); + virtual void updateSettings(); + virtual void applySpecial(void *); virtual parammapping_t getParameterMap() const; @@ -85,6 +132,8 @@ class LLSettingsVODay : public LLSettingsDay public: LLSettingsVODay(const LLSD &data); + static ptr_t buildDay(LLSD settings); + static ptr_t buildFromLegacyPreset(const std::string &name, const LLSD &oldsettings); static ptr_t buildFromLegacyMessage(const LLUUID ®ionId, LLSD daycycle, LLSD skys, LLSD water); static ptr_t buildDefaultDayCycle(); diff --git a/indra/newview/llviewerassetstorage.h b/indra/newview/llviewerassetstorage.h index 50131682e7..cefe215431 100644 --- a/indra/newview/llviewerassetstorage.h +++ b/indra/newview/llviewerassetstorage.h @@ -69,14 +69,14 @@ protected: // virtual void _queueDataRequest(const LLUUID& uuid, LLAssetType::EType type, - void (*callback) (LLVFS *vfs, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat), + LLGetAssetCallback callback, void *user_data, BOOL duplicate, BOOL is_priority); void queueRequestHttp(const LLUUID& uuid, LLAssetType::EType type, - void (*callback) (LLVFS *vfs, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat), + LLGetAssetCallback callback, void *user_data, BOOL duplicate, BOOL is_priority); @@ -86,7 +86,7 @@ protected: void assetRequestCoro(LLViewerAssetRequest *req, const LLUUID uuid, LLAssetType::EType atype, - void (*callback) (LLVFS *vfs, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat), + LLGetAssetCallback callback, void *user_data); std::string getAssetURL(const std::string& cap_url, const LLUUID& uuid, LLAssetType::EType atype); diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp index 01b4fcfbe1..fcb1bd40c7 100644 --- a/indra/newview/llviewerassetupload.cpp +++ b/indra/newview/llviewerassetupload.cpp @@ -482,7 +482,7 @@ LLBufferedAssetUploadInfo::LLBufferedAssetUploadInfo(LLUUID itemId, LLAssetType: mTaskId(LLUUID::null), mContents(buffer), mInvnFinishFn(finish), - mTaskFinishFn(NULL), + mTaskFinishFn(nullptr), mStoredToVFS(false) { setItemId(itemId); @@ -496,7 +496,7 @@ LLBufferedAssetUploadInfo::LLBufferedAssetUploadInfo(LLUUID itemId, LLPointer ptr_t; + typedef std::shared_ptr ptr_t; LLResourceUploadInfo( LLTransactionID transactId, @@ -165,8 +165,8 @@ private: class LLBufferedAssetUploadInfo : public LLResourceUploadInfo { public: - typedef boost::function invnUploadFinish_f; - typedef boost::function taskUploadFinish_f; + typedef std::function invnUploadFinish_f; + typedef std::function taskUploadFinish_f; LLBufferedAssetUploadInfo(LLUUID itemId, LLAssetType::EType assetType, std::string buffer, invnUploadFinish_f finish); LLBufferedAssetUploadInfo(LLUUID itemId, LLPointer image, invnUploadFinish_f finish); diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 1ab7ec0156..d6f48a4c55 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -1097,7 +1097,7 @@ void create_inventory_item(const LLUUID& agent_id, const LLUUID& session_id, const LLUUID& parent, const LLTransactionID& transaction_id, const std::string& name, const std::string& desc, LLAssetType::EType asset_type, - LLInventoryType::EType inv_type, LLWearableType::EType wtype, + LLInventoryType::EType inv_type, U8 subtype, U32 next_owner_perm, LLPointer cb) { @@ -1132,7 +1132,7 @@ void create_inventory_item(const LLUUID& agent_id, const LLUUID& session_id, msg->addU32Fast(_PREHASH_NextOwnerMask, next_owner_perm); msg->addS8Fast(_PREHASH_Type, (S8)asset_type); msg->addS8Fast(_PREHASH_InvType, (S8)inv_type); - msg->addU8Fast(_PREHASH_WearableType, (U8)wtype); + msg->addU8Fast(_PREHASH_WearableType, (U8)subtype); msg->addStringFast(_PREHASH_Name, server_name); msg->addStringFast(_PREHASH_Description, desc); @@ -1146,9 +1146,36 @@ void create_inventory_callingcard(const LLUUID& avatar_id, const LLUUID& parent LLAvatarNameCache::get(avatar_id, &av_name); create_inventory_item(gAgent.getID(), gAgent.getSessionID(), parent, LLTransactionID::tnull, av_name.getUserName(), item_desc, LLAssetType::AT_CALLINGCARD, - LLInventoryType::IT_CALLINGCARD, NOT_WEARABLE, PERM_MOVE | PERM_TRANSFER, cb); + LLInventoryType::IT_CALLINGCARD, NO_INV_SUBTYPE, PERM_MOVE | PERM_TRANSFER, cb); } +void create_inventory_wearable(const LLUUID& agent_id, const LLUUID& session_id, + const LLUUID& parent, const LLTransactionID& transaction_id, + const std::string& name, + const std::string& desc, LLAssetType::EType asset_type, + LLWearableType::EType wtype, + U32 next_owner_perm, + LLPointer cb) +{ + create_inventory_item(agent_id, session_id, parent, transaction_id, + name, desc, asset_type, LLInventoryType::IT_WEARABLE, static_cast(wtype), + next_owner_perm, cb); +} + +void create_inventory_settings(const LLUUID& agent_id, const LLUUID& session_id, + const LLUUID& parent, const LLTransactionID& transaction_id, + const std::string& name, + const std::string& desc, + LLSettingsType settype, + U32 next_owner_perm, + LLPointer cb) +{ + create_inventory_item(agent_id, session_id, parent, transaction_id, + name, desc, LLAssetType::AT_SETTINGS, LLInventoryType::IT_SETTINGS, + static_cast(settype), next_owner_perm, cb); +} + + void copy_inventory_item( const LLUUID& agent_id, const LLUUID& current_owner, @@ -1700,7 +1727,7 @@ void create_new_item(const std::string& name, desc, asset_type, inv_type, - NOT_WEARABLE, + NO_INV_SUBTYPE, next_owner_perm, cb); } diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h index b3053e365b..b89ed42829 100644 --- a/indra/newview/llviewerinventory.h +++ b/indra/newview/llviewerinventory.h @@ -31,6 +31,7 @@ #include "llframetimer.h" #include "llwearable.h" #include "llinitdestroyclass.h" //for LLDestroyClass +#include "llinventorysettings.h" #include // boost::signals2::trackable @@ -295,7 +296,7 @@ public: // virtual void fire(const LLUUID& item_id) -{ + { mFireFunc(item_id); } @@ -336,17 +337,32 @@ public: extern LLInventoryCallbackManager gInventoryCallbacks; -#define NOT_WEARABLE (LLWearableType::EType)0 +const U8 NO_INV_SUBTYPE{ 0 }; // *TODO: Find a home for these void create_inventory_item(const LLUUID& agent_id, const LLUUID& session_id, const LLUUID& parent, const LLTransactionID& transaction_id, const std::string& name, const std::string& desc, LLAssetType::EType asset_type, - LLInventoryType::EType inv_type, LLWearableType::EType wtype, + LLInventoryType::EType inv_type, U8 subtype, U32 next_owner_perm, LLPointer cb); +void create_inventory_wearable(const LLUUID& agent_id, const LLUUID& session_id, + const LLUUID& parent, const LLTransactionID& transaction_id, + const std::string& name, + const std::string& desc, LLAssetType::EType asset_type, + LLWearableType::EType wtype, + U32 next_owner_perm, + LLPointer cb); + +void create_inventory_settings(const LLUUID& agent_id, const LLUUID& session_id, + const LLUUID& parent, const LLTransactionID& transaction_id, + const std::string& name, const std::string& desc, + LLSettingsType settype, + U32 next_owner_perm, LLPointer cb); + + void create_inventory_callingcard(const LLUUID& avatar_id, const LLUUID& parent = LLUUID::null, LLPointer cb=NULL); /** diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 90355b7166..482de8a722 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -441,7 +441,7 @@ class LLFileUploadBulk : public view_listener_t LLStringUtil::stripNonprintable(asset_name); LLStringUtil::trim(asset_name); - LLResourceUploadInfo::ptr_t uploadInfo(new LLNewFileResourceUploadInfo( + LLResourceUploadInfo::ptr_t uploadInfo(std::make_shared( filename, asset_name, asset_name, 0, @@ -451,7 +451,7 @@ class LLFileUploadBulk : public view_listener_t LLFloaterPerms::getEveryonePerms("Uploads"), expected_upload_cost)); - upload_new_resource(uploadInfo, NULL, NULL); + upload_new_resource(uploadInfo); filename = picker.getNextFile(); } @@ -647,7 +647,7 @@ LLUUID upload_new_resource( void *userdata) { - LLResourceUploadInfo::ptr_t uploadInfo(new LLNewFileResourceUploadInfo( + LLResourceUploadInfo::ptr_t uploadInfo(std::make_shared( src_filename, name, desc, compression_info, destination_folder_type, inv_type, @@ -730,7 +730,7 @@ void upload_done_callback( create_inventory_item(gAgent.getID(), gAgent.getSessionID(), folder_id, data->mAssetInfo.mTransactionID, data->mAssetInfo.getName(), data->mAssetInfo.getDescription(), data->mAssetInfo.mType, - data->mInventoryType, NOT_WEARABLE, next_owner_perms, + data->mInventoryType, NO_INV_SUBTYPE, next_owner_perms, LLPointer(NULL)); } else @@ -766,7 +766,7 @@ void upload_done_callback( LLStringUtil::trim(asset_name); std::string display_name = LLStringUtil::null; - LLAssetStorage::LLStoreAssetCallback callback = NULL; + LLAssetStorage::LLStoreAssetCallback callback; void *userdata = NULL; upload_new_resource( next_file, diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h index 6941b4dc0e..973739d7ac 100644 --- a/indra/newview/llviewermenufile.h +++ b/indra/newview/llviewermenufile.h @@ -59,7 +59,7 @@ LLUUID upload_new_resource( void upload_new_resource( LLResourceUploadInfo::ptr_t &uploadInfo, - LLAssetStorage::LLStoreAssetCallback callback = NULL, + LLAssetStorage::LLStoreAssetCallback callback = LLAssetStorage::LLStoreAssetCallback(), void *userdata = NULL); diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index b272595d79..1520ef7a2f 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -2895,9 +2895,13 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("UpdateGestureTaskInventory"); capabilityNames.append("UpdateNotecardAgentInventory"); capabilityNames.append("UpdateNotecardTaskInventory"); + capabilityNames.append("UpdateSettingsAgentInventory"); + capabilityNames.append("UpdateSettingsTaskInventory"); capabilityNames.append("UpdateScriptAgent"); capabilityNames.append("UpdateScriptTask"); - capabilityNames.append("UploadBakedTexture"); + capabilityNames.append("UpdateSettingsAgentInventory"); + capabilityNames.append("UpdateSettingsTaskInventory"); + capabilityNames.append("UploadBakedTexture"); capabilityNames.append("UserInfo"); capabilityNames.append("ViewerAsset"); capabilityNames.append("ViewerMetrics"); diff --git a/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml b/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml index 0f0acea832..88423ad023 100644 --- a/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml +++ b/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml @@ -24,8 +24,8 @@ border="false" auto_resize="false" user_resize="true" - height="30" - min_height="30" + height="45" + min_height="45" background_visible="false"> Preset Name: @@ -138,6 +137,15 @@ name="cancel_btn" width="100" /> +