diff options
Diffstat (limited to 'indra')
227 files changed, 18039 insertions, 12044 deletions
diff --git a/indra/cmake/Atmosphere.cmake b/indra/cmake/Atmosphere.cmake new file mode 100644 index 0000000000..9c14df2a11 --- /dev/null +++ b/indra/cmake/Atmosphere.cmake @@ -0,0 +1,5 @@ +# -*- cmake -*- +include(Prebuilt) +use_prebuilt_binary(libatmosphere) +set(LIBATMOSPHERE_LIBRARIES atmosphere) +set(LIBATMOSPHERE_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/atmosphere) diff --git a/indra/cmake/LLRender.cmake b/indra/cmake/LLRender.cmake index 868922451f..0940d1de63 100644 --- a/indra/cmake/LLRender.cmake +++ b/indra/cmake/LLRender.cmake @@ -3,6 +3,7 @@ include(Variables) include(FreeType) include(GLH) +include(Atmosphere) set(LLRENDER_INCLUDE_DIRS ${LIBS_OPEN_DIR}/llrender diff --git a/indra/llappearance/llwearabletype.cpp b/indra/llappearance/llwearabletype.cpp index 207e0c4011..85d3caecce 100644 --- a/indra/llappearance/llwearabletype.cpp +++ b/indra/llappearance/llwearabletype.cpp @@ -29,17 +29,17 @@ #include "llinventorytype.h" #include "llinventorydefines.h" -static LLTranslationBridge* sTrans = NULL; +static LLTranslationBridge::ptr_t sTrans = NULL; // static -void LLWearableType::initClass(LLTranslationBridge* trans) +void LLWearableType::initClass(LLTranslationBridge::ptr_t &trans) { sTrans = trans; } void LLWearableType::cleanupClass() { - delete sTrans; + sTrans.reset(); } struct WearableEntry : public LLDictionaryEntry @@ -172,6 +172,6 @@ BOOL LLWearableType::getAllowMultiwear(LLWearableType::EType type) // static LLWearableType::EType LLWearableType::inventoryFlagsToWearableType(U32 flags) { - return (LLWearableType::EType)(flags & LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK); + return (LLWearableType::EType)(flags & LLInventoryItemFlags::II_FLAGS_SUBTYPE_MASK); } diff --git a/indra/llappearance/llwearabletype.h b/indra/llappearance/llwearabletype.h index 519d5b92a2..74eb904c8d 100644 --- a/indra/llappearance/llwearabletype.h +++ b/indra/llappearance/llwearabletype.h @@ -31,16 +31,7 @@ #include "lldictionary.h" #include "llinventorytype.h" #include "llsingleton.h" - -class LLTranslationBridge -{ -public: - // clang needs this to be happy - virtual ~LLTranslationBridge() {} - - virtual std::string getString(const std::string &xml_desc) = 0; -}; - +#include "llinvtranslationbrdg.h" class LLWearableType { @@ -69,7 +60,7 @@ public: WT_NONE = -1, }; - static void initClass(LLTranslationBridge* trans); // initializes static members + static void initClass(LLTranslationBridge::ptr_t &trans); // initializes static members static void cleanupClass(); // initializes static members static const std::string& getTypeName(EType type); 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(); } } @@ -221,14 +224,6 @@ bool LLAssetType::lookupIsLinkType(EType asset_type) } // static -const std::string &LLAssetType::badLookup() -{ - static const std::string sBadLookup = "llassettype_bad_lookup"; - return sBadLookup; - -} - -// static bool LLAssetType::lookupIsAssetFetchByIDAllowed(EType asset_type) { const LLAssetDictionary *dict = LLAssetDictionary::getInstance(); diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h index b849be9f16..32502d5e33 100644 --- a/indra/llcommon/llassettype.h +++ b/indra/llcommon/llassettype.h @@ -116,10 +116,19 @@ 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_RESERVED_6 = 55, + + AT_SETTINGS = 56, // Collection of settings + + AT_COUNT = 57, // +*********************************************************+ // | TO ADD AN ELEMENT TO THIS ENUM: | @@ -153,7 +162,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() {} 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/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp index 1aaff5628f..c3fb4ebc2c 100644 --- a/indra/llcommon/llsdserialize.cpp +++ b/indra/llcommon/llsdserialize.cpp @@ -55,6 +55,7 @@ static const S32 UNZIP_LLSD_MAX_DEPTH = 96; static const char LEGACY_NON_HEADER[] = "<llsd>"; 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 @@ -81,6 +82,11 @@ void LLSDSerialize::serialize(const LLSD& sd, std::ostream& str, ELLSD_Serialize f = new LLSDXMLFormatter; break; + case LLSD_NOTATION: + str << "<? " << LLSD_NOTATION_HEADER << " ?>\n"; + f = new LLSDNotationFormatter; + break; + default: LL_WARNS() << "serialize request for unknown ELLSD_Serialize" << LL_ENDL; } @@ -168,6 +174,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 8165410e80..fe0f4443ef 100644 --- a/indra/llcommon/llsdserialize.h +++ b/indra/llcommon/llsdserialize.h @@ -706,7 +706,7 @@ class LL_COMMON_API LLSDSerialize public: enum ELLSD_Serialize { - LLSD_BINARY, LLSD_XML + LLSD_BINARY, LLSD_XML, LLSD_NOTATION }; /** diff --git a/indra/llcommon/llsdutil.cpp b/indra/llcommon/llsdutil.cpp index 9d00395c0a..6a23c443a0 100644 --- a/indra/llcommon/llsdutil.cpp +++ b/indra/llcommon/llsdutil.cpp @@ -322,6 +322,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() *****************************************************************************/ @@ -681,3 +855,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 01ab6bcb8d..863be04c8a 100644 --- a/indra/llcommon/llsdutil.h +++ b/indra/llcommon/llsdutil.h @@ -30,6 +30,7 @@ #define LL_LLSDUTIL_H #include "llsd.h" +#include <boost/functional/hash.hpp> // U32 LL_COMMON_API LLSD ll_sd_from_U32(const U32); @@ -70,6 +71,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,4 +435,86 @@ 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<LLSD> +{ + 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: + default: + 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 <vector> #include "stdtypes.h" #include "llpreprocessor.h" +#include <boost/functional/hash.hpp> 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<LLUUID> +{ + 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/llinventory/CMakeLists.txt b/indra/llinventory/CMakeLists.txt index 68dd00d880..f1bc28427d 100644 --- a/indra/llinventory/CMakeLists.txt +++ b/indra/llinventory/CMakeLists.txt @@ -23,12 +23,17 @@ set(llinventory_SOURCE_FILES llfoldertype.cpp llinventory.cpp llinventorydefines.cpp + llinventorysettings.cpp llinventorytype.cpp lllandmark.cpp llnotecard.cpp llparcel.cpp llpermissions.cpp llsaleinfo.cpp + llsettingsbase.cpp + llsettingsdaycycle.cpp + llsettingssky.cpp + llsettingswater.cpp lltransactionflags.cpp lluserrelations.cpp ) @@ -41,7 +46,9 @@ set(llinventory_HEADER_FILES llfoldertype.h llinventory.h llinventorydefines.h + llinventorysettings.h llinventorytype.h + llinvtranslationbrdg.h lllandmark.h llnotecard.h llparcel.h @@ -49,6 +56,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/llfoldertype.cpp b/indra/llinventory/llfoldertype.cpp index b0daf639fa..2c8c82a62b 100644 --- a/indra/llinventory/llfoldertype.cpp +++ b/indra/llinventory/llfoldertype.cpp @@ -147,7 +147,7 @@ bool LLFolderType::lookupIsEnsembleType(EType folder_type) // static LLAssetType::EType LLFolderType::folderTypeToAssetType(LLFolderType::EType folder_type) { - if (LLAssetType::lookup(LLAssetType::EType(folder_type)) == LLAssetType::badLookup()) + if (LLAssetType::lookup(LLAssetType::EType(folder_type)) == LLAssetType::BADLOOKUP) { LL_WARNS() << "Converting to unknown asset type " << folder_type << LL_ENDL; } diff --git a/indra/llinventory/llinventorydefines.h b/indra/llinventory/llinventorydefines.h index 3881fb1fd7..54562673f3 100644 --- a/indra/llinventory/llinventorydefines.h +++ b/indra/llinventory/llinventorydefines.h @@ -81,9 +81,10 @@ public: II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS = 0x200000, // Whether a returned object is composed of multiple items. - II_FLAGS_WEARABLES_MASK = 0xff, - // Wearables use the low order byte of flags to store the - // LLWearableType::EType enumeration found in newview/llwearable.h + II_FLAGS_SUBTYPE_MASK = 0x0000ff, + // Some items like Wearables and settings use the low order byte + // of flags to store the sub type of the inventory item. + // see LLWearableType::EType enumeration found in newview/llwearable.h II_FLAGS_PERM_OVERWRITE_MASK = (II_FLAGS_OBJECT_SLAM_PERM | II_FLAGS_OBJECT_SLAM_SALE | diff --git a/indra/llinventory/llinventorysettings.cpp b/indra/llinventory/llinventorysettings.cpp new file mode 100644 index 0000000000..8887c23a6c --- /dev/null +++ b/indra/llinventory/llinventorysettings.cpp @@ -0,0 +1,110 @@ +/** +* @file llinventorysettings.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 "linden_common.h" +#include "llinventorysettings.h" +#include "llinventorytype.h" +#include "llinventorydefines.h" +#include "lldictionary.h" +#include "llsingleton.h" +#include "llinvtranslationbrdg.h" + +//========================================================================= +namespace { + LLTranslationBridge::ptr_t sTranslator; +} + +//========================================================================= +struct SettingsEntry : public LLDictionaryEntry +{ + SettingsEntry(const std::string &name, + const std::string& default_new_name, + LLInventoryType::EIconName iconName) : + LLDictionaryEntry(name), + mDefaultNewName(default_new_name), + mLabel(name), + mIconName(iconName) + { + std::string transdname = sTranslator->getString(mLabel); + if (!transdname.empty()) + { + mLabel = transdname; + } + } + + std::string mLabel; + std::string mDefaultNewName; //keep mLabel for backward compatibility + LLInventoryType::EIconName mIconName; +}; + +class LLSettingsDictionary : public LLSingleton<LLSettingsDictionary>, + public LLDictionary<LLSettingsType::type_e, SettingsEntry> +{ + LLSINGLETON(LLSettingsDictionary); + + void initSingleton(); +}; + +LLSettingsDictionary::LLSettingsDictionary() +{ +} + +void LLSettingsDictionary::initSingleton() +{ + addEntry(LLSettingsType::ST_SKY, new SettingsEntry("sky", "New Sky", LLInventoryType::ICONNAME_SETTINGS_SKY)); + addEntry(LLSettingsType::ST_WATER, new SettingsEntry("water", "New Water", LLInventoryType::ICONNAME_SETTINGS_WATER)); + addEntry(LLSettingsType::ST_DAYCYCLE, new SettingsEntry("day", "New Day", LLInventoryType::ICONNAME_SETTINGS_DAY)); + addEntry(LLSettingsType::ST_NONE, new SettingsEntry("none", "New Settings", LLInventoryType::ICONNAME_SETTINGS)); + addEntry(LLSettingsType::ST_INVALID, new SettingsEntry("invalid", "New Settings", LLInventoryType::ICONNAME_SETTINGS)); +} + +//========================================================================= + +LLSettingsType::type_e LLSettingsType::fromInventoryFlags(U32 flags) +{ + return (LLSettingsType::type_e)(flags & LLInventoryItemFlags::II_FLAGS_SUBTYPE_MASK); +} + + +LLInventoryType::EIconName LLSettingsType::getIconName(LLSettingsType::type_e type) +{ + const SettingsEntry *entry = LLSettingsDictionary::instance().lookup(type); + if (!entry) + return getIconName(ST_INVALID); + return entry->mIconName; +} + + +void LLSettingsType::initClass(LLTranslationBridge::ptr_t &trans) +{ + sTranslator = trans; +} + +void LLSettingsType::cleanupClass() +{ + sTranslator.reset(); +} diff --git a/indra/llinventory/llinventorysettings.h b/indra/llinventory/llinventorysettings.h new file mode 100644 index 0000000000..fb08190ea9 --- /dev/null +++ b/indra/llinventory/llinventorysettings.h @@ -0,0 +1,55 @@ +/** +* @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 + +#include "llinventorytype.h" +#include "llinvtranslationbrdg.h" + +class LLSettingsType +{ +public: + enum type_e + { + ST_SKY = 0, + ST_WATER = 1, + ST_DAYCYCLE = 2, + + ST_INVALID = 255, + ST_NONE = -1 + }; + + static type_e fromInventoryFlags(U32 flags); + static LLInventoryType::EIconName getIconName(type_e type); + + static void initClass(LLTranslationBridge::ptr_t &trans); + static void cleanupClass(); +}; + + +#endif diff --git a/indra/llinventory/llinventorytype.cpp b/indra/llinventory/llinventorytype.cpp index d1e6807f52..2b6b53556d 100644 --- a/indra/llinventory/llinventorytype.cpp +++ b/indra/llinventory/llinventorytype.cpp @@ -85,6 +85,7 @@ LLInventoryDictionary::LLInventoryDictionary() addEntry(LLInventoryType::IT_MESH, new InventoryEntry("mesh", "mesh", 1, LLAssetType::AT_MESH)); addEntry(LLInventoryType::IT_WIDGET, new InventoryEntry("widget", "widget", 1, LLAssetType::AT_WIDGET)); addEntry(LLInventoryType::IT_PERSON, new InventoryEntry("person", "person", 1, LLAssetType::AT_PERSON)); + addEntry(LLInventoryType::IT_SETTINGS, new InventoryEntry("settings", "settings", 1, LLAssetType::AT_SETTINGS)); } @@ -145,6 +146,14 @@ DEFAULT_ASSET_FOR_INV_TYPE[LLAssetType::AT_COUNT] = LLInventoryType::IT_NONE, // 47 AT_NONE LLInventoryType::IT_NONE, // 48 AT_NONE LLInventoryType::IT_MESH, // 49 AT_MESH + + LLInventoryType::IT_NONE, // 50 AT_RESERVED_1 + LLInventoryType::IT_NONE, // 51 AT_RESERVED_2 + LLInventoryType::IT_NONE, // 52 AT_RESERVED_3 + LLInventoryType::IT_NONE, // 53 AT_RESERVED_4 + LLInventoryType::IT_NONE, // 54 AT_RESERVED_5 + + LLInventoryType::IT_SETTINGS, // 55 AT_SETTINGS }; // static diff --git a/indra/llinventory/llinventorytype.h b/indra/llinventory/llinventorytype.h index fc3c78cf50..86486373b5 100644 --- a/indra/llinventory/llinventorytype.h +++ b/indra/llinventory/llinventorytype.h @@ -64,7 +64,8 @@ public: IT_MESH = 22, IT_WIDGET = 23, IT_PERSON = 24, - IT_COUNT = 25, + IT_SETTINGS = 25, + IT_COUNT = 26, IT_NONE = -1 }; @@ -110,6 +111,11 @@ public: ICONNAME_LINKFOLDER, ICONNAME_MESH, + ICONNAME_SETTINGS, + ICONNAME_SETTINGS_SKY, + ICONNAME_SETTINGS_WATER, + ICONNAME_SETTINGS_DAY, + ICONNAME_INVALID, ICONNAME_COUNT, ICONNAME_NONE = -1 diff --git a/indra/llinventory/llinvtranslationbrdg.h b/indra/llinventory/llinvtranslationbrdg.h new file mode 100644 index 0000000000..fbd887030a --- /dev/null +++ b/indra/llinventory/llinvtranslationbrdg.h @@ -0,0 +1,41 @@ +/** +* @file llinvtranslationbrdg.h +* @brief Translation adapter for inventory. +* +* $LicenseInfo:firstyear=2002&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2010, 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_TRANSLATIONBRDG_H +#define LL_TRANSLATIONBRDG_H + +class LLTranslationBridge +{ +public: + typedef std::shared_ptr<LLTranslationBridge> ptr_t; + + // clang needs this to be happy + virtual ~LLTranslationBridge() {} + + virtual std::string getString(const std::string &xml_desc) = 0; +}; + +#endif diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h index 135d0ca7b9..6ef389d246 100644 --- a/indra/llinventory/llparcel.h +++ b/indra/llinventory/llparcel.h @@ -34,6 +34,7 @@ #include "llpermissions.h" #include "lltimer.h" #include "v3math.h" +#include "llsettingsdaycycle.h" // Grid out of which parcels taken is stepped every 4 meters. const F32 PARCEL_GRID_STEP_METERS = 4.f; @@ -589,8 +590,7 @@ public: LLUUID getPreviousOwnerID() const { return mPreviousOwnerID; } BOOL getPreviouslyGroupOwned() const { return mPreviouslyGroupOwned; } BOOL getSellWithObjects() const { return (mParcelFlags & PF_SELL_PARCEL_OBJECTS) ? TRUE : FALSE; } - - + protected: LLUUID mID; LLUUID mOwnerID; @@ -665,7 +665,8 @@ protected: BOOL mAllowGroupAVSounds; BOOL mAllowAnyAVSounds; - + bool mIsDefaultDayCycle; + public: // HACK, make private S32 mLocalID; diff --git a/indra/llinventory/llsettingsbase.cpp b/indra/llinventory/llsettingsbase.cpp new file mode 100644 index 0000000000..d8e337e231 --- /dev/null +++ b/indra/llinventory/llsettingsbase.cpp @@ -0,0 +1,587 @@ +/** +* @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 <algorithm> + +#include "llsdserialize.h" + +//========================================================================= +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"); +const std::string LLSettingsBase::SETTING_HASH("hash"); +const std::string LLSettingsBase::SETTING_TYPE("type"); + +//========================================================================= +LLSettingsBase::LLSettingsBase(): + mSettings(LLSD::emptyMap()), + mDirty(true), + mAssetID(), + mBlendedFactor(0.0) +{ +} + +LLSettingsBase::LLSettingsBase(const LLSD setting) : + mSettings(setting), + mDirty(true), + mAssetID(), + mBlendedFactor(0.0) +{ +} + +//========================================================================= +void LLSettingsBase::lerpSettings(const LLSettingsBase &other, F64 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, F64 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::TypeUUID: + newSettings[key_name] = value.asUUID(); + break; + +// case LLSD::TypeBoolean: +// case LLSD::TypeString: +// 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(getSettings(), 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<LLSD>{}(hash_settings); +} + +bool LLSettingsBase::validate() +{ + validation_list_t validations = getValidationList(); + + if (!mSettings.has(SETTING_TYPE)) + { + mSettings[SETTING_TYPE] = getSettingType(); + } + + LLSD result = LLSettingsBase::settingValidation(mSettings, validations); + + if (result["errors"].size() > 0) + { + LL_WARNS("SETTINGS") << "Validation errors: " << result["errors"] << LL_ENDL; + } + if (result["warnings"].size() > 0) + { + LL_WARNS("SETTINGS") << "Validation warnings: " << result["errors"] << LL_ENDL; + } + + return result["success"].asBoolean(); +} + +LLSD LLSettingsBase::settingValidation(LLSD &settings, validation_list_t &validations) +{ + 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); + stringset_t validated; + stringset_t strip; + bool isValid(true); + LLSD errors(LLSD::emptyArray()); + LLSD warnings(LLSD::emptyArray()); + + // Fields common to all settings. + if (!validateName.verify(settings)) + { + errors.append( LLSD::String("Unable to validate 'name'.") ); + isValid = false; + } + validated.insert(validateName.getName()); + + if (!validateId.verify(settings)) + { + errors.append( LLSD::String("Unable to validate 'id'.") ); + isValid = false; + } + validated.insert(validateId.getName()); + + if (!validateHash.verify(settings)) + { + errors.append( LLSD::String("Unable to validate 'hash'.") ); + isValid = false; + } + validated.insert(validateHash.getName()); + + if (!validateType.verify(settings)) + { + errors.append( LLSD::String("Unable to validate 'type'.") ); + isValid = false; + } + validated.insert(validateType.getName()); + + // Fields for specific settings. + for (auto &test: validations) + { + if (!test.verify(settings)) + { + std::stringstream errtext; + + errtext << "Settings LLSD fails validation and could not be corrected for '" << test.getName() << "'!\n"; + errors.append( errtext.str() ); + isValid = false; + } + validated.insert(test.getName()); + } + + // strip extra entries + for (LLSD::map_const_iterator itm = settings.beginMap(); itm != settings.endMap(); ++itm) + { + if (validated.find((*itm).first) == validated.end()) + { + std::stringstream warntext; + + warntext << "Stripping setting '" << (*itm).first << "'"; + warnings.append( warntext.str() ); + strip.insert((*itm).first); + } + } + + for (const std::string &its: strip) + { + settings.erase(its); + } + + return LLSDMap("success", LLSD::Boolean(isValid)) + ("errors", errors) + ("warnings", warnings); +} + +//========================================================================= +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 << "' with no default." << 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) +{ + F64 real = value.asReal(); + + F64 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(F64 blendf) +{ + setPosition(blendf); +} + +F64 LLSettingsBlender::setPosition(F64 blendf) +{ + if (blendf >= 1.0) + { + triggerComplete(); + return 1.0; + } + blendf = llclamp(blendf, 0.0, 1.0); + + mTarget->replaceSettings(mInitial->getSettings()); + if (!mFinal || (mInitial == mFinal) || (blendf == 0.0)) + { // this is a trivial blend. Results will be identical to the initial. + return blendf; + } + mTarget->blend(mFinal, blendf); + + return blendf; +} + +void LLSettingsBlender::triggerComplete() +{ + mTarget->replaceSettings(mFinal->getSettings()); + LLSettingsBlender::ptr_t hold = shared_from_this(); // prevents this from deleting too soon + mOnFinished(shared_from_this()); +} + +//------------------------------------------------------------------------- +F64 LLSettingsBlenderTimeDelta::calculateBlend(F64 spanpos, F64 spanlen) const +{ + return fmod(spanpos, spanlen) / spanlen; +} + +void LLSettingsBlenderTimeDelta::update(F64 timedelta) +{ + mTimeSpent += F64Seconds(timedelta); + + if (mTimeSpent > mBlendSpan) + { + triggerComplete(); + return; + } + + F64 blendf = calculateBlend(mTimeSpent.value(), mBlendSpan.value()); + // Note no clamp here. + + setPosition(blendf); +} diff --git a/indra/llinventory/llsettingsbase.h b/indra/llinventory/llsettingsbase.h new file mode 100644 index 0000000000..1ef7df79ad --- /dev/null +++ b/indra/llinventory/llsettingsbase.h @@ -0,0 +1,375 @@ +/** +* @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 <string> +#include <map> +#include <vector> +#include <boost/signals2.hpp> + +#include "llsd.h" +#include "llsdutil.h" +#include "v2math.h" +#include "v3math.h" +#include "v4math.h" +#include "llquaternion.h" +#include "v4color.h" +#include "v3color.h" + +#include "llinventorysettings.h" + +class LLSettingsBase : + public std::enable_shared_from_this<LLSettingsBase>, + private boost::noncopyable +{ + 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; + static const std::string SETTING_HASH; + static const std::string SETTING_TYPE; + + typedef std::map<std::string, S32> parammapping_t; + + typedef std::shared_ptr<LLSettingsBase> ptr_t; + + virtual ~LLSettingsBase() { }; + + //--------------------------------------------------------------------- + virtual std::string getSettingType() const = 0; + + virtual LLSettingsType::type_e getSettingTypeValue() 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; + mBlendedFactor = 0.0; + 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()); + } + + inline F64 getBlendFactor() const + { + return mBlendedFactor; + } + + // 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<LLSettingsBase *>(this))->updateSettings(); + } + + virtual void blend(const ptr_t &end, F64 blendf) = 0; + + virtual bool validate(); + + virtual ptr_t buildDerivedClone() = 0; + + class Validator + { + public: + typedef boost::function<bool(LLSD &)> 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), + mDefault(defval) + { } + + 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; + LLSD mDefault; + }; + typedef std::vector<Validator> validation_list_t; + + static LLSD settingValidation(LLSD &settings, validation_list_t &validations); +protected: + + LLSettingsBase(); + LLSettingsBase(const LLSD setting); + + static LLSD settingValidation(LLSD settings); + + typedef std::set<std::string> stringset_t; + + // combining settings objects. Customize for specific setting types + virtual void lerpSettings(const LLSettingsBase &other, F64 mix); + LLSD interpolateSDMap(const LLSD &settings, const LLSD &other, F64 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; + LLAssetID mAssetID; + + LLSD cloneSettings() const; + + inline void setBlendFactor(F64 blendfactor) + { + mBlendedFactor = blendfactor; + } + +private: + bool mDirty; + + LLSD combineSDMaps(const LLSD &first, const LLSD &other) const; + + F64 mBlendedFactor; +}; + + +class LLSettingsBlender : public std::enable_shared_from_this<LLSettingsBlender> +{ +public: + typedef std::shared_ptr<LLSettingsBlender> ptr_t; + typedef boost::signals2::signal<void(const ptr_t )> finish_signal_t; + typedef boost::signals2::connection connection_t; + + LLSettingsBlender(const LLSettingsBase::ptr_t &target, + const LLSettingsBase::ptr_t &initsetting, const LLSettingsBase::ptr_t &endsetting) : + mOnFinished(), + mTarget(target), + mInitial(initsetting), + mFinal(endsetting) + { + if (mInitial) + mTarget->replaceSettings(mInitial->getSettings()); + + if (!mFinal) + mFinal = mInitial; + } + + virtual ~LLSettingsBlender() {} + + virtual void reset( LLSettingsBase::ptr_t &initsetting, const LLSettingsBase::ptr_t &endsetting, F64 /*span*/ = 1.0) + { + // note: the 'span' reset parameter is unused by the base class. + if (!mInitial) + LL_WARNS("BLENDER") << "Reseting blender with empty initial setting. Expect badness in the future." << LL_ENDL; + + mInitial = initsetting; + mFinal = endsetting; + + if (!mFinal) + mFinal = mInitial; + + mTarget->replaceSettings(mInitial->getSettings()); + } + + LLSettingsBase::ptr_t getTarget() const + { + return mTarget; + } + + LLSettingsBase::ptr_t getInitial() const + { + return mInitial; + } + + LLSettingsBase::ptr_t getFinal() const + { + return mFinal; + } + + connection_t setOnFinished(const finish_signal_t::slot_type &onfinished) + { + return mOnFinished.connect(onfinished); + } + + virtual void update(F64 blendf); + virtual F64 setPosition(F64 blendf); + + virtual void switchTrack(S32 trackno, F64 position = -1.0) { /*NoOp*/ } + +protected: + void triggerComplete(); + + finish_signal_t mOnFinished; + + LLSettingsBase::ptr_t mTarget; + LLSettingsBase::ptr_t mInitial; + LLSettingsBase::ptr_t mFinal; +}; + +class LLSettingsBlenderTimeDelta : public LLSettingsBlender +{ +public: + LLSettingsBlenderTimeDelta(const LLSettingsBase::ptr_t &target, + const LLSettingsBase::ptr_t &initsetting, const LLSettingsBase::ptr_t &endsetting, F64Seconds seconds) : + LLSettingsBlender(target, initsetting, endsetting), + mBlendSpan(seconds), + mLastUpdate(0.0f), + mTimeSpent(0.0f) + { + mTimeStart = F64Seconds(LLDate::now().secondsSinceEpoch()); + mLastUpdate = mTimeStart; + } + + virtual ~LLSettingsBlenderTimeDelta() + { + } + + virtual void reset(LLSettingsBase::ptr_t &initsetting, const LLSettingsBase::ptr_t &endsetting, F64 span = 1.0) override + { + LLSettingsBlender::reset(initsetting, endsetting, span); + + mBlendSpan.value(span); + mTimeStart.value(LLDate::now().secondsSinceEpoch()); + mLastUpdate = mTimeStart; + mTimeSpent.value(0.0f); + } + + virtual void update(F64 timedelta) override; + +protected: + F64 calculateBlend(F64 spanpos, F64 spanlen) const; + + F64Seconds mBlendSpan; + F64Seconds mLastUpdate; + F64Seconds mTimeSpent; + F64Seconds mTimeStart; +}; + + +#endif diff --git a/indra/llinventory/llsettingsdaycycle.cpp b/indra/llinventory/llsettingsdaycycle.cpp new file mode 100644 index 0000000000..577b12b031 --- /dev/null +++ b/indra/llinventory/llsettingsdaycycle.cpp @@ -0,0 +1,629 @@ +/** +* @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 <algorithm> +#include <boost/make_shared.hpp> +#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"); + + 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_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 S64Seconds LLSettingsDay::MINIMUM_DAYLENGTH(300); // 5 mins +const S64Seconds LLSettingsDay::DEFAULT_DAYLENGTH(14400); // 4 hours +const S64Seconds LLSettingsDay::MAXIMUM_DAYLENGTH(604800); // 7 days + +const S64Seconds LLSettingsDay::MINIMUM_DAYOFFSET(0); +const S64Seconds LLSettingsDay::DEFAULT_DAYOFFSET(57600); // +16 hours == -8 hours (SLT time offset) +const S64Seconds LLSettingsDay::MAXIMUM_DAYOFFSET(86400); // 24 hours + +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]; + + settings[SETTING_TYPE] = getSettingType(); + + std::map<std::string, LLSettingsBase::ptr_t> in_use; + + LLSD tracks(LLSD::emptyArray()); + + for (auto &track: mDayTracks) + { + LLSD trackout(LLSD::emptyArray()); + + for (auto &frame: track) + { + F32 frame_time = frame.first; + LLSettingsBase::ptr_t data = frame.second; + size_t datahash = data->getHash(); + + std::stringstream keyname; + keyname << datahash; + + trackout.append(LLSD(LLSDMap(SETTING_KEYKFRAME, LLSD::Real(frame_time))(SETTING_KEYNAME, keyname.str()))); + in_use[keyname.str()] = data; + } + tracks.append(trackout); + } + settings[SETTING_TRACKS] = tracks; + + LLSD frames(LLSD::emptyMap()); + for (auto &used_frame: in_use) + { + LLSD framesettings = llsd_clone(used_frame.second->getSettings(), + LLSDMap("*", true)(SETTING_NAME, false)(SETTING_ID, false)(SETTING_HASH, false)); + + frames[used_frame.first] = framesettings; + } + settings[SETTING_FRAMES] = frames; + + return settings; +} + +bool LLSettingsDay::initialize() +{ + LLSD tracks = mSettings[SETTING_TRACKS]; + LLSD frames = mSettings[SETTING_FRAMES]; + + std::map<std::string, LLSettingsBase::ptr_t> used; + + for (LLSD::map_const_iterator itFrame = frames.beginMap(); itFrame != frames.endMap(); ++itFrame) + { + std::string name = (*itFrame).first; + LLSD data = (*itFrame).second; + LLSettingsBase::ptr_t keyframe; + + if (data[SETTING_TYPE].asString() == "sky") + { + keyframe = buildSky(data); + } + else if (data[SETTING_TYPE].asString() == "water") + { + keyframe = buildWater(data); + } + else + { + LL_WARNS("DAYCYCLE") << "Unknown child setting type '" << data[SETTING_TYPE].asString() << "' named '" << name << "'" << LL_ENDL; + } + if (!keyframe) + { + LL_WARNS("DAYCYCLE") << "Invalid frame data" << LL_ENDL; + continue; + } + + used[name] = keyframe; + } + + bool haswater(false); + bool hassky(false); + + 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) + { + if (i == TRACK_WATER) + haswater |= true; + else + hassky |= true; + mDayTracks[i][keyframe] = setting; + } + } + } + + if (!haswater || !hassky) + { + LL_WARNS("DAYCYCLE") << "Must have at least one water and one sky frame!" << LL_ENDL; + return false; + } + // these are no longer needed and just take up space now. + mSettings.erase(SETTING_TRACKS); + mSettings.erase(SETTING_FRAMES); + + mInitialized = true; + return true; +} + + +//========================================================================= +LLSD LLSettingsDay::defaults() +{ + LLSD dfltsetting; + + dfltsetting[SETTING_NAME] = "_default_"; + + LLSD waterTrack; + waterTrack[SETTING_KEYKFRAME] = 0.0f; + waterTrack[SETTING_KEYNAME] = "_default_"; + + LLSD skyTrack; + skyTrack[SETTING_KEYKFRAME] = 0.0f; + skyTrack[SETTING_KEYNAME] = "_default_"; + + LLSD tracks; + tracks.append(LLSDArray(waterTrack)); + tracks.append(LLSDArray(skyTrack)); + + dfltsetting[SETTING_TRACKS] = tracks; + + LLSD frames(LLSD::emptyMap()); + + frames["water:_defaults_"] = LLSettingsWater::defaults(); + frames["sky:_defaults_"] = LLSettingsSky::defaults(); + + dfltsetting[SETTING_FRAMES] = frames; + + dfltsetting[SETTING_TYPE] = "daycycle"; + + return dfltsetting; +} + +void LLSettingsDay::blend(const LLSettingsBase::ptr_t &other, F64 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); + } + + S32 framecount(0); + + for (LLSD::array_iterator track = value.beginArray(); track != value.endArray(); ++track) + { + S32 index = 0; + while (index < (*track).size()) + { + LLSD& elem = (*track)[index]; + + ++framecount; + if (index >= LLSettingsDay::FRAME_MAX) + { + (*track).erase(index); + continue; + } + + if (!elem.has(LLSettingsDay::SETTING_KEYKFRAME)) + { + (*track).erase(index); + continue; + } + + if (!elem[LLSettingsDay::SETTING_KEYKFRAME].isReal()) + { + (*track).erase(index); + continue; + } + + if (!elem.has(LLSettingsDay::SETTING_KEYNAME) && + !elem.has(LLSettingsDay::SETTING_KEYID)) + { + (*track).erase(index); + continue; + } + + F32 frame = elem[LLSettingsDay::SETTING_KEYKFRAME].asReal(); + if ((frame < 0.0) || (frame > 1.0)) + { + frame = llclamp(frame, 0.0f, 1.0f); + elem[LLSettingsDay::SETTING_KEYKFRAME] = frame; + } + ++index; + } + + } + + int waterTracks = value[0].size(); + int skyTracks = framecount - waterTracks; + + if (waterTracks < 1) + { + LL_WARNS("SETTINGS") << "Missing water track" << LL_ENDL; + return false; + } + + if (skyTracks < 1) + { + LL_WARNS("SETTINGS") << "Missing sky tracks" << LL_ENDL; + return false; + } + return true; + } + + bool validateDayCycleFrames(LLSD &value) + { + bool hasSky(false); + bool hasWater(false); + + for (LLSD::map_iterator itf = value.beginMap(); itf != value.endMap(); ++itf) + { + LLSD frame = (*itf).second; + + std::string ftype = frame[LLSettingsBase::SETTING_TYPE]; + if (ftype == "sky") + { + LLSettingsSky::validation_list_t valid_sky = LLSettingsSky::validationList(); + LLSD res_sky = LLSettingsBase::settingValidation(frame, valid_sky); + + if (res_sky["success"].asInteger() == 0) + { + LL_WARNS("SETTINGS") << "Sky setting named '" << (*itf).first << "' validation failed!: " << res_sky << LL_ENDL; + LL_WARNS("SETTINGS") << "Sky: " << frame << LL_ENDL; + continue; + } + hasSky |= true; + } + else if (ftype == "water") + { + LLSettingsWater::validation_list_t valid_h2o = LLSettingsWater::validationList(); + LLSD res_h2o = LLSettingsBase::settingValidation(frame, valid_h2o); + if (res_h2o["success"].asInteger() == 0) + { + LL_WARNS("SETTINGS") << "Water setting named '" << (*itf).first << "' validation failed!: " << res_h2o << LL_ENDL; + LL_WARNS("SETTINGS") << "Water: " << frame << LL_ENDL; + continue; + } + hasWater |= true; + } + else + { + LL_WARNS("SETTINGS") << "Unknown settings block of type '" << ftype << "' named '" << (*itf).first << "'" << LL_ENDL; + return false; + } + } + + if (!hasSky) + { + LL_WARNS("SETTINGS") << "No skies defined." << LL_ENDL; + return false; + } + + if (!hasWater) + { + LL_WARNS("SETTINGS") << "No waters defined." << LL_ENDL; + return false; + } + + return true; + } +} + +LLSettingsDay::validation_list_t LLSettingsDay::getValidationList() const +{ + return LLSettingsDay::validationList(); +} + +LLSettingsDay::validation_list_t LLSettingsDay::validationList() +{ + static validation_list_t validation; + + if (validation.empty()) + { + validation.push_back(Validator(SETTING_TRACKS, true, LLSD::TypeArray, + &validateDayCycleTrack)); + validation.push_back(Validator(SETTING_FRAMES, true, LLSD::TypeMap, + &validateDayCycleFrames)); + } + + return validation; +} + +LLSettingsDay::CycleTrack_t &LLSettingsDay::getCycleTrack(S32 track) +{ + static CycleTrack_t emptyTrack; + if (mDayTracks.size() <= track) + return emptyTrack; + + return mDayTracks[track]; +} + +//========================================================================= +void LLSettingsDay::startDayCycle() +{ + F64Seconds now(LLDate::now().secondsSinceEpoch()); + + if (!mInitialized) + { + LL_WARNS("DAYCYCLE") << "Attempt to start day cycle on uninitialized object." << LL_ENDL; + return; + } + +} + + +void LLSettingsDay::updateSettings() +{ +} + +//========================================================================= +LLSettingsDay::KeyframeList_t LLSettingsDay::getTrackKeyframes(S32 trackno) +{ + if ((trackno < 0) || (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 (auto &frame: track) + { + keyframes.push_back(frame.first); + } + + return keyframes; +} + +bool LLSettingsDay::moveTrackKeyframe(S32 trackno, F32 old_frame, F32 new_frame) +{ + if ((trackno < 0) || (trackno >= TRACK_MAX)) + { + LL_WARNS("DAYCYCLE") << "Attempt get track (#" << trackno << ") out of range!" << LL_ENDL; + return false; + } + + if (old_frame == new_frame) + { + return false; + } + + CycleTrack_t &track = mDayTracks[trackno]; + CycleTrack_t::iterator iter = track.find(old_frame); + if (iter != track.end()) + { + LLSettingsBase::ptr_t base = iter->second; + track.erase(iter); + track[llclamp(new_frame, 0.0f, 1.0f)] = base; + return true; + } + + return false; + +} + +bool LLSettingsDay::removeTrackKeyframe(S32 trackno, F32 frame) +{ + if ((trackno < 0) || (trackno >= TRACK_MAX)) + { + LL_WARNS("DAYCYCLE") << "Attempt get track (#" << trackno << ") out of range!" << LL_ENDL; + return false; + } + + CycleTrack_t &track = mDayTracks[trackno]; + CycleTrack_t::iterator iter = track.find(frame); + if (iter != track.end()) + { + LLSettingsBase::ptr_t base = iter->second; + track.erase(iter); + return true; + } + + return false; +} + +void LLSettingsDay::setWaterAtKeyframe(const LLSettingsWaterPtr_t &water, F32 keyframe) +{ + setSettingsAtKeyframe(water, keyframe, TRACK_WATER); +} + +LLSettingsWater::ptr_t LLSettingsDay::getWaterAtKeyframe(F32 keyframe) const +{ + return std::dynamic_pointer_cast<LLSettingsWater>(getSettingsAtKeyframe(keyframe, TRACK_WATER)); +} + +void LLSettingsDay::setSkyAtKeyframe(const LLSettingsSky::ptr_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; + } + + setSettingsAtKeyframe(sky, keyframe, track); +} + +LLSettingsSky::ptr_t LLSettingsDay::getSkyAtKeyframe(F32 keyframe, S32 track) const +{ + if ((track < 1) || (track >= TRACK_MAX)) + { + LL_WARNS("DAYCYCLE") << "Attempt to set sky track (#" << track << ") out of range!" << LL_ENDL; + return LLSettingsSky::ptr_t(); + } + + return std::dynamic_pointer_cast<LLSettingsSky>(getSettingsAtKeyframe(keyframe, track)); +} + +void LLSettingsDay::setSettingsAtKeyframe(const LLSettingsBase::ptr_t &settings, F32 keyframe, S32 track) +{ + if ((track < 0) || (track >= TRACK_MAX)) + { + LL_WARNS("DAYCYCLE") << "Attempt to set track (#" << track << ") out of range!" << LL_ENDL; + return; + } + + mDayTracks[track][llclamp(keyframe, 0.0f, 1.0f)] = settings; + setDirtyFlag(true); +} + +LLSettingsBase::ptr_t LLSettingsDay::getSettingsAtKeyframe(F32 keyframe, S32 track) const +{ + if ((track < 0) || (track >= TRACK_MAX)) + { + LL_WARNS("DAYCYCLE") << "Attempt to set sky track (#" << track << ") out of range!" << LL_ENDL; + return LLSettingsBase::ptr_t(); + } + + // todo: better way to identify keyframes? + CycleTrack_t::const_iterator iter = mDayTracks[track].find(keyframe); + if (iter != mDayTracks[track].end()) + { + return iter->second; + } + + return LLSettingsBase::ptr_t(); +} + +F32 LLSettingsDay::getUpperBoundFrame(S32 track, F32 keyframe) +{ + return get_wrapping_atafter(mDayTracks[track], keyframe)->first; +} + +F32 LLSettingsDay::getLowerBoundFrame(S32 track, F32 keyframe) +{ + return get_wrapping_atbefore(mDayTracks[track], keyframe)->first; +} + +LLSettingsDay::TrackBound_t LLSettingsDay::getBoundingEntries(LLSettingsDay::CycleTrack_t &track, F32 keyframe) +{ + return TrackBound_t(get_wrapping_atbefore(track, keyframe), get_wrapping_atafter(track, keyframe)); +} + +//========================================================================= diff --git a/indra/llinventory/llsettingsdaycycle.h b/indra/llinventory/llsettingsdaycycle.h new file mode 100644 index 0000000000..5e6fc7f21d --- /dev/null +++ b/indra/llinventory/llsettingsdaycycle.h @@ -0,0 +1,146 @@ +/** +* @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; + +// These are alias for LLSettingsWater::ptr_t and LLSettingsSky::ptr_t respectively. +// Here for definitions only. +typedef std::shared_ptr<LLSettingsWater> LLSettingsWaterPtr_t; +typedef std::shared_ptr<LLSettingsSky> LLSettingsSkyPtr_t; + +class LLSettingsDay : public LLSettingsBase +{ +public: + 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 S64Seconds MINIMUM_DAYLENGTH; + static const S64Seconds DEFAULT_DAYLENGTH; + static const S64Seconds MAXIMUM_DAYLENGTH; + + static const S64Seconds MINIMUM_DAYOFFSET; + static const S64Seconds DEFAULT_DAYOFFSET; + static const S64Seconds MAXIMUM_DAYOFFSET; + + static const S32 TRACK_WATER; + static const S32 TRACK_MAX; + static const S32 FRAME_MAX; + + typedef std::map<F32, LLSettingsBase::ptr_t> CycleTrack_t; + typedef std::vector<CycleTrack_t> CycleList_t; + typedef std::shared_ptr<LLSettingsDay> ptr_t; + typedef std::vector<F32> KeyframeList_t; + typedef std::pair<CycleTrack_t::iterator, CycleTrack_t::iterator> TrackBound_t; + + //--------------------------------------------------------------------- + LLSettingsDay(const LLSD &data); + virtual ~LLSettingsDay() { }; + + bool initialize(); + + virtual ptr_t buildClone() = 0; + virtual LLSD getSettings() const override; + virtual LLSettingsType::type_e getSettingTypeValue() const override { return LLSettingsType::ST_DAYCYCLE; } + + + //--------------------------------------------------------------------- + virtual std::string getSettingType() const override { return std::string("daycycle"); } + + // Settings status + virtual void blend(const LLSettingsBase::ptr_t &other, F64 mix) override; + + static LLSD defaults(); + + //--------------------------------------------------------------------- + KeyframeList_t getTrackKeyframes(S32 track); + bool moveTrackKeyframe(S32 track, F32 old_frame, F32 new_frame); + bool removeTrackKeyframe(S32 track, F32 frame); + + void setWaterAtKeyframe(const LLSettingsWaterPtr_t &water, F32 keyframe); + LLSettingsWaterPtr_t getWaterAtKeyframe(F32 keyframe) const; + void setSkyAtKeyframe(const LLSettingsSkyPtr_t &sky, F32 keyframe, S32 track); + LLSettingsSkyPtr_t getSkyAtKeyframe(F32 keyframe, S32 track) const; + void setSettingsAtKeyframe(const LLSettingsBase::ptr_t &settings, F32 keyframe, S32 track); + LLSettingsBase::ptr_t getSettingsAtKeyframe(F32 keyframe, S32 track) const; + //--------------------------------------------------------------------- + void startDayCycle(); + + 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; } + CycleTrack_t & getCycleTrack(S32 track); + + virtual validation_list_t getValidationList() const override; + static validation_list_t validationList(); + + virtual LLSettingsBase::ptr_t buildDerivedClone() override { return buildClone(); } + + F32 getUpperBoundFrame(S32 track, F32 keyframe); + F32 getLowerBoundFrame(S32 track, F32 keyframe); + +protected: + LLSettingsDay(); + + virtual void updateSettings() override; + + bool mInitialized; + +private: + CycleList_t mDayTracks; + + F64Seconds mLastUpdateTime; + + 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); + +// 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..45c1ca1d7f --- /dev/null +++ b/indra/llinventory/llsettingssky.cpp @@ -0,0 +1,955 @@ +/** +* @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 <algorithm> +#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_BLUE_DENSITY("blue_density"); +const std::string LLSettingsSky::SETTING_BLUE_HORIZON("blue_horizon"); +const std::string LLSettingsSky::SETTING_DENSITY_MULTIPLIER("density_multiplier"); +const std::string LLSettingsSky::SETTING_DISTANCE_MULTIPLIER("distance_multiplier"); +const std::string LLSettingsSky::SETTING_HAZE_DENSITY("haze_density"); +const std::string LLSettingsSky::SETTING_HAZE_HORIZON("haze_horizon"); + +const std::string LLSettingsSky::SETTING_BLOOM_TEXTUREID("bloom_id"); +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_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_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_TEXTUREID("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"); + +// these are new settings for the advanced atmospherics model +const std::string LLSettingsSky::SETTING_PLANET_RADIUS("planet_radius"); +const std::string LLSettingsSky::SETTING_SKY_BOTTOM_RADIUS("sky_bottom_radius"); +const std::string LLSettingsSky::SETTING_SKY_TOP_RADIUS("sky_top_radius"); +const std::string LLSettingsSky::SETTING_SUN_ARC_RADIANS("sun_arc_radians"); + +const std::string LLSettingsSky::SETTING_RAYLEIGH_CONFIG("rayleigh_config"); +const std::string LLSettingsSky::SETTING_MIE_CONFIG("mie_config"); +const std::string LLSettingsSky::SETTING_MIE_ANISOTROPY_FACTOR("anisotropy"); +const std::string LLSettingsSky::SETTING_ABSORPTION_CONFIG("absorption_config"); + +const std::string LLSettingsSky::KEY_DENSITY_PROFILE("density"); +const std::string LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH("width"); +const std::string LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM("exp_term"); +const std::string LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR("exp_scale"); +const std::string LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM("linear_term"); +const std::string LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM("constant_term"); + +const LLUUID LLSettingsSky::DEFAULT_SUN_ID("cce0f112-878f-4586-a2e2-a8f104bba271"); // dataserver +const LLUUID LLSettingsSky::DEFAULT_MOON_ID("d07f6eed-b96a-47cd-b51d-400ad4a1c428"); // dataserver +const LLUUID LLSettingsSky::DEFAULT_CLOUD_ID("1dc1368f-e8fe-f02d-a08d-9d9f11c1af6b"); + +namespace +{ + +LLSettingsSky::validation_list_t rayleighValidationList() +{ + static LLSettingsBase::validation_list_t rayleighValidation; + if (rayleighValidation.empty()) + { + rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH, true, LLSD::TypeReal, + boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(32768.0f))))); + + rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM, true, LLSD::TypeReal, + boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(2.0f))))); + + rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, true, LLSD::TypeReal, + boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(-1.0f)(1.0f))))); + + rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM, true, LLSD::TypeReal, + boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(2.0f))))); + + rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM, true, LLSD::TypeReal, + boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f))))); + } + return rayleighValidation; +} + +LLSettingsSky::validation_list_t absorptionValidationList() +{ + static LLSettingsBase::validation_list_t absorptionValidation; + if (absorptionValidation.empty()) + { + absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH, true, LLSD::TypeReal, + boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(32768.0f))))); + + absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM, true, LLSD::TypeReal, + boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(2.0f))))); + + absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, true, LLSD::TypeReal, + boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(-1.0f)(1.0f))))); + + absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM, true, LLSD::TypeReal, + boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(2.0f))))); + + absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM, true, LLSD::TypeReal, + boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f))))); + } + return absorptionValidation; +} + +LLSettingsSky::validation_list_t mieValidationList() +{ + static LLSettingsBase::validation_list_t mieValidation; + if (mieValidation.empty()) + { + mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH, true, LLSD::TypeReal, + boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(32768.0f))))); + + mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM, true, LLSD::TypeReal, + boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(2.0f))))); + + mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, true, LLSD::TypeReal, + boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(-1.0f)(1.0f))))); + + mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM, true, LLSD::TypeReal, + boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(2.0f))))); + + mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM, true, LLSD::TypeReal, + boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f))))); + + mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_MIE_ANISOTROPY_FACTOR, true, LLSD::TypeReal, + boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f))))); + } + return mieValidation; +} + +bool validateRayleighLayers(LLSD &value) +{ + LLSettingsSky::validation_list_t rayleighValidations = rayleighValidationList(); + if (value.isArray()) + { + bool allGood = true; + for (LLSD::array_iterator itf = value.beginArray(); itf != value.endArray(); ++itf) + { + LLSD& layerConfig = (*itf); + if (layerConfig.type() == LLSD::Type::TypeMap) + { + if (!validateRayleighLayers(layerConfig)) + { + allGood = false; + } + } + else if (layerConfig.type() == LLSD::Type::TypeArray) + { + return validateRayleighLayers(layerConfig); + } + else + { + return LLSettingsBase::settingValidation(value, rayleighValidations); + } + } + return allGood; + } + llassert(value.type() == LLSD::Type::TypeMap); + LLSD result = LLSettingsBase::settingValidation(value, rayleighValidations); + if (result["errors"].size() > 0) + { + LL_WARNS("SETTINGS") << "Rayleigh Config Validation errors: " << result["errors"] << LL_ENDL; + return false; + } + if (result["warnings"].size() > 0) + { + LL_WARNS("SETTINGS") << "Rayleigh Config Validation warnings: " << result["errors"] << LL_ENDL; + return false; + } + return true; +} + +bool validateAbsorptionLayers(LLSD &value) +{ + LLSettingsBase::validation_list_t absorptionValidations = absorptionValidationList(); + if (value.isArray()) + { + bool allGood = true; + for (LLSD::array_iterator itf = value.beginArray(); itf != value.endArray(); ++itf) + { + LLSD& layerConfig = (*itf); + if (layerConfig.type() == LLSD::Type::TypeMap) + { + if (!validateAbsorptionLayers(layerConfig)) + { + allGood = false; + } + } + else if (layerConfig.type() == LLSD::Type::TypeArray) + { + return validateAbsorptionLayers(layerConfig); + } + else + { + return LLSettingsBase::settingValidation(value, absorptionValidations); + } + } + return allGood; + } + llassert(value.type() == LLSD::Type::TypeMap); + LLSD result = LLSettingsBase::settingValidation(value, absorptionValidations); + if (result["errors"].size() > 0) + { + LL_WARNS("SETTINGS") << "Absorption Config Validation errors: " << result["errors"] << LL_ENDL; + return false; + } + if (result["warnings"].size() > 0) + { + LL_WARNS("SETTINGS") << "Absorption Config Validation warnings: " << result["errors"] << LL_ENDL; + return false; + } + return true; +} + +bool validateMieLayers(LLSD &value) +{ + LLSettingsBase::validation_list_t mieValidations = mieValidationList(); + if (value.isArray()) + { + bool allGood = true; + for (LLSD::array_iterator itf = value.beginArray(); itf != value.endArray(); ++itf) + { + LLSD& layerConfig = (*itf); + if (layerConfig.type() == LLSD::Type::TypeMap) + { + if (!validateMieLayers(layerConfig)) + { + allGood = false; + } + } + else if (layerConfig.type() == LLSD::Type::TypeArray) + { + return validateMieLayers(layerConfig); + } + else + { + return LLSettingsBase::settingValidation(value, mieValidations); + } + } + return allGood; + } + LLSD result = LLSettingsBase::settingValidation(value, mieValidations); + if (result["errors"].size() > 0) + { + LL_WARNS("SETTINGS") << "Mie Config Validation errors: " << result["errors"] << LL_ENDL; + return false; + } + if (result["warnings"].size() > 0) + { + LL_WARNS("SETTINGS") << "Mie Config Validation warnings: " << result["errors"] << LL_ENDL; + return false; + } + return true; +} + +} + +//========================================================================= +LLSettingsSky::LLSettingsSky(const LLSD &data) : + LLSettingsBase(data), + mNextSunTextureId(), + mNextMoonTextureId(), + mNextCloudTextureId() +{ +} + +LLSettingsSky::LLSettingsSky(): + LLSettingsBase(), + mNextSunTextureId(), + mNextMoonTextureId(), + mNextCloudTextureId() +{ +} + +void LLSettingsSky::blend(const LLSettingsBase::ptr_t &end, F64 blendf) +{ + LLSettingsSky::ptr_t other = std::static_pointer_cast<LLSettingsSky>(end); + LLSD blenddata = interpolateSDMap(mSettings, other->mSettings, blendf); + + replaceSettings(blenddata); + setBlendFactor(blendf); + mNextSunTextureId = other->getSunTextureId(); + mNextMoonTextureId = other->getMoonTextureId(); + mNextCloudTextureId = other->getCloudNoiseTextureId(); +} + + +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 +{ + return LLSettingsSky::validationList(); +} + +LLSettingsSky::validation_list_t LLSettingsSky::validationList() +{ + 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]]]]]]]]]] + +// LEGACY_ATMOSPHERICS + 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_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_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_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_BLOOM_TEXTUREID, true, LLSD::TypeUUID)); + 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_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_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_TEXTUREID, false, LLSD::TypeUUID)); + + validation.push_back(Validator(SETTING_PLANET_RADIUS, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(1000.0f)(32768.0f))))); + + validation.push_back(Validator(SETTING_SKY_BOTTOM_RADIUS, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(1000.0f)(32768.0f))))); + + validation.push_back(Validator(SETTING_SKY_TOP_RADIUS, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(1000.0f)(32768.0f))))); + + validation.push_back(Validator(SETTING_SUN_ARC_RADIANS, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(0.1f))))); + + validation.push_back(Validator(SETTING_RAYLEIGH_CONFIG, true, LLSD::TypeArray, &validateRayleighLayers)); + validation.push_back(Validator(SETTING_ABSORPTION_CONFIG, true, LLSD::TypeArray, &validateAbsorptionLayers)); + validation.push_back(Validator(SETTING_MIE_CONFIG, true, LLSD::TypeArray, &validateMieLayers)); + } + return validation; +} + +LLSD LLSettingsSky::rayleighConfigDefault() +{ + LLSD dflt_rayleigh; + dflt_rayleigh[SETTING_DENSITY_PROFILE_WIDTH] = 0.0f; // 0 -> the entire atmosphere + dflt_rayleigh[SETTING_DENSITY_PROFILE_EXP_TERM] = 1.0f; + dflt_rayleigh[SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR] = -1.0f / 8000.0f; + dflt_rayleigh[SETTING_DENSITY_PROFILE_LINEAR_TERM] = 0.0f; + dflt_rayleigh[SETTING_DENSITY_PROFILE_CONSTANT_TERM] = 0.0f; + return dflt_rayleigh; +} + +LLSD LLSettingsSky::absorptionConfigDefault() +{ +// absorption (ozone) has two linear ramping zones + LLSD dflt_absorption_layer_a; + dflt_absorption_layer_a[SETTING_DENSITY_PROFILE_WIDTH] = 25000.0f; // 0 -> the entire atmosphere + dflt_absorption_layer_a[SETTING_DENSITY_PROFILE_EXP_TERM] = 0.0f; + dflt_absorption_layer_a[SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR] = 0.0f; + dflt_absorption_layer_a[SETTING_DENSITY_PROFILE_LINEAR_TERM] = -1.0f / 25000.0f; + dflt_absorption_layer_a[SETTING_DENSITY_PROFILE_CONSTANT_TERM] = -2.0f / 3.0f; + + LLSD dflt_absorption_layer_b; + dflt_absorption_layer_b[SETTING_DENSITY_PROFILE_WIDTH] = 0.0f; // 0 -> remainder of the atmosphere + dflt_absorption_layer_b[SETTING_DENSITY_PROFILE_EXP_TERM] = 0.0f; + dflt_absorption_layer_b[SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR] = 0.0f; + dflt_absorption_layer_b[SETTING_DENSITY_PROFILE_LINEAR_TERM] = -1.0f / 15000.0f; + dflt_absorption_layer_b[SETTING_DENSITY_PROFILE_CONSTANT_TERM] = 8.0f / 3.0f; + + LLSD dflt_absorption; + dflt_absorption.append(dflt_absorption_layer_a); + dflt_absorption.append(dflt_absorption_layer_b); + return dflt_absorption; +} + +LLSD LLSettingsSky::mieConfigDefault() +{ + LLSD dflt_mie; + dflt_mie[SETTING_DENSITY_PROFILE_WIDTH] = 0.0f; // 0 -> the entire atmosphere + dflt_mie[SETTING_DENSITY_PROFILE_EXP_TERM] = 1.0f; + dflt_mie[SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR] = -1.0f / 1200.0f; + dflt_mie[SETTING_DENSITY_PROFILE_LINEAR_TERM] = 0.0f; + dflt_mie[SETTING_DENSITY_PROFILE_CONSTANT_TERM] = 0.0f; + dflt_mie[SETTING_MIE_ANISOTROPY_FACTOR] = 0.9f; + return dflt_mie; +} + +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 +// LEGACY_ATMOSPHERICS + 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_DENSITY_MULTIPLIER] = LLSD::Real(0.0001); + dfltsetting[SETTING_DISTANCE_MULTIPLIER] = LLSD::Real(0.8000); + dfltsetting[SETTING_HAZE_DENSITY] = LLSD::Real(0.6999); + dfltsetting[SETTING_HAZE_HORIZON] = LLSD::Real(0.1899); + + 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_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_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] = IMG_BLOOM1; + dfltsetting[SETTING_CLOUD_TEXTUREID] = DEFAULT_CLOUD_ID; + dfltsetting[SETTING_MOON_TEXTUREID] = DEFAULT_MOON_ID; // gMoonTextureID; // These two are returned by the login... wow! + dfltsetting[SETTING_SUN_TEXTUREID] = DEFAULT_SUN_ID; // gSunTextureID; + + dfltsetting[SETTING_TYPE] = "sky"; + + // defaults are for earth... + dfltsetting[SETTING_PLANET_RADIUS] = 6360.0f; + dfltsetting[SETTING_SKY_BOTTOM_RADIUS] = 6360.0f; + dfltsetting[SETTING_SKY_TOP_RADIUS] = 6420.0f; + dfltsetting[SETTING_SUN_ARC_RADIANS] = 0.00935f / 2.0f; + + // These are technically capable of handling multiple layers of density config + // and so are expected to be an array, but we make an array of size 1 w/ each default density config + dfltsetting[SETTING_RAYLEIGH_CONFIG].append(rayleighConfigDefault()); + dfltsetting[SETTING_MIE_CONFIG].append(mieConfigDefault()); + dfltsetting[SETTING_ABSORPTION_CONFIG].append(absorptionConfigDefault()); + + return dfltsetting; +} + +LLSD LLSettingsSky::translateLegacySettings(LLSD legacy) +{ + LLSD newsettings(defaults()); + +// AdvancedAtmospherics TODO +// These need to be translated into density profile info in the new settings format... +// LEGACY_ATMOSPHERICS + 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_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_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_RAYLEIGH_CONFIG)) + { + newsettings[SETTING_RAYLEIGH_CONFIG].append(rayleighConfigDefault()); + } + + if (!legacy.has(SETTING_ABSORPTION_CONFIG)) + { + newsettings[SETTING_ABSORPTION_CONFIG].append(absorptionConfigDefault()); + } + + if (!legacy.has(SETTING_MIE_CONFIG)) + { + newsettings[SETTING_MIE_CONFIG].append(mieConfigDefault()); + } + + 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_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_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_PLANET_RADIUS)) + { + newsettings[SETTING_PLANET_RADIUS] = LLSD::Real(legacy[SETTING_PLANET_RADIUS].asReal()); + } + else + { + newsettings[SETTING_PLANET_RADIUS] = 6360.0f; + } + + if (legacy.has(SETTING_SKY_BOTTOM_RADIUS)) + { + newsettings[SETTING_SKY_BOTTOM_RADIUS] = LLSD::Real(legacy[SETTING_SKY_BOTTOM_RADIUS].asReal()); + } + else + { + newsettings[SETTING_SKY_BOTTOM_RADIUS] = 6360.0f; + } + + if (legacy.has(SETTING_SKY_TOP_RADIUS)) + { + newsettings[SETTING_SKY_TOP_RADIUS] = LLSD::Real(legacy[SETTING_SKY_TOP_RADIUS].asReal()); + } + else + { + newsettings[SETTING_SKY_TOP_RADIUS] = 6420.0f; + } + + if (legacy.has(SETTING_SUN_ARC_RADIANS)) + { + newsettings[SETTING_SUN_ARC_RADIANS] = LLSD::Real(legacy[SETTING_SUN_ARC_RADIANS].asReal()); + } + else + { + newsettings[SETTING_SUN_ARC_RADIANS] = 0.00935f / 2.0f; + } + + 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() +{ + +// LEGACY_ATMOSPHERICS + 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); + if (body_az[1] < 0.0f) + azimuth = F_TWO_PI - azimuth; + } + else + azimuth = 0.0f; + + if (fabs(body_al.normalize()) > 0.001) + { + altitude = angle_between(DUE_EAST, body_al); + if (body_al[2] < 0.0f) + { + altitude = F_TWO_PI - altitude; + } + } + else + altitude = 0.0f; + } +} + + diff --git a/indra/llinventory/llsettingssky.h b/indra/llinventory/llsettingssky.h new file mode 100644 index 0000000000..9379cd37c3 --- /dev/null +++ b/indra/llinventory/llsettingssky.h @@ -0,0 +1,531 @@ +/** +* @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_DENSITY_MULTIPLIER; + static const std::string SETTING_DISTANCE_MULTIPLIER; + static const std::string SETTING_HAZE_DENSITY; + static const std::string SETTING_HAZE_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_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_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_TEXTUREID; + + static const std::string SETTING_PLANET_RADIUS; + static const std::string SETTING_SKY_BOTTOM_RADIUS; + static const std::string SETTING_SKY_TOP_RADIUS; + static const std::string SETTING_SUN_ARC_RADIANS; + + static const std::string SETTING_RAYLEIGH_CONFIG; + static const std::string SETTING_MIE_CONFIG; + static const std::string SETTING_ABSORPTION_CONFIG; + + static const std::string KEY_DENSITY_PROFILE; + static const std::string SETTING_DENSITY_PROFILE_WIDTH; + static const std::string SETTING_DENSITY_PROFILE_EXP_TERM; + static const std::string SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR; + static const std::string SETTING_DENSITY_PROFILE_LINEAR_TERM; + static const std::string SETTING_DENSITY_PROFILE_CONSTANT_TERM; + static const std::string SETTING_MIE_ANISOTROPY_FACTOR; + + static const LLUUID DEFAULT_SUN_ID; + static const LLUUID DEFAULT_MOON_ID; + static const LLUUID DEFAULT_CLOUD_ID; + + typedef std::shared_ptr<LLSettingsSky> ptr_t; + typedef std::pair<F32, F32> azimalt_t; + + //--------------------------------------------------------------------- + LLSettingsSky(const LLSD &data); + virtual ~LLSettingsSky() { }; + + virtual ptr_t buildClone() = 0; + + //--------------------------------------------------------------------- + virtual std::string getSettingType() const override { return std::string("sky"); } + virtual LLSettingsType::type_e getSettingTypeValue() const override { return LLSettingsType::ST_SKY; } + + + // Settings status + virtual void blend(const LLSettingsBase::ptr_t &end, F64 blendf) override; + + static LLSD defaults(); + + LLUUID getBloomTextureId() const + { + return mSettings[SETTING_BLOOM_TEXTUREID].asUUID(); + } + + //--------------------------------------------------------------------- + LLColor3 getAmbientColor() const + { + return LLColor3(mSettings[SETTING_AMBIENT]); + } + + void setAmbientColor(const LLColor3 &val) + { + setValue(SETTING_AMBIENT, val); + } + + 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); + } + + 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 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); + } + + 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(); + } + + void setCloudNoiseTextureId(const LLUUID &id) + { + setValue(SETTING_CLOUD_TEXTUREID, id); + } + + 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 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); + } + + 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(); + } + + void setMaxY(F32 val) + { + setValue(SETTING_MAX_Y, val); + } + + 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(); + } + + void setMoonTextureId(LLUUID id) + { + setValue(SETTING_MOON_TEXTUREID, id); + } + + 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_TEXTUREID].asUUID(); + } + + void setSunTextureId(LLUUID id) + { + setValue(SETTING_SUN_TEXTUREID, id); + } + + // 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; + } + + //===================================================================== + virtual void loadTextures() { }; + + //===================================================================== + virtual validation_list_t getValidationList() const override; + static validation_list_t validationList(); + + static LLSD translateLegacySettings(LLSD legacy); + + //===================================================================== + // transient properties used in animations. + LLUUID getNextSunTextureId() const + { + return mNextSunTextureId; + } + + LLUUID getNextMoonTextureId() const + { + return mNextMoonTextureId; + } + + LLUUID getNextCloudNoiseTextureId() const + { + return mNextCloudTextureId; + } + + virtual LLSettingsBase::ptr_t buildDerivedClone() override { return buildClone(); } + +protected: + 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; + + LLSettingsSky(); + + virtual stringset_t getSlerpKeys() const override; + + virtual void updateSettings() override; + +private: + static LLSD rayleighConfigDefault(); + static LLSD absorptionConfigDefault(); + static LLSD mieConfigDefault(); + + 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; + + LLUUID mNextSunTextureId; + LLUUID mNextMoonTextureId; + LLUUID mNextCloudTextureId; + + typedef std::map<std::string, S32> 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..c6798945a3 --- /dev/null +++ b/indra/llinventory/llsettingswater.cpp @@ -0,0 +1,226 @@ +/** +* @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 <algorithm> +#include <boost/make_shared.hpp> +#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), + mNextNormalMapID() +{ +} + +LLSettingsWater::LLSettingsWater() : + LLSettingsBase(), + mNextNormalMapID() +{ +} + +//========================================================================= +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(); + + dfltsetting[SETTING_TYPE] = "water"; + + 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, F64 blendf) +{ + LLSettingsWater::ptr_t other = std::static_pointer_cast<LLSettingsWater>(end); + LLSD blenddata = interpolateSDMap(mSettings, other->mSettings, blendf); + + replaceSettings(blenddata); + setBlendFactor(blendf); + mNextNormalMapID = other->getNormalMapID(); +} + +LLSettingsWater::validation_list_t LLSettingsWater::getValidationList() const +{ + return LLSettingsWater::validationList(); +} + +LLSettingsWater::validation_list_t LLSettingsWater::validationList() +{ + 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..acae903e92 --- /dev/null +++ b/indra/llinventory/llsettingswater.h @@ -0,0 +1,239 @@ +/** +* @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 std::shared_ptr<LLSettingsWater> ptr_t; + + //--------------------------------------------------------------------- + LLSettingsWater(const LLSD &data); + virtual ~LLSettingsWater() { }; + + virtual ptr_t buildClone() = 0; + + //--------------------------------------------------------------------- + virtual std::string getSettingType() const override { return std::string("water"); } + virtual LLSettingsType::type_e getSettingTypeValue() const override { return LLSettingsType::ST_WATER; } + + // Settings status + virtual void blend(const LLSettingsBase::ptr_t &end, F64 blendf) override; + + 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; + } + + //------------------------------------------- + LLUUID getNextNormalMapID() const + { + return mNextNormalMapID; + } + + + virtual validation_list_t getValidationList() const override; + static validation_list_t validationList(); + + static LLSD translateLegacySettings(LLSD legacy); + + virtual LLSettingsBase::ptr_t buildDerivedClone() override { return buildClone(); } + +protected: + 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; + + LLSettingsWater(); + + LLVector4 mWaterPlane; + F32 mWaterFogKS; + +private: + LLUUID mNextNormalMapID; +}; + +#endif diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt index 4c8bcdac91..61d13c0b1c 100644 --- a/indra/llmath/CMakeLists.txt +++ b/indra/llmath/CMakeLists.txt @@ -87,6 +87,7 @@ set(llmath_HEADER_FILES raytrace.h v2math.h v3color.h + v3colorutil.h v3dmath.h v3math.h v4color.h diff --git a/indra/llmath/llquaternion.cpp b/indra/llmath/llquaternion.cpp index 47374c287f..a8d9eba2a0 100644 --- a/indra/llmath/llquaternion.cpp +++ b/indra/llmath/llquaternion.cpp @@ -103,6 +103,10 @@ LLQuaternion::LLQuaternion(const LLVector3 &x_axis, *this = mat.quaternion(); normalize(); } +LLQuaternion::LLQuaternion(const LLSD &sd) +{ + setValue(sd); +} // Quatizations void LLQuaternion::quantize16(F32 lower, F32 upper) @@ -860,6 +864,26 @@ void LLQuaternion::getAngleAxis(F32* angle, LLVector3 &vec) const } } +const LLQuaternion& LLQuaternion::setFromAzimuthAndAltitude(F32 azimuthRadians, F32 altitudeRadians) +{ + // euler angle inputs are complements of azimuth/altitude which are measured from zenith + F32 pitch = llclamp(F_PI_BY_TWO - altitudeRadians, 0.0f, F_PI_BY_TWO); + F32 yaw = llclamp(F_PI_BY_TWO - azimuthRadians, 0.0f, F_PI_BY_TWO); + setEulerAngles(0.0f, pitch, yaw); + return *this; +} + +void LLQuaternion::getAzimuthAndAltitude(F32 &azimuthRadians, F32 &altitudeRadians) +{ + F32 rick_roll; + F32 pitch; + F32 yaw; + getEulerAngles(&rick_roll, &pitch, &yaw); + // make these measured from zenith + altitudeRadians = llclamp(F_PI_BY_TWO - pitch, 0.0f, F_PI_BY_TWO); + azimuthRadians = llclamp(F_PI_BY_TWO - yaw, 0.0f, F_PI_BY_TWO); +} + // quaternion does not need to be normalized void LLQuaternion::getEulerAngles(F32 *roll, F32 *pitch, F32 *yaw) const { diff --git a/indra/llmath/llquaternion.h b/indra/llmath/llquaternion.h index aa0b1752f4..e2cdad548b 100644 --- a/indra/llmath/llquaternion.h +++ b/indra/llmath/llquaternion.h @@ -28,6 +28,7 @@ #define LLQUATERNION_H #include <iostream> +#include "llsd.h" #ifndef LLMATH_H //enforce specific include order to avoid tangling inline dependencies #error "Please include llmath.h first." @@ -63,6 +64,10 @@ public: LLQuaternion(const LLVector3 &x_axis, const LLVector3 &y_axis, const LLVector3 &z_axis); // Initializes Quaternion from Matrix3 = [x_axis ; y_axis ; z_axis] + explicit LLQuaternion(const LLSD &sd); // Initializes Quaternion from LLSD array. + + LLSD getValue() const; + void setValue(const LLSD& sd); BOOL isIdentity() const; BOOL isNotIdentity() const; @@ -79,7 +84,8 @@ public: const LLQuaternion& set(const F32 *q); // Sets Quaternion to normalize(quat[VX], quat[VY], quat[VZ], quat[VW]) const LLQuaternion& set(const LLMatrix3 &mat); // Sets Quaternion to mat2quat(mat) const LLQuaternion& set(const LLMatrix4 &mat); // Sets Quaternion to mat2quat(mat) - + const LLQuaternion& setFromAzimuthAndAltitude(F32 azimuth, F32 altitude); + const LLQuaternion& setAngleAxis(F32 angle, F32 x, F32 y, F32 z); // Sets Quaternion to axis_angle2quat(angle, x, y, z) const LLQuaternion& setAngleAxis(F32 angle, const LLVector3 &vec); // Sets Quaternion to axis_angle2quat(angle, vec) const LLQuaternion& setAngleAxis(F32 angle, const LLVector4 &vec); // Sets Quaternion to axis_angle2quat(angle, vec) @@ -100,6 +106,7 @@ public: void getAngleAxis(F32* angle, F32* x, F32* y, F32* z) const; // returns rotation in radians about axis x,y,z void getAngleAxis(F32* angle, LLVector3 &vec) const; void getEulerAngles(F32 *roll, F32* pitch, F32 *yaw) const; + void getAzimuthAndAltitude(F32 &azimuth, F32 &altitude); F32 normalize(); // Normalizes Quaternion and returns magnitude F32 normQuat(); // deprecated @@ -166,6 +173,25 @@ public: //static U32 mMultCount; }; +inline LLSD LLQuaternion::getValue() const +{ + LLSD ret; + ret[0] = mQ[0]; + ret[1] = mQ[1]; + ret[2] = mQ[2]; + ret[3] = mQ[3]; + return ret; +} + +inline void LLQuaternion::setValue(const LLSD& sd) +{ + mQ[0] = sd[0].asReal(); + mQ[1] = sd[1].asReal(); + mQ[2] = sd[2].asReal(); + mQ[3] = sd[3].asReal(); +} + + // checker inline BOOL LLQuaternion::isFinite() const { diff --git a/indra/llmath/v2math.cpp b/indra/llmath/v2math.cpp index a0cd642853..a24571f2c8 100644 --- a/indra/llmath/v2math.cpp +++ b/indra/llmath/v2math.cpp @@ -118,7 +118,7 @@ LLSD LLVector2::getValue() const return ret; } -void LLVector2::setValue(LLSD& sd) +void LLVector2::setValue(const LLSD& sd) { mV[0] = (F32) sd[0].asReal(); mV[1] = (F32) sd[1].asReal(); diff --git a/indra/llmath/v2math.h b/indra/llmath/v2math.h index 8d5db96f5e..2335a2e327 100644 --- a/indra/llmath/v2math.h +++ b/indra/llmath/v2math.h @@ -49,6 +49,7 @@ class LLVector2 LLVector2(F32 x, F32 y); // Initializes LLVector2 to (x. y) LLVector2(const F32 *vec); // Initializes LLVector2 to (vec[0]. vec[1]) explicit LLVector2(const LLVector3 &vec); // Initializes LLVector2 to (vec[0]. vec[1]) + explicit LLVector2(const LLSD &sd); // Clears LLVector2 to (0, 0). DEPRECATED - prefer zeroVec. void clear(); @@ -61,7 +62,7 @@ class LLVector2 void set(const F32 *vec); // Sets LLVector2 to vec LLSD getValue() const; - void setValue(LLSD& sd); + void setValue(const LLSD& sd); void setVec(F32 x, F32 y); // deprecated void setVec(const LLVector2 &vec); // deprecated @@ -145,6 +146,10 @@ inline LLVector2::LLVector2(const LLVector3 &vec) mV[VY] = vec.mV[VY]; } +inline LLVector2::LLVector2(const LLSD &sd) +{ + setValue(sd); +} // Clear and Assignment Functions diff --git a/indra/llmath/v3colorutil.h b/indra/llmath/v3colorutil.h new file mode 100644 index 0000000000..6d8cd9329b --- /dev/null +++ b/indra/llmath/v3colorutil.h @@ -0,0 +1,115 @@ +/** + * @file v3color.h + * @brief LLColor3 class header file. + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, 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_V3COLORUTIL_H +#define LL_V3COLORUTIL_H + +#include "v3color.h" + +inline LLColor3 componentDiv(LLColor3 const &left, LLColor3 const & right) +{ + return LLColor3(left.mV[0] / right.mV[0], + left.mV[1] / right.mV[1], + left.mV[2] / right.mV[2]); +} + + +inline LLColor3 componentMult(LLColor3 const &left, LLColor3 const & right) +{ + return LLColor3(left.mV[0] * right.mV[0], + left.mV[1] * right.mV[1], + left.mV[2] * right.mV[2]); +} + + +inline LLColor3 componentExp(LLColor3 const &v) +{ + return LLColor3(exp(v.mV[0]), + exp(v.mV[1]), + exp(v.mV[2])); +} + +inline LLColor3 componentPow(LLColor3 const &v, F32 exponent) +{ + return LLColor3(pow(v.mV[0], exponent), + pow(v.mV[1], exponent), + pow(v.mV[2], exponent)); +} + +inline LLColor3 componentSaturate(LLColor3 const &v) +{ + return LLColor3(std::max(std::min(v.mV[0], 1.f), 0.f), + std::max(std::min(v.mV[1], 1.f), 0.f), + std::max(std::min(v.mV[2], 1.f), 0.f)); +} + + +inline LLColor3 componentSqrt(LLColor3 const &v) +{ + return LLColor3(sqrt(v.mV[0]), + sqrt(v.mV[1]), + sqrt(v.mV[2])); +} + +inline void componentMultBy(LLColor3 & left, LLColor3 const & right) +{ + left.mV[0] *= right.mV[0]; + left.mV[1] *= right.mV[1]; + left.mV[2] *= right.mV[2]; +} + +inline LLColor3 colorMix(LLColor3 const & left, LLColor3 const & right, F32 amount) +{ + return (left + ((right - left) * amount)); +} + +inline LLColor3 smear(F32 val) +{ + return LLColor3(val, val, val); +} + +inline F32 color_intens(const LLColor3 &col) +{ + return col.mV[0] + col.mV[1] + col.mV[2]; +} + +inline F32 color_max(const LLColor3 &col) +{ + return llmax(col.mV[0], col.mV[1], col.mV[2]); +} + +inline F32 color_max(const LLColor4 &col) +{ + return llmax(col.mV[0], col.mV[1], col.mV[2]); +} + + +inline F32 color_min(const LLColor3 &col) +{ + return llmin(col.mV[0], col.mV[1], col.mV[2]); +} + +#endif diff --git a/indra/llmath/v4color.h b/indra/llmath/v4color.h index 8f353ead5a..614cdc9f3e 100644 --- a/indra/llmath/v4color.h +++ b/indra/llmath/v4color.h @@ -114,9 +114,11 @@ class LLColor4 friend LLColor4 operator-(const LLColor4 &a, const LLColor4 &b); // Return vector a minus b friend LLColor4 operator*(const LLColor4 &a, const LLColor4 &b); // Return component wise a * b friend LLColor4 operator*(const LLColor4 &a, F32 k); // Return rgb times scaler k (no alpha change) + friend LLColor4 operator/(const LLColor4 &a, F32 k); // Return rgb divided by scalar k (no alpha change) friend LLColor4 operator*(F32 k, const LLColor4 &a); // Return rgb times scaler k (no alpha change) friend LLColor4 operator%(const LLColor4 &a, F32 k); // Return alpha times scaler k (no rgb change) friend LLColor4 operator%(F32 k, const LLColor4 &a); // Return alpha times scaler k (no rgb change) + friend bool operator==(const LLColor4 &a, const LLColor4 &b); // Return a == b friend bool operator!=(const LLColor4 &a, const LLColor4 &b); // Return a != b @@ -477,6 +479,15 @@ inline LLColor4 operator*(const LLColor4 &a, F32 k) a.mV[VW]); } +inline LLColor4 operator/(const LLColor4 &a, F32 k) +{ + return LLColor4( + a.mV[VX] / k, + a.mV[VY] / k, + a.mV[VZ] / k, + a.mV[VW]); +} + inline LLColor4 operator*(F32 k, const LLColor4 &a) { // only affects rgb (not a!) diff --git a/indra/llmath/v4math.h b/indra/llmath/v4math.h index 623c8b2003..3f6d480ed9 100644 --- a/indra/llmath/v4math.h +++ b/indra/llmath/v4math.h @@ -30,6 +30,7 @@ #include "llerror.h" #include "llmath.h" #include "v3math.h" +#include "v2math.h" class LLMatrix3; class LLMatrix4; @@ -46,8 +47,11 @@ class LLVector4 LLVector4(); // Initializes LLVector4 to (0, 0, 0, 1) explicit LLVector4(const F32 *vec); // Initializes LLVector4 to (vec[0]. vec[1], vec[2], vec[3]) explicit LLVector4(const F64 *vec); // Initialized LLVector4 to ((F32) vec[0], (F32) vec[1], (F32) vec[3], (F32) vec[4]); + explicit LLVector4(const LLVector2 &vec); + explicit LLVector4(const LLVector2 &vec, F32 z, F32 w); explicit LLVector4(const LLVector3 &vec); // Initializes LLVector4 to (vec, 1) explicit LLVector4(const LLVector3 &vec, F32 w); // Initializes LLVector4 to (vec, w) + explicit LLVector4(const LLSD &sd); LLVector4(F32 x, F32 y, F32 z); // Initializes LLVector4 to (x. y, z, 1) LLVector4(F32 x, F32 y, F32 z, F32 w); @@ -61,6 +65,15 @@ class LLVector4 return ret; } + void setValue(const LLSD& sd) + { + mV[0] = sd[0].asReal(); + mV[1] = sd[1].asReal(); + mV[2] = sd[2].asReal(); + mV[3] = sd[3].asReal(); + } + + inline BOOL isFinite() const; // checks to see if all values of LLVector3 are finite inline void clear(); // Clears LLVector4 to (0, 0, 0, 1) @@ -175,6 +188,22 @@ inline LLVector4::LLVector4(const F64 *vec) mV[VW] = (F32) vec[VW]; } +inline LLVector4::LLVector4(const LLVector2 &vec) +{ + mV[VX] = vec[VX]; + mV[VY] = vec[VY]; + mV[VZ] = 0.f; + mV[VW] = 0.f; +} + +inline LLVector4::LLVector4(const LLVector2 &vec, F32 z, F32 w) +{ + mV[VX] = vec[VX]; + mV[VY] = vec[VY]; + mV[VZ] = z; + mV[VW] = w; +} + inline LLVector4::LLVector4(const LLVector3 &vec) { mV[VX] = vec.mV[VX]; @@ -191,6 +220,11 @@ inline LLVector4::LLVector4(const LLVector3 &vec, F32 w) mV[VW] = w; } +inline LLVector4::LLVector4(const LLSD &sd) +{ + setValue(sd); +} + inline BOOL LLVector4::isFinite() const { diff --git a/indra/llmessage/llassetstorage.cpp b/indra/llmessage/llassetstorage.cpp index 596d57c7b7..2b12a062c3 100644 --- a/indra/llmessage/llassetstorage.cpp +++ b/indra/llmessage/llassetstorage.cpp @@ -62,6 +62,42 @@ const LLUUID CATEGORIZE_LOST_AND_FOUND_ID(std::string("00000000-0000-0000-0000-0 const U64 TOXIC_ASSET_LIFETIME = (120 * 1000000); // microseconds +namespace +{ + bool operator == (const LLAssetStorage::LLGetAssetCallback &lhs, const LLAssetStorage::LLGetAssetCallback &rhs) + { + auto fnPtrLhs = lhs.target<LLAssetStorage::LLGetAssetCallback>(); + auto fnPtrRhs = rhs.target<LLAssetStorage::LLGetAssetCallback>(); + if (fnPtrLhs && fnPtrRhs) + return (*fnPtrLhs == *fnPtrRhs); + else if (!fnPtrLhs && !fnPtrRhs) + return true; + return false; + } + +// Rider: This is the general case of the operator declared above. The code compares the callback +// passed into the LLAssetStorage functions to determine if there are duplicated requests for an +// asset. Unfortunately std::function does not provide a direct way to compare two variables so +// we define the operator here. +// XCode is not very happy with the variadic temples in use below so we will just define the specific +// case of comparing two LLGetAssetCallback objects since that is all we really use. +// +// template<typename T, typename... U> +// bool operator == (const std::function<T(U...)> &a, const std::function <T(U...)> &b) +// { +// typedef T(fnType)(U...); +// +// auto fnPtrA = a.target<T(*)(U...)>(); +// auto fnPtrB = b.target<T(*)(U...)>(); +// if (fnPtrA && fnPtrB) +// return (*fnPtrA == *fnPtrB); +// else if (!fnPtrA && !fnPtrB) +// return true; +// return false; +// } + +} + ///---------------------------------------------------------------------------- /// LLAssetInfo ///---------------------------------------------------------------------------- @@ -160,7 +196,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 +227,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), @@ -449,7 +485,7 @@ bool LLAssetStorage::findInStaticVFSAndInvokeCallback(const LLUUID& uuid, LLAsse // IW - uuid is passed by value to avoid side effects, please don't re-add & void LLAssetStorage::getAssetData(const LLUUID uuid, LLAssetType::EType type, - LLGetAssetCallback callback, + LLAssetStorage::LLGetAssetCallback callback, void *user_data, BOOL is_priority) { @@ -496,7 +532,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 +1366,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<void(*)(LLVFS *, const LLUUID &, LLAssetType::EType, void *, S32, LLExtStat)>(); + 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 <string> +#include <functional> #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<void(LLVFS *vfs, const LLUUID &asset_id, LLAssetType::EType asset_type, void *user_data, S32 status, LLExtStat ext_status)> LLGetAssetCallback; +typedef std::function<void(const LLUUID &asset_id, void *user_data, S32 status, LLExtStat ext_status)> 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<LLUUID,U64,lluuid_less> 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/llplugin/llpluginprocesschild.cpp b/indra/llplugin/llpluginprocesschild.cpp index e24d222cb6..594793cf56 100644 --- a/indra/llplugin/llpluginprocesschild.cpp +++ b/indra/llplugin/llpluginprocesschild.cpp @@ -253,7 +253,7 @@ void LLPluginProcessChild::sleep(F64 seconds) } else { - ms_sleep((int)(seconds * 1000.0f)); + ms_sleep((int)(seconds * 1000.0f)); } } diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt index 331f988382..26aaf10d07 100644 --- a/indra/llrender/CMakeLists.txt +++ b/indra/llrender/CMakeLists.txt @@ -13,6 +13,7 @@ include(LLVFS) include(LLWindow) include(LLXML) include(LLVFS) +include(Atmosphere) include_directories( ${FREETYPE_INCLUDE_DIRS} @@ -24,6 +25,7 @@ include_directories( ${LLWINDOW_INCLUDE_DIRS} ${LLXML_INCLUDE_DIRS} ${LLVFS_INCLUDE_DIRS} + ${ATMOSPHERE_INCLUDE_DIR} ) include_directories(SYSTEM ${LLCOMMON_SYSTEM_INCLUDE_DIRS} @@ -31,6 +33,7 @@ include_directories(SYSTEM ) set(llrender_SOURCE_FILES + llatmosphere.cpp llcubemap.cpp llfontbitmapcache.cpp llfontfreetype.cpp @@ -56,6 +59,7 @@ set(llrender_SOURCE_FILES set(llrender_HEADER_FILES CMakeLists.txt + llatmosphere.h llcubemap.h llfontgl.h llfontfreetype.h @@ -103,7 +107,9 @@ if (BUILD_HEADLESS) ${LLXML_LIBRARIES} ${LLVFS_LIBRARIES} ${LLWINDOW_HEADLESS_LIBRARIES} - ${OPENGL_HEADLESS_LIBRARIES}) + ${LIBATMOSPHERE_LIBRARIES} + ${OPENGL_HEADLESS_LIBRARIES} + ) endif (BUILD_HEADLESS) @@ -126,5 +132,7 @@ target_link_libraries(llrender ${LLVFS_LIBRARIES} ${LLWINDOW_LIBRARIES} ${FREETYPE_LIBRARIES} - ${OPENGL_LIBRARIES}) + ${LIBATMOSPHERE_LIBRARIES} + ${OPENGL_LIBRARIES} + ) diff --git a/indra/llrender/llatmosphere.cpp b/indra/llrender/llatmosphere.cpp new file mode 100644 index 0000000000..6ce5292839 --- /dev/null +++ b/indra/llrender/llatmosphere.cpp @@ -0,0 +1,221 @@ +/** + * @file llatmosphere.cpp + * @brief LLAtmosphere integration impl + * + * $LicenseInfo:firstyear=2018&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2018, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llatmosphere.h" +#include "llfasttimer.h" +#include "llsys.h" +#include "llglheaders.h" +#include "llrender.h" +#include "llshadermgr.h" +#include "llglslshader.h" + +LLAtmosphere* gAtmosphere = nullptr; + +void LLAtmosphere::initClass() +{ + if (!gAtmosphere) + { + gAtmosphere = new LLAtmosphere; + } +} + +void LLAtmosphere::cleanupClass() +{ + if(gAtmosphere) + { + delete gAtmosphere; + } + gAtmosphere = NULL; +} + +LLAtmosphere::LLAtmosphere() +{ + // Init libatmosphere model + m_config.num_scattering_orders = 4; + + // Values from "Reference Solar Spectral Irradiance: ASTM G-173", ETR column + // (see http://rredc.nrel.gov/solar/spectra/am1.5/ASTMG173/ASTMG173.html), + // summed and averaged in each bin (e.g. the value for 360nm is the average + // of the ASTM G-173 values for all wavelengths between 360 and 370nm). + // Values in W.m^-2. + const int kLambdaMin = 360; + const int kLambdaMax = 830; + const double kSolarIrradiance[48] = { + 1.11776, 1.14259, 1.01249, 1.14716, 1.72765, 1.73054, 1.6887, 1.61253, + 1.91198, 2.03474, 2.02042, 2.02212, 1.93377, 1.95809, 1.91686, 1.8298, + 1.8685, 1.8931, 1.85149, 1.8504, 1.8341, 1.8345, 1.8147, 1.78158, 1.7533, + 1.6965, 1.68194, 1.64654, 1.6048, 1.52143, 1.55622, 1.5113, 1.474, 1.4482, + 1.41018, 1.36775, 1.34188, 1.31429, 1.28303, 1.26758, 1.2367, 1.2082, + 1.18737, 1.14683, 1.12362, 1.1058, 1.07124, 1.04992 + }; + + // Values from http://www.iup.uni-bremen.de/gruppen/molspec/databases/ + // referencespectra/o3spectra2011/index.html for 233K, summed and averaged in + // each bin (e.g. the value for 360nm is the average of the original values + // for all wavelengths between 360 and 370nm). Values in m^2. + const double kOzoneCrossSection[48] = { + 1.18e-27, 2.182e-28, 2.818e-28, 6.636e-28, 1.527e-27, 2.763e-27, 5.52e-27, + 8.451e-27, 1.582e-26, 2.316e-26, 3.669e-26, 4.924e-26, 7.752e-26, 9.016e-26, + 1.48e-25, 1.602e-25, 2.139e-25, 2.755e-25, 3.091e-25, 3.5e-25, 4.266e-25, + 4.672e-25, 4.398e-25, 4.701e-25, 5.019e-25, 4.305e-25, 3.74e-25, 3.215e-25, + 2.662e-25, 2.238e-25, 1.852e-25, 1.473e-25, 1.209e-25, 9.423e-26, 7.455e-26, + 6.566e-26, 5.105e-26, 4.15e-26, 4.228e-26, 3.237e-26, 2.451e-26, 2.801e-26, + 2.534e-26, 1.624e-26, 1.465e-26, 2.078e-26, 1.383e-26, 7.105e-27 + }; + + // From https://en.wikipedia.org/wiki/Dobson_unit, in molecules.m^-2. + const double kDobsonUnit = 2.687e20; + + // Maximum number density of ozone molecules, in m^-3 (computed so at to get + // 300 Dobson units of ozone - for this we divide 300 DU by the integral of + // the ozone density profile defined below, which is equal to 15km). + const double kMaxOzoneNumberDensity = 300.0 * kDobsonUnit / 15000.0; + + const double kSunAngularRadius = 0.00935 / 2.0; + const double kBottomRadius = 6360000.0; + const double kTopRadius = 6420000.0; + const double kRayleigh = 1.24062e-6; + const double kRayleighScaleHeight = 8000.0; + const double kMieScaleHeight = 1200.0; + const double kMieAngstromAlpha = 0.0; + const double kMieAngstromBeta = 5.328e-3; + const double kMieSingleScatteringAlbedo = 0.9; + const double kMiePhaseFunctionG = 0.8; + const double max_sun_zenith_angle = F_PI * 2.0 / 3.0; + + atmosphere::DensityProfileLayer rayleigh_density(0.0, 1.0, -1.0 / kRayleighScaleHeight, 0.0, 0.0); + atmosphere::DensityProfileLayer mie_density(0.0, 1.0, -1.0 / kMieScaleHeight, 0.0, 0.0); + + // Density profile increasing linearly from 0 to 1 between 10 and 25km, and + // decreasing linearly from 1 to 0 between 25 and 40km. This is an approximate + // profile from http://www.kln.ac.lk/science/Chemistry/Teaching_Resources/ + // Documents/Introduction%20to%20atmospheric%20chemistry.pdf (page 10). + std::vector<atmosphere::DensityProfileLayer> ozone_density; + ozone_density.push_back(atmosphere::DensityProfileLayer(25000.0, 0.0, 0.0, 1.0 / 15000.0, -2.0 / 3.0)); + ozone_density.push_back(atmosphere::DensityProfileLayer(0.0, 0.0, 0.0, -1.0 / 15000.0, 8.0 / 3.0)); + + std::vector<double> wavelengths; + std::vector<double> solar_irradiance; + std::vector<double> rayleigh_scattering; + std::vector<double> mie_scattering; + std::vector<double> mie_extinction; + std::vector<double> absorption_extinction; + std::vector<double> ground_albedo; + + for (int l = kLambdaMin; l <= kLambdaMax; l += 10) + { + double lambda = static_cast<double>(l) * 1e-3; // micro-meters + double mie = kMieAngstromBeta / kMieScaleHeight * pow(lambda, -kMieAngstromAlpha); + wavelengths.push_back(l); + solar_irradiance.push_back(kSolarIrradiance[(l - kLambdaMin) / 10]); + rayleigh_scattering.push_back(kRayleigh * pow(lambda, -4)); + mie_scattering.push_back(mie * kMieSingleScatteringAlbedo); + mie_extinction.push_back(mie); + absorption_extinction.push_back(kMaxOzoneNumberDensity * kOzoneCrossSection[(l - kLambdaMin) / 10]); + ground_albedo.push_back(0.1f); + } + + m_model = new atmosphere::Model( + wavelengths, + solar_irradiance, + kSunAngularRadius, + kBottomRadius, + kTopRadius, + {rayleigh_density}, + rayleigh_scattering, + {mie_density}, + mie_scattering, + mie_extinction, + kMiePhaseFunctionG, + ozone_density, + absorption_extinction, + ground_albedo, + max_sun_zenith_angle, + 1000.0, + 15, + false, + true); + + m_model->Init(m_config, m_textures); + + m_transmittance = new LLGLTexture; + m_scattering = new LLGLTexture; + m_mie_scattering = new LLGLTexture; + + m_transmittance->generateGLTexture(); + m_transmittance->setAddressMode(LLTexUnit::eTextureAddressMode::TAM_CLAMP); + m_transmittance->setFilteringOption(LLTexUnit::eTextureFilterOptions::TFO_BILINEAR); + m_transmittance->setExplicitFormat(GL_RGB16F_ARB, GL_RGB, GL_FLOAT); + m_transmittance->setTexName(m_textures.transmittance_texture); + m_transmittance->setTarget(GL_TEXTURE_2D, LLTexUnit::TT_TEXTURE); + + m_scattering->generateGLTexture(); + m_scattering->setAddressMode(LLTexUnit::eTextureAddressMode::TAM_CLAMP); + m_scattering->setFilteringOption(LLTexUnit::eTextureFilterOptions::TFO_BILINEAR); + m_scattering->setExplicitFormat(GL_RGB16F_ARB, GL_RGB, GL_FLOAT); + m_scattering->setTexName(m_textures.transmittance_texture); + m_scattering->setTarget(GL_TEXTURE_3D, LLTexUnit::TT_TEXTURE_3D); + + m_mie_scattering->generateGLTexture(); + m_mie_scattering->setAddressMode(LLTexUnit::eTextureAddressMode::TAM_CLAMP); + m_mie_scattering->setFilteringOption(LLTexUnit::eTextureFilterOptions::TFO_BILINEAR); + m_mie_scattering->setExplicitFormat(GL_RGB16F_ARB, GL_RGB, GL_FLOAT); + m_mie_scattering->setTexName(m_textures.transmittance_texture); + m_mie_scattering->setTarget(GL_TEXTURE_3D, LLTexUnit::TT_TEXTURE_3D); +}; + +LLAtmosphere::~LLAtmosphere() +{ + // Cease referencing textures from atmosphere::model from our LLGLTextures wrappers for same. + m_transmittance->setTexName(0); + m_scattering->setTexName(0); + m_mie_scattering->setTexName(0); + + delete m_model; + m_model = nullptr; +} + +LLGLTexture* LLAtmosphere::getTransmittance() const +{ + return m_transmittance; +} + +LLGLTexture* LLAtmosphere::getScattering() const +{ + return m_scattering; +} + +LLGLTexture* LLAtmosphere::getMieScattering() const +{ + return m_mie_scattering; +} + +GLhandleARB LLAtmosphere::getAtmosphericShaderForLink() const +{ + return m_model ? m_model->GetShader() : 0; +} diff --git a/indra/llrender/llatmosphere.h b/indra/llrender/llatmosphere.h new file mode 100644 index 0000000000..6a9d1a4438 --- /dev/null +++ b/indra/llrender/llatmosphere.h @@ -0,0 +1,72 @@ +/** + * @file llatmosphere.h + * @brief LLAtmosphere class for integration with libatmosphere + * + * $LicenseInfo:firstyear=2018&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2018, 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_ATMOSPHERE_H +#define LL_ATMOSPHERE_H + +#include "llglheaders.h" +#include "llgltexture.h" +#include "libatmosphere/model.h" + +class LLAtmosphere +{ +public: + LLAtmosphere(); + ~LLAtmosphere(); + + static void initClass(); + static void cleanupClass(); + + const LLAtmosphere& operator=(const LLAtmosphere& rhs) + { + LL_ERRS() << "Illegal operation!" << LL_ENDL; + return *this; + } + + LLGLTexture* getTransmittance() const; + LLGLTexture* getScattering() const; + LLGLTexture* getMieScattering() const; + + GLhandleARB getAtmosphericShaderForLink() const; + +protected: + LLAtmosphere(const LLAtmosphere& rhs) + { + *this = rhs; + } + + atmosphere::ModelConfig m_config; + atmosphere::PrecomputedTextures m_textures; + atmosphere::Model* m_model = nullptr; + + LLPointer<LLGLTexture> m_transmittance; + LLPointer<LLGLTexture> m_scattering; + LLPointer<LLGLTexture> m_mie_scattering; +}; + +extern LLAtmosphere* gAtmosphere; + +#endif // LL_ATMOSPHERE_H diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 35b6951779..2f78b6e104 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -1352,8 +1352,8 @@ void LLGLManager::initExtensions() // nSight doesn't support use of ARB funcs that have been normalized in the API if (!LLRender::sNsightDebugSupport) { - glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetAttribLocationARB"); - glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindAttribLocationARB"); + glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetAttribLocationARB"); + glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindAttribLocationARB"); } else { diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 970502f2d6..b09ec53bc0 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -154,8 +154,7 @@ void LLGLSLShader::clearStats() mSamplesDrawn = 0; mDrawCalls = 0; mTextureStateFetched = false; - mTextureMagFilter.clear(); - mTextureMinFilter.clear(); + mTextureMagMinFilter.clear(); } void LLGLSLShader::dumpStats() @@ -168,14 +167,16 @@ void LLGLSLShader::dumpStats() { LL_INFOS() << mShaderFiles[i].first << LL_ENDL; } - for (U32 i = 0; i < mTexture.size(); ++i) + for (uniforms_index_t::iterator it = mTexture.begin(); it != mTexture.end(); ++it) { - GLint idx = mTexture[i]; + S32 i = (*it).first; + GLint idx = (*it).second; if (idx >= 0) { GLint uniform_idx = getUniformLocation(i); - LL_INFOS() << mUniformNameMap[uniform_idx] << " - " << std::hex << mTextureMagFilter[i] << "/" << mTextureMinFilter[i] << std::dec << LL_ENDL; + magmin_filter_t::iterator it = mTextureMagMinFilter.find(i); + LL_INFOS() << mUniformNameMap[uniform_idx] << " - " << std::hex << (*it).second.second << "/" << (*it).second.first << std::dec << LL_ENDL; } } LL_INFOS() << "=============================================" << LL_ENDL; @@ -232,14 +233,13 @@ void LLGLSLShader::placeProfileQuery() if (!mTextureStateFetched) { mTextureStateFetched = true; - mTextureMagFilter.resize(mTexture.size()); - mTextureMinFilter.resize(mTexture.size()); U32 cur_active = gGL.getCurrentTexUnitIndex(); - for (U32 i = 0; i < mTexture.size(); ++i) + for (uniforms_index_t::iterator it = mTexture.begin(); it != mTexture.end(); ++it) { - GLint idx = mTexture[i]; + S32 i = (*it).first; + GLint idx = (*it).second; if (idx >= 0) { @@ -253,8 +253,7 @@ void LLGLSLShader::placeProfileQuery() glGetTexParameteriv(type, GL_TEXTURE_MAG_FILTER, (GLint*) &mag); glGetTexParameteriv(type, GL_TEXTURE_MIN_FILTER, (GLint*) &min); - mTextureMagFilter[i] = mag; - mTextureMinFilter[i] = min; + mTextureMagMinFilter[i] = magmin_values_t(mag, min); } } @@ -402,12 +401,17 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes, mDefines["OLD_SELECT"] = "1"; #endif + if (mExtraLinkObject) + { + attachObject(mExtraLinkObject); + } + //compile new source vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin(); for ( ; fileIter != mShaderFiles.end(); fileIter++ ) { GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, &mDefines, mFeatures.mIndexedTextureChannels); - LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL; + LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << " shaderhandle=" << shaderhandle << LL_ENDL; if (shaderhandle) { attachObject(shaderhandle); @@ -470,13 +474,14 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes, } S32 cur_tex = channel_count; //adjust any texture channels that might have been overwritten - for (U32 i = 0; i < mTexture.size(); i++) + for (uniforms_index_t::iterator it = mTexture.begin(); it != mTexture.end(); ++it) { - if (mTexture[i] > -1 && mTexture[i] < channel_count) + int i = (*it).first; + if (((*it).second >= 0) && ((*it).second < channel_count)) { llassert(cur_tex < gGLManager.mNumTextureImageUnits); uniform1i(i, cur_tex); - mTexture[i] = cur_tex++; + (*it).second = cur_tex++; } } unbind(); @@ -655,13 +660,16 @@ void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> * //find the index of this uniform for (S32 i = 0; i < (S32) LLShaderMgr::instance()->mReservedUniforms.size(); i++) { - if ( (mUniform[i] == -1) - && (LLShaderMgr::instance()->mReservedUniforms[i] == name)) + if (LLShaderMgr::instance()->mReservedUniforms[i] == name) { - //found it - mUniform[i] = location; - mTexture[i] = mapUniformTextureChannel(location, type); - return; + std::pair<uniforms_index_t::iterator, bool> result; + + result = mUniform.insert(uniforms_index_t::value_type(i, location)); + if (result.second) + { + mTexture[i] = mapUniformTextureChannel(location, type); + return; + } } } @@ -669,13 +677,17 @@ void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> * { for (U32 i = 0; i < uniforms->size(); i++) { - if ( (mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] == -1) - && ((*uniforms)[i].String() == name)) + std::pair<uniforms_index_t::iterator, bool> result; + S32 index = i + LLShaderMgr::instance()->mReservedUniforms.size(); + + if ((*uniforms)[i].String() == name) { - //found it - mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] = location; - mTexture[i+LLShaderMgr::instance()->mReservedUniforms.size()] = mapUniformTextureChannel(location, type); - return; + result = mUniform.insert(uniforms_index_t::value_type(index, location)); + if (result.second) + { + mTexture[index] = mapUniformTextureChannel(location, type); + return; + } } } } @@ -715,10 +727,6 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms) mUniformNameMap.clear(); mTexture.clear(); mValue.clear(); - //initialize arrays - U32 numUniforms = (uniforms == NULL) ? 0 : uniforms->size(); - mUniform.resize(numUniforms + LLShaderMgr::instance()->mReservedUniforms.size(), -1); - mTexture.resize(numUniforms + LLShaderMgr::instance()->mReservedUniforms.size(), -1); bind(); @@ -910,20 +918,14 @@ S32 LLGLSLShader::bindTexture(const std::string &uniform, LLTexture *texture, LL S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode) { - if (uniform < 0 || uniform >= (S32)mTexture.size()) - { - UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL; - return -1; - } + GLint channel = getTexChannelForIndex(uniform); - uniform = mTexture[uniform]; - - if (uniform > -1) + if (channel > -1) { - gGL.getTexUnit(uniform)->bind(texture, mode); + gGL.getTexUnit(channel)->bind(texture, mode); } - return uniform; + return channel; } S32 LLGLSLShader::unbindTexture(const std::string &uniform, LLTexUnit::eTextureType mode) @@ -936,82 +938,64 @@ S32 LLGLSLShader::unbindTexture(const std::string &uniform, LLTexUnit::eTextureT S32 LLGLSLShader::unbindTexture(S32 uniform, LLTexUnit::eTextureType mode) { - if (uniform < 0 || uniform >= (S32)mTexture.size()) - { - UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL; - return -1; - } - - uniform = mTexture[uniform]; - - if (uniform > -1) + GLint channel = getTexChannelForIndex(uniform); + + if (channel > -1) { - gGL.getTexUnit(uniform)->unbind(mode); + gGL.getTexUnit(channel)->unbind(mode); } - return uniform; + return channel; } S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode) { - if (uniform < 0 || uniform >= (S32)mTexture.size()) - { - UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL; - return -1; - } - S32 index = mTexture[uniform]; - if (index != -1) + GLint channel = getTexChannelForIndex(uniform); + + if (channel != -1) { - gGL.getTexUnit(index)->activate(); - gGL.getTexUnit(index)->enable(mode); + gGL.getTexUnit(channel)->activate(); + gGL.getTexUnit(channel)->enable(mode); } - return index; + return channel; } S32 LLGLSLShader::disableTexture(S32 uniform, LLTexUnit::eTextureType mode) { - if (uniform < 0 || uniform >= (S32)mTexture.size()) - { - UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL; - return -1; - } - S32 index = mTexture[uniform]; - if (index != -1 && gGL.getTexUnit(index)->getCurrType() != LLTexUnit::TT_NONE) + GLint channel = getTexChannelForIndex(uniform); + + if (channel != -1 && gGL.getTexUnit(channel)->getCurrType() != LLTexUnit::TT_NONE) { - if (gDebugGL && gGL.getTexUnit(index)->getCurrType() != mode) + if (gDebugGL && gGL.getTexUnit(channel)->getCurrType() != mode) { if (gDebugSession) { - gFailLog << "Texture channel " << index << " texture type corrupted." << std::endl; + gFailLog << "Texture channel " << channel << " texture type corrupted." << std::endl; ll_fail("LLGLSLShader::disableTexture failed"); } else { - LL_ERRS() << "Texture channel " << index << " texture type corrupted." << LL_ENDL; + LL_ERRS() << "Texture channel " << channel << " texture type corrupted." << LL_ENDL; } } - gGL.getTexUnit(index)->disable(); + gGL.getTexUnit(channel)->disable(); } - return index; + return channel; } void LLGLSLShader::uniform1i(U32 index, GLint x) { if (mProgramObject) { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } + GLint location = getLocationForIndex(index); - if (mUniform[index] >= 0) + if (location >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); + std::map<GLint, LLVector4>::iterator iter = mValue.find(location); if (iter == mValue.end() || iter->second.mV[0] != x) { - glUniform1iARB(mUniform[index], x); - mValue[mUniform[index]] = LLVector4(x,0.f,0.f,0.f); + glUniform1iARB(location, x); + mValue[location] = LLVector4(x,0.f,0.f,0.f); } } } @@ -1021,19 +1005,15 @@ void LLGLSLShader::uniform1f(U32 index, GLfloat x) { if (mProgramObject) { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } + GLint location = getLocationForIndex(index); - if (mUniform[index] >= 0) + if (location >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); + std::map<GLint, LLVector4>::iterator iter = mValue.find(location); if (iter == mValue.end() || iter->second.mV[0] != x) { - glUniform1fARB(mUniform[index], x); - mValue[mUniform[index]] = LLVector4(x,0.f,0.f,0.f); + glUniform1fARB(location, x); + mValue[location] = LLVector4(x,0.f,0.f,0.f); } } } @@ -1043,20 +1023,16 @@ void LLGLSLShader::uniform2f(U32 index, GLfloat x, GLfloat y) { if (mProgramObject) { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } + GLint location = getLocationForIndex(index); - if (mUniform[index] >= 0) + if (location >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); + std::map<GLint, LLVector4>::iterator iter = mValue.find(location); LLVector4 vec(x,y,0.f,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec)) { - glUniform2fARB(mUniform[index], x, y); - mValue[mUniform[index]] = vec; + glUniform2fARB(location, x, y); + mValue[location] = vec; } } } @@ -1066,20 +1042,16 @@ void LLGLSLShader::uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z) { if (mProgramObject) { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } + GLint location = getLocationForIndex(index); - if (mUniform[index] >= 0) + if (location >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); + std::map<GLint, LLVector4>::iterator iter = mValue.find(location); LLVector4 vec(x,y,z,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec)) { - glUniform3fARB(mUniform[index], x, y, z); - mValue[mUniform[index]] = vec; + glUniform3fARB(location, x, y, z); + mValue[location] = vec; } } } @@ -1089,20 +1061,16 @@ void LLGLSLShader::uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat { if (mProgramObject) { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } + GLint location = getLocationForIndex(index); - if (mUniform[index] >= 0) + if (location >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); + std::map<GLint, LLVector4>::iterator iter = mValue.find(location); LLVector4 vec(x,y,z,w); if (iter == mValue.end() || shouldChange(iter->second,vec)) { - glUniform4fARB(mUniform[index], x, y, z, w); - mValue[mUniform[index]] = vec; + glUniform4fARB(location, x, y, z, w); + mValue[location] = vec; } } } @@ -1112,20 +1080,16 @@ void LLGLSLShader::uniform1iv(U32 index, U32 count, const GLint* v) { if (mProgramObject) { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } + GLint location = getLocationForIndex(index); - if (mUniform[index] >= 0) + if (location >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); + std::map<GLint, LLVector4>::iterator iter = mValue.find(location); LLVector4 vec(v[0],0.f,0.f,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) { - glUniform1ivARB(mUniform[index], count, v); - mValue[mUniform[index]] = vec; + glUniform1ivARB(location, count, v); + mValue[location] = vec; } } } @@ -1135,20 +1099,16 @@ void LLGLSLShader::uniform1fv(U32 index, U32 count, const GLfloat* v) { if (mProgramObject) { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } + GLint location = getLocationForIndex(index); - if (mUniform[index] >= 0) + if (location >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); + std::map<GLint, LLVector4>::iterator iter = mValue.find(location); LLVector4 vec(v[0],0.f,0.f,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) { - glUniform1fvARB(mUniform[index], count, v); - mValue[mUniform[index]] = vec; + glUniform1fvARB(location, count, v); + mValue[location] = vec; } } } @@ -1158,20 +1118,16 @@ void LLGLSLShader::uniform2fv(U32 index, U32 count, const GLfloat* v) { if (mProgramObject) { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } + GLint location = getLocationForIndex(index); - if (mUniform[index] >= 0) + if (location >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); + std::map<GLint, LLVector4>::iterator iter = mValue.find(location); LLVector4 vec(v[0],v[1],0.f,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) { - glUniform2fvARB(mUniform[index], count, v); - mValue[mUniform[index]] = vec; + glUniform2fvARB(location, count, v); + mValue[location] = vec; } } } @@ -1181,20 +1137,16 @@ void LLGLSLShader::uniform3fv(U32 index, U32 count, const GLfloat* v) { if (mProgramObject) { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } + GLint location = getLocationForIndex(index); - if (mUniform[index] >= 0) + if (location >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); + std::map<GLint, LLVector4>::iterator iter = mValue.find(location); LLVector4 vec(v[0],v[1],v[2],0.f); if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) { - glUniform3fvARB(mUniform[index], count, v); - mValue[mUniform[index]] = vec; + glUniform3fvARB(location, count, v); + mValue[location] = vec; } } } @@ -1204,20 +1156,16 @@ void LLGLSLShader::uniform4fv(U32 index, U32 count, const GLfloat* v) { if (mProgramObject) { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } + GLint location = getLocationForIndex(index); - if (mUniform[index] >= 0) + if (location >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); + std::map<GLint, LLVector4>::iterator iter = mValue.find(location); LLVector4 vec(v[0],v[1],v[2],v[3]); if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) { - glUniform4fvARB(mUniform[index], count, v); - mValue[mUniform[index]] = vec; + glUniform4fvARB(location, count, v); + mValue[location] = vec; } } } @@ -1227,15 +1175,11 @@ void LLGLSLShader::uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, c { if (mProgramObject) { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } + GLint location = getLocationForIndex(index); - if (mUniform[index] >= 0) + if (location >= 0) { - glUniformMatrix2fvARB(mUniform[index], count, transpose, v); + glUniformMatrix2fvARB(location, count, transpose, v); } } } @@ -1244,15 +1188,11 @@ void LLGLSLShader::uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, c { if (mProgramObject) { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } + GLint location = getLocationForIndex(index); - if (mUniform[index] >= 0) + if (location >= 0) { - glUniformMatrix3fvARB(mUniform[index], count, transpose, v); + glUniformMatrix3fvARB(location, count, transpose, v); } } } @@ -1261,15 +1201,11 @@ void LLGLSLShader::uniformMatrix3x4fv(U32 index, U32 count, GLboolean transpose, { if (mProgramObject) { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } + GLint location = getLocationForIndex(index); - if (mUniform[index] >= 0) + if (location >= 0) { - glUniformMatrix3x4fv(mUniform[index], count, transpose, v); + glUniformMatrix3x4fv(location, count, transpose, v); } } } @@ -1278,15 +1214,11 @@ void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, c { if (mProgramObject) { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } + GLint location = getLocationForIndex(index); - if (mUniform[index] >= 0) + if (location >= 0) { - glUniformMatrix4fvARB(mUniform[index], count, transpose, v); + glUniformMatrix4fvARB(location, count, transpose, v); } } } @@ -1317,14 +1249,8 @@ GLint LLGLSLShader::getUniformLocation(const LLStaticHashedString& uniform) GLint LLGLSLShader::getUniformLocation(U32 index) { - GLint ret = -1; - if (mProgramObject) - { - llassert(index < mUniform.size()); - return mUniform[index]; - } - - return ret; + /*TODO: flatten this... change calls to gUL(U32) */ + return getLocationForIndex(index); } GLint LLGLSLShader::getAttribLocation(U32 attrib) diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index 6f10d122cb..a7a9e27fcd 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -166,14 +166,20 @@ public: U32 mMatHash[LLRender::NUM_MATRIX_MODES]; U32 mLightHash; + typedef std::map<S32, GLint> uniforms_index_t; + typedef std::pair<U32, U32> magmin_values_t; + + typedef std::map < S32, magmin_values_t> magmin_filter_t; + GLhandleARB mProgramObject; std::vector<GLint> mAttribute; //lookup table of attribute enum to attribute channel U32 mAttributeMask; //mask of which reserved attributes are set (lines up with LLVertexBuffer::getTypeMask()) - std::vector<GLint> mUniform; //lookup table of uniform enum to uniform location + uniforms_index_t mUniform; + uniforms_index_t mTexture; + LLStaticStringTable<GLint> mUniformMap; //lookup map of uniform name to uniform location std::map<GLint, std::string> mUniformNameMap; //lookup map of uniform location to uniform name std::map<GLint, LLVector4> mValue; //lookup map of uniform location to last known value - std::vector<GLint> mTexture; S32 mTotalUniformSize; S32 mActiveTextureChannels; S32 mShaderLevel; @@ -197,11 +203,32 @@ public: static U32 sTotalDrawCalls; bool mTextureStateFetched; - std::vector<U32> mTextureMagFilter; - std::vector<U32> mTextureMinFilter; + magmin_filter_t mTextureMagMinFilter; + + GLhandleARB mExtraLinkObject = 0; private: void unloadInternal(); + + inline GLint getLocationForIndex(S32 index) + { + if (!mProgramObject) + return -1; + uniforms_index_t::iterator it = mUniform.find(index); + if (it == mUniform.end()) + return -1; + return (*it).second; + } + + inline GLint getTexChannelForIndex(S32 index) + { + if (!mProgramObject) + return -1; + uniforms_index_t::iterator it = mTexture.find(index); + if (it == mTexture.end()) + return -1; + return (*it).second; + } }; //UI shader (declared here so llui_libtest will link properly) diff --git a/indra/llrender/llgltexture.cpp b/indra/llrender/llgltexture.cpp index 3a6eebebba..e9a39d8acb 100644 --- a/indra/llrender/llgltexture.cpp +++ b/indra/llrender/llgltexture.cpp @@ -30,20 +30,20 @@ // static S32 LLGLTexture::getTotalNumOfCategories() { - return MAX_GL_IMAGE_CATEGORY - (BOOST_HIGH - BOOST_SCULPTED) + 2 ; + return MAX_GL_IMAGE_CATEGORY - (BOOST_HIGH - BOOST_SCULPTED) + 2; } // static //index starts from zero. S32 LLGLTexture::getIndexFromCategory(S32 category) { - return (category < BOOST_HIGH) ? category : category - (BOOST_HIGH - BOOST_SCULPTED) + 1 ; + return (category < BOOST_HIGH) ? category : category - (BOOST_HIGH - BOOST_SCULPTED) + 1; } //static S32 LLGLTexture::getCategoryFromIndex(S32 index) { - return (index < BOOST_HIGH) ? index : index + (BOOST_HIGH - BOOST_SCULPTED) - 1 ; + return (index < BOOST_HIGH) ? index : index + (BOOST_HIGH - BOOST_SCULPTED) - 1; } LLGLTexture::LLGLTexture(BOOL usemipmaps) @@ -55,19 +55,19 @@ LLGLTexture::LLGLTexture(BOOL usemipmaps) LLGLTexture::LLGLTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) { init(); - mFullWidth = width ; - mFullHeight = height ; + mFullWidth = width; + mFullHeight = height; mUseMipMaps = usemipmaps; - mComponents = components ; + mComponents = components; setTexelsPerImage(); } LLGLTexture::LLGLTexture(const LLImageRaw* raw, BOOL usemipmaps) { init(); - mUseMipMaps = usemipmaps ; + mUseMipMaps = usemipmaps; // Create an empty image of the specified size and width - mGLTexturep = new LLImageGL(raw, usemipmaps) ; + mGLTexturep = new LLImageGL(raw, usemipmaps); } LLGLTexture::~LLGLTexture() @@ -81,13 +81,13 @@ void LLGLTexture::init() mFullWidth = 0; mFullHeight = 0; - mTexelsPerImage = 0 ; - mUseMipMaps = FALSE ; - mComponents = 0 ; + mTexelsPerImage = 0; + mUseMipMaps = FALSE; + mComponents = 0; - mTextureState = NO_DELETE ; + mTextureState = NO_DELETE; mDontDiscard = FALSE; - mNeedsGLTexture = FALSE ; + mNeedsGLTexture = FALSE; } void LLGLTexture::cleanup() @@ -111,287 +111,301 @@ void LLGLTexture::setBoostLevel(S32 level) { if(mBoostLevel != level) { - mBoostLevel = level ; + mBoostLevel = level; if(mBoostLevel != LLGLTexture::BOOST_NONE && mBoostLevel != LLGLTexture::BOOST_ICON) { - setNoDelete() ; + setNoDelete(); } } } void LLGLTexture::forceActive() { - mTextureState = ACTIVE ; + mTextureState = ACTIVE; } void LLGLTexture::setActive() { if(mTextureState != NO_DELETE) { - mTextureState = ACTIVE ; + mTextureState = ACTIVE; } } //set the texture to stay in memory void LLGLTexture::setNoDelete() { - mTextureState = NO_DELETE ; + mTextureState = NO_DELETE; } void LLGLTexture::generateGLTexture() { if(mGLTexturep.isNull()) { - mGLTexturep = new LLImageGL(mFullWidth, mFullHeight, mComponents, mUseMipMaps) ; + mGLTexturep = new LLImageGL(mFullWidth, mFullHeight, mComponents, mUseMipMaps); } } LLImageGL* LLGLTexture::getGLTexture() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep ; + return mGLTexturep; } BOOL LLGLTexture::createGLTexture() { if(mGLTexturep.isNull()) { - generateGLTexture() ; + generateGLTexture(); } - return mGLTexturep->createGLTexture() ; + return mGLTexturep->createGLTexture(); } BOOL LLGLTexture::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename, BOOL to_create, S32 category) { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename, to_create, category) ; + BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename, to_create, category); if(ret) { - mFullWidth = mGLTexturep->getCurrentWidth() ; - mFullHeight = mGLTexturep->getCurrentHeight() ; - mComponents = mGLTexturep->getComponents() ; + mFullWidth = mGLTexturep->getCurrentWidth(); + mFullHeight = mGLTexturep->getCurrentHeight(); + mComponents = mGLTexturep->getComponents(); setTexelsPerImage(); } - return ret ; + return ret; } void LLGLTexture::setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes) { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - mGLTexturep->setExplicitFormat(internal_format, primary_format, type_format, swap_bytes) ; + mGLTexturep->setExplicitFormat(internal_format, primary_format, type_format, swap_bytes); } void LLGLTexture::setAddressMode(LLTexUnit::eTextureAddressMode mode) { - llassert(mGLTexturep.notNull()) ; - mGLTexturep->setAddressMode(mode) ; + llassert(mGLTexturep.notNull()); + mGLTexturep->setAddressMode(mode); } void LLGLTexture::setFilteringOption(LLTexUnit::eTextureFilterOptions option) { - llassert(mGLTexturep.notNull()) ; - mGLTexturep->setFilteringOption(option) ; + llassert(mGLTexturep.notNull()); + mGLTexturep->setFilteringOption(option); } //virtual S32 LLGLTexture::getWidth(S32 discard_level) const { - llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getWidth(discard_level) ; + llassert(mGLTexturep.notNull()); + return mGLTexturep->getWidth(discard_level); } //virtual S32 LLGLTexture::getHeight(S32 discard_level) const { - llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getHeight(discard_level) ; + llassert(mGLTexturep.notNull()); + return mGLTexturep->getHeight(discard_level); } S32 LLGLTexture::getMaxDiscardLevel() const { - llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getMaxDiscardLevel() ; + llassert(mGLTexturep.notNull()); + return mGLTexturep->getMaxDiscardLevel(); } S32 LLGLTexture::getDiscardLevel() const { - llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getDiscardLevel() ; + llassert(mGLTexturep.notNull()); + return mGLTexturep->getDiscardLevel(); } S8 LLGLTexture::getComponents() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->getComponents() ; + return mGLTexturep->getComponents(); } LLGLuint LLGLTexture::getTexName() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->getTexName() ; + return mGLTexturep->getTexName(); } BOOL LLGLTexture::hasGLTexture() const { if(mGLTexturep.notNull()) { - return mGLTexturep->getHasGLTexture() ; + return mGLTexturep->getHasGLTexture(); } - return FALSE ; + return FALSE; } BOOL LLGLTexture::getBoundRecently() const { if(mGLTexturep.notNull()) { - return mGLTexturep->getBoundRecently() ; + return mGLTexturep->getBoundRecently(); } - return FALSE ; + return FALSE; } LLTexUnit::eTextureType LLGLTexture::getTarget(void) const { - llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getTarget() ; + llassert(mGLTexturep.notNull()); + return mGLTexturep->getTarget(); } BOOL LLGLTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height) { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height) ; + return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height); } BOOL LLGLTexture::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height) { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height) ; + return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height); } void LLGLTexture::setGLTextureCreated (bool initialized) { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - mGLTexturep->setGLTextureCreated (initialized) ; + mGLTexturep->setGLTextureCreated (initialized); } void LLGLTexture::setCategory(S32 category) { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); + + mGLTexturep->setCategory(category); +} - mGLTexturep->setCategory(category) ; +void LLGLTexture::setTexName(LLGLuint texName) +{ + llassert(mGLTexturep.notNull()); + return mGLTexturep->setTexName(texName); +} + +void LLGLTexture::setTarget(const LLGLenum target, const LLTexUnit::eTextureType bind_target) +{ + llassert(mGLTexturep.notNull()); + return mGLTexturep->setTarget(target, bind_target); } LLTexUnit::eTextureAddressMode LLGLTexture::getAddressMode(void) const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->getAddressMode() ; + return mGLTexturep->getAddressMode(); } S32Bytes LLGLTexture::getTextureMemory() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->mTextureMemory ; + return mGLTexturep->mTextureMemory; } LLGLenum LLGLTexture::getPrimaryFormat() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->getPrimaryFormat() ; + return mGLTexturep->getPrimaryFormat(); } BOOL LLGLTexture::getIsAlphaMask() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->getIsAlphaMask() ; + return mGLTexturep->getIsAlphaMask(); } BOOL LLGLTexture::getMask(const LLVector2 &tc) { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->getMask(tc) ; + return mGLTexturep->getMask(tc); } F32 LLGLTexture::getTimePassedSinceLastBound() { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->getTimePassedSinceLastBound() ; + return mGLTexturep->getTimePassedSinceLastBound(); } BOOL LLGLTexture::getMissed() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->getMissed() ; + return mGLTexturep->getMissed(); } BOOL LLGLTexture::isJustBound() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->isJustBound() ; + return mGLTexturep->isJustBound(); } void LLGLTexture::forceUpdateBindStats(void) const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->forceUpdateBindStats() ; + return mGLTexturep->forceUpdateBindStats(); } U32 LLGLTexture::getTexelsInAtlas() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->getTexelsInAtlas() ; + return mGLTexturep->getTexelsInAtlas(); } U32 LLGLTexture::getTexelsInGLTexture() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->getTexelsInGLTexture() ; + return mGLTexturep->getTexelsInGLTexture(); } BOOL LLGLTexture::isGLTextureCreated() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->isGLTextureCreated() ; + return mGLTexturep->isGLTextureCreated(); } S32 LLGLTexture::getDiscardLevelInAtlas() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->getDiscardLevelInAtlas() ; + return mGLTexturep->getDiscardLevelInAtlas(); } void LLGLTexture::destroyGLTexture() { if(mGLTexturep.notNull() && mGLTexturep->getHasGLTexture()) { - mGLTexturep->destroyGLTexture() ; - mTextureState = DELETED ; + mGLTexturep->destroyGLTexture(); + mTextureState = DELETED; } } void LLGLTexture::setTexelsPerImage() { - S32 fullwidth = llmin(mFullWidth,(S32)MAX_IMAGE_SIZE_DEFAULT); - S32 fullheight = llmin(mFullHeight,(S32)MAX_IMAGE_SIZE_DEFAULT); - mTexelsPerImage = (F32)fullwidth * fullheight; + U32 fullwidth = llmin(mFullWidth, (U32)MAX_IMAGE_SIZE_DEFAULT); + U32 fullheight = llmin(mFullHeight, (U32)MAX_IMAGE_SIZE_DEFAULT); + mTexelsPerImage = (U32)fullwidth * fullheight; } +static LLUUID sStubUUID; +const LLUUID& LLGLTexture::getID() const { return sStubUUID; } diff --git a/indra/llrender/llgltexture.h b/indra/llrender/llgltexture.h index 70610d9626..bdaed05591 100644 --- a/indra/llrender/llgltexture.h +++ b/indra/llrender/llgltexture.h @@ -104,7 +104,7 @@ public: virtual void dump(); // debug info to LL_INFOS() - virtual const LLUUID& getID() const = 0; + virtual const LLUUID& getID() const; void setBoostLevel(S32 level); S32 getBoostLevel() { return mBoostLevel; } @@ -133,6 +133,8 @@ public: BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height); void setGLTextureCreated (bool initialized); void setCategory(S32 category) ; + void setTexName(LLGLuint); // for forcing w/ externally created textures only + void setTarget(const LLGLenum target, const LLTexUnit::eTextureType bind_target); LLTexUnit::eTextureAddressMode getAddressMode(void) const ; S32 getMaxDiscardLevel() const; @@ -179,11 +181,11 @@ protected: protected: S32 mBoostLevel; // enum describing priority level - S32 mFullWidth; - S32 mFullHeight; + U32 mFullWidth; + U32 mFullHeight; BOOL mUseMipMaps; S8 mComponents; - F32 mTexelsPerImage; // Texels per image. + U32 mTexelsPerImage; // Texels per image. mutable S8 mNeedsGLTexture; //GL texture diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 89500dcc04..9b545bca0a 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -352,10 +352,9 @@ BOOL LLImageGL::create(LLPointer<LLImageGL>& dest, const LLImageRaw* imageraw, B } //---------------------------------------------------------------------------- - LLImageGL::LLImageGL(BOOL usemipmaps) : LLTrace::MemTrackable<LLImageGL>("LLImageGL"), - mSaveData(0) + mSaveData(0), mExternalTexture(FALSE) { init(usemipmaps); setSize(0, 0, 0); @@ -365,7 +364,7 @@ LLImageGL::LLImageGL(BOOL usemipmaps) LLImageGL::LLImageGL(U32 width, U32 height, U8 components, BOOL usemipmaps) : LLTrace::MemTrackable<LLImageGL>("LLImageGL"), - mSaveData(0) + mSaveData(0), mExternalTexture(FALSE) { llassert( components <= 4 ); init(usemipmaps); @@ -376,7 +375,7 @@ LLImageGL::LLImageGL(U32 width, U32 height, U8 components, BOOL usemipmaps) LLImageGL::LLImageGL(const LLImageRaw* imageraw, BOOL usemipmaps) : LLTrace::MemTrackable<LLImageGL>("LLImageGL"), - mSaveData(0) + mSaveData(0), mExternalTexture(FALSE) { init(usemipmaps); setSize(0, 0, 0); @@ -386,12 +385,36 @@ LLImageGL::LLImageGL(const LLImageRaw* imageraw, BOOL usemipmaps) createGLTexture(0, imageraw); } +LLImageGL::LLImageGL( + LLGLuint texName, + U32 components, + LLGLenum target, + LLGLint formatInternal, + LLGLenum formatPrimary, + LLGLenum formatType, + LLTexUnit::eTextureAddressMode addressMode) + : LLTrace::MemTrackable<LLImageGL>("LLImageGL"), mSaveData(0), mExternalTexture(TRUE) +{ + init(false); + mTexName = texName; + mTarget = target; + mComponents = components; + mAddressMode = addressMode; + mFormatType = formatType; + mFormatInternal = formatInternal; + mFormatPrimary = formatPrimary; +} + + LLImageGL::~LLImageGL() { - LLImageGL::cleanup(); - sImageList.erase(this); - freePickMask(); - sCount--; + if (!mExternalTexture) + { + LLImageGL::cleanup(); + sImageList.erase(this); + freePickMask(); + sCount--; + } } void LLImageGL::init(BOOL usemipmaps) diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 2be54be062..4f3d7eed0a 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -84,7 +84,10 @@ public: LLImageGL(BOOL usemipmaps = TRUE); LLImageGL(U32 width, U32 height, U8 components, BOOL usemipmaps = TRUE); LLImageGL(const LLImageRaw* imageraw, BOOL usemipmaps = TRUE); - + + // For wrapping textures created via GL elsewhere with our API only. Use with caution. + LLImageGL(LLGLuint mTexName, U32 components, LLGLenum target, LLGLint formatInternal, LLGLenum formatPrimary, LLGLenum formatType, LLTexUnit::eTextureAddressMode addressMode); + protected: virtual ~LLImageGL(); @@ -234,6 +237,8 @@ protected: LLGLenum mFormatType; BOOL mFormatSwapBytes;// if true, use glPixelStorei(GL_UNPACK_SWAP_BYTES, 1) + BOOL mExternalTexture; + // STATICS public: static std::set<LLImageGL*> sImageList; @@ -279,6 +284,8 @@ public: void setCategory(S32 category) {mCategory = category;} S32 getCategory()const {return mCategory;} + void setTexName(GLuint texName) { mTexName = texName; } + //for debug use: show texture size distribution //---------------------------------------- static S32 sCurTexSizeBar ; diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 65d6181920..a8f622d3ff 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -59,7 +59,8 @@ static const GLenum sGLTextureType[] = GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_CUBE_MAP_ARB, - GL_TEXTURE_2D_MULTISAMPLE + GL_TEXTURE_2D_MULTISAMPLE, + GL_TEXTURE_3D }; static const GLint sGLAddressMode[] = diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 32bb728d8a..6f22f1d8cb 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -61,10 +61,11 @@ public: typedef enum { TT_TEXTURE = 0, // Standard 2D Texture - TT_RECT_TEXTURE, // Non power of 2 texture - TT_CUBE_MAP, // 6-sided cube map texture + TT_RECT_TEXTURE, // Non power of 2 texture + TT_CUBE_MAP, // 6-sided cube map texture TT_MULTISAMPLE_TEXTURE, // see GL_ARB_texture_multisample - TT_NONE // No texture type is currently enabled + TT_TEXTURE_3D, // standard 3D Texture + TT_NONE, // No texture type is currently enabled } eTextureType; typedef enum @@ -445,7 +446,7 @@ public: static U32 sUICalls; static U32 sUIVerts; static bool sGLCoreProfile; - static bool sNsightDebugSupport; + static bool sNsightDebugSupport; private: friend class LLLightState; diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index e721ad93fa..287f22783f 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -512,16 +512,16 @@ static std::string get_object_log(GLhandleARB ret) void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns, const std::string& filename) { std::string log = get_object_log(ret); + std::string fname = filename; + if (filename.empty()) + { + fname = "unknown shader file"; + } - if (log.length() > 0 || warns) + if (log.length() > 0) { - LL_DEBUGS("ShaderLoading") << "Shader loading "; - - if (!filename.empty()) - { - LL_CONT << "From " << filename << ":\n"; - } - LL_CONT << log << LL_ENDL; + LL_INFOS() << "Shader loading from " << fname << ":\n" << LL_ENDL; + LL_INFOS() << log << LL_ENDL; } } @@ -953,7 +953,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade // Add shader file to map mShaderObjects[filename] = ret; shader_level = try_gpu_class; - } + } else { if (shader_level > 1) @@ -1114,10 +1114,10 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("specularMap"); mReservedUniforms.push_back("bumpMap"); mReservedUniforms.push_back("environmentMap"); - mReservedUniforms.push_back("cloude_noise_texture"); + mReservedUniforms.push_back("cloud_noise_texture"); mReservedUniforms.push_back("fullbright"); mReservedUniforms.push_back("lightnorm"); - mReservedUniforms.push_back("sunlight_color_copy"); + mReservedUniforms.push_back("sunlight_color"); mReservedUniforms.push_back("ambient"); mReservedUniforms.push_back("blue_horizon"); mReservedUniforms.push_back("blue_density"); @@ -1267,6 +1267,16 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("origin"); mReservedUniforms.push_back("display_gamma"); + + mReservedUniforms.push_back("inscatter"); + mReservedUniforms.push_back("sun_size"); + mReservedUniforms.push_back("fog_color"); + + mReservedUniforms.push_back("transmittance_texture"); + mReservedUniforms.push_back("scattering_texture"); + mReservedUniforms.push_back("irradiance_texture"); + mReservedUniforms.push_back("single_mie_scattering_texture"); + llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS); std::set<std::string> dupe_check; diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index 394b38f832..ac3f7d58d5 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -30,6 +30,11 @@ #include "llgl.h" #include "llglslshader.h" +/*RIDER: TODO: + * This should use the LL Singleton<> template... but not a quick conversion. + * (llviewershadermgr derives from this) + */ + class LLShaderMgr { public: @@ -215,7 +220,18 @@ public: TERRAIN_ALPHARAMP, SHINY_ORIGIN, -DISPLAY_GAMMA, + DISPLAY_GAMMA, + + INSCATTER_RT, + SUN_SIZE, + FOG_COLOR, + + // precomputed textures from libatmosphere + TRANSMITTANCE_TEX, + SCATTER_TEX, + ILLUMINANCE_TEX, + SINGLE_MIE_SCATTER_TEX, + END_RESERVED_UNIFORMS } eGLSLReservedUniforms; diff --git a/indra/llrender/lltexture.cpp b/indra/llrender/lltexture.cpp index 90fbcec2be..6eef36216c 100644 --- a/indra/llrender/lltexture.cpp +++ b/indra/llrender/lltexture.cpp @@ -29,3 +29,15 @@ LLTexture::~LLTexture() { } + +S8 LLTexture::getType() const { llassert(false); return 0; } +void LLTexture::setKnownDrawSize(S32 width, S32 height) { llassert(false); } +bool LLTexture::bindDefaultImage(const S32 stage) { llassert(false); return false; } +bool LLTexture::bindDebugImage(const S32 stage) { llassert(false); return false; } +void LLTexture::forceImmediateUpdate() { llassert(false); } +void LLTexture::setActive() { llassert(false); } +S32 LLTexture::getWidth(S32 discard_level) const { llassert(false); return 0; } +S32 LLTexture::getHeight(S32 discard_level) const { llassert(false); return 0; } +bool LLTexture::isActiveFetching() { llassert(false); return false; } +LLImageGL* LLTexture::getGLTexture() const { llassert(false); return nullptr; } +void LLTexture::updateBindStatsForTester() { } diff --git a/indra/llrender/lltexture.h b/indra/llrender/lltexture.h index 9fca8b8cd3..41481fb8a7 100644 --- a/indra/llrender/lltexture.h +++ b/indra/llrender/lltexture.h @@ -58,21 +58,21 @@ public: // //interfaces to access LLGLTexture // - virtual S8 getType() const = 0 ; - virtual void setKnownDrawSize(S32 width, S32 height) = 0 ; - virtual bool bindDefaultImage(const S32 stage = 0) = 0 ; - virtual bool bindDebugImage(const S32 stage = 0) = 0; - virtual void forceImmediateUpdate() = 0 ; - virtual void setActive() = 0 ; - virtual S32 getWidth(S32 discard_level = -1) const = 0 ; - virtual S32 getHeight(S32 discard_level = -1) const = 0 ; - virtual bool isActiveFetching() = 0; + virtual S8 getType() const; + virtual void setKnownDrawSize(S32 width, S32 height); + virtual bool bindDefaultImage(const S32 stage = 0); + virtual bool bindDebugImage(const S32 stage = 0); + virtual void forceImmediateUpdate(); + virtual void setActive(); + virtual S32 getWidth(S32 discard_level = -1) const; + virtual S32 getHeight(S32 discard_level = -1) const; + virtual bool isActiveFetching(); private: //note: do not make this function public. - virtual LLImageGL* getGLTexture() const = 0 ; + virtual LLImageGL* getGLTexture() const; - virtual void updateBindStatsForTester() = 0 ; + virtual void updateBindStatsForTester(); }; #endif diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp index 0aa3e17075..5cfe79267f 100644 --- a/indra/llui/llmultislider.cpp +++ b/indra/llui/llmultislider.cpp @@ -196,7 +196,11 @@ void LLMultiSlider::setValue(const LLSD& value) F32 LLMultiSlider::getSliderValue(const std::string& name) const { - return (F32)mValue[name].asReal(); + if (mValue.has(name)) + { + return (F32)mValue[name].asReal(); + } + return 0; } void LLMultiSlider::setCurSlider(const std::string& name) @@ -206,6 +210,24 @@ void LLMultiSlider::setCurSlider(const std::string& name) } } +F32 LLMultiSlider::getSliderValueFromX(S32 xpos) const +{ + S32 left_edge = mThumbWidth / 2; + S32 right_edge = getRect().getWidth() - (mThumbWidth / 2); + + xpos += mMouseOffset; + xpos = llclamp(xpos, left_edge, right_edge); + + F32 t = F32(xpos - left_edge) / (right_edge - left_edge); + + return((t * (mMaxValue - mMinValue)) + mMinValue); +} + +void LLMultiSlider::resetCurSlider() +{ + mCurSlider = LLStringUtil::null; +} + const std::string& LLMultiSlider::addSlider() { return addSlider(mInitialValue); @@ -334,10 +356,15 @@ void LLMultiSlider::deleteSlider(const std::string& name) void LLMultiSlider::clear() { - while(mThumbRects.size() > 0) { + while(mThumbRects.size() > 0 && mValue.size() > 0) { deleteCurSlider(); } + if (mThumbRects.size() > 0 || mValue.size() > 0) + { + LL_WARNS() << "Failed to fully clear Multi slider" << LL_ENDL; + } + LLF32UICtrl::clear(); } @@ -345,14 +372,15 @@ BOOL LLMultiSlider::handleHover(S32 x, S32 y, MASK mask) { if( gFocusMgr.getMouseCapture() == this ) { - S32 left_edge = mThumbWidth/2; - S32 right_edge = getRect().getWidth() - (mThumbWidth/2); - - x += mMouseOffset; - x = llclamp( x, left_edge, right_edge ); - - F32 t = F32(x - left_edge) / (right_edge - left_edge); - setCurSliderValue(t * (mMaxValue - mMinValue) + mMinValue ); +// S32 left_edge = mThumbWidth/2; +// S32 right_edge = getRect().getWidth() - (mThumbWidth/2); +// +// x += mMouseOffset; +// x = llclamp( x, left_edge, right_edge ); +// +// F32 t = F32(x - left_edge) / (right_edge - left_edge); +// setCurSliderValue(t * (mMaxValue - mMinValue) + mMinValue ); + setCurSliderValue(getSliderValueFromX(x)); onCommit(); getWindow()->setCursor(UI_CURSOR_ARROW); @@ -416,20 +444,23 @@ BOOL LLMultiSlider::handleMouseDown(S32 x, S32 y, MASK mask) } } - // Find the offset of the actual mouse location from the center of the thumb. - if (mThumbRects[mCurSlider].pointInRect(x,y)) - { - mMouseOffset = (mThumbRects[mCurSlider].mLeft + mThumbWidth/2) - x; - } - else + if (!mCurSlider.empty()) { - mMouseOffset = 0; - } + // Find the offset of the actual mouse location from the center of the thumb. + if (mThumbRects[mCurSlider].pointInRect(x,y)) + { + mMouseOffset = (mThumbRects[mCurSlider].mLeft + mThumbWidth/2) - x; + } + else + { + mMouseOffset = 0; + } - // Start dragging the thumb - // No handler needed for focus lost since this class has no state that depends on it. - gFocusMgr.setMouseCapture( this ); - mDragStartThumbRect = mThumbRects[mCurSlider]; + // Start dragging the thumb + // No handler needed for focus lost since this class has no state that depends on it. + gFocusMgr.setMouseCapture( this ); + mDragStartThumbRect = mThumbRects[mCurSlider]; + } } make_ui_sound("UISndClick"); @@ -546,7 +577,7 @@ void LLMultiSlider::draw() thumb_imagep->drawSolid(mDragStartThumbRect, mThumbCenterColor.get() % 0.3f); // draw the highlight - if (hasFocus()) + if (hasFocus() && !mCurSlider.empty()) { thumb_imagep->drawBorder(mThumbRects[mCurSlider], gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth()); } @@ -578,7 +609,7 @@ void LLMultiSlider::draw() else { // draw highlight - if (hasFocus()) + if (hasFocus() && !mCurSlider.empty()) { thumb_imagep->drawBorder(mThumbRects[mCurSlider], gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth()); } diff --git a/indra/llui/llmultislider.h b/indra/llui/llmultislider.h index 2b422e89c9..0177597da2 100644 --- a/indra/llui/llmultislider.h +++ b/indra/llui/llmultislider.h @@ -72,10 +72,12 @@ public: virtual ~LLMultiSlider(); void setSliderValue(const std::string& name, F32 value, BOOL from_event = FALSE); F32 getSliderValue(const std::string& name) const; + F32 getSliderValueFromX(S32 xpos) const; const std::string& getCurSlider() const { return mCurSlider; } F32 getCurSliderValue() const { return getSliderValue(mCurSlider); } void setCurSlider(const std::string& name); + void resetCurSlider(); void setCurSliderValue(F32 val, BOOL from_event = false) { setSliderValue(mCurSlider, val, from_event); } /*virtual*/ void setValue(const LLSD& value); diff --git a/indra/llui/llmultisliderctrl.cpp b/indra/llui/llmultisliderctrl.cpp index c460a08afc..a982d431b3 100644 --- a/indra/llui/llmultisliderctrl.cpp +++ b/indra/llui/llmultisliderctrl.cpp @@ -213,6 +213,11 @@ void LLMultiSliderCtrl::setCurSlider(const std::string& name) mCurValue = mMultiSlider->getCurSliderValue(); } +void LLMultiSliderCtrl::resetCurSlider() +{ + mMultiSlider->resetCurSlider(); +} + BOOL LLMultiSliderCtrl::setLabelArg( const std::string& key, const LLStringExplicit& text ) { BOOL res = FALSE; diff --git a/indra/llui/llmultisliderctrl.h b/indra/llui/llmultisliderctrl.h index b6a3542376..5c4777ebd0 100644 --- a/indra/llui/llmultisliderctrl.h +++ b/indra/llui/llmultisliderctrl.h @@ -74,7 +74,7 @@ protected: public: virtual ~LLMultiSliderCtrl(); - F32 getSliderValue(const std::string& name) const; + F32 getSliderValue(const std::string& name) const { return mMultiSlider->getSliderValue(name); } void setSliderValue(const std::string& name, F32 v, BOOL from_event = FALSE); virtual void setValue(const LLSD& value ); @@ -84,6 +84,7 @@ public: const std::string& getCurSlider() const { return mMultiSlider->getCurSlider(); } F32 getCurSliderValue() const { return mCurValue; } void setCurSlider(const std::string& name); + void resetCurSlider(); void setCurSliderValue(F32 val, BOOL from_event = false) { setSliderValue(mMultiSlider->getCurSlider(), val, from_event); } virtual void setMinValue(const LLSD& min_value) { setMinValue((F32)min_value.asReal()); } @@ -98,6 +99,8 @@ public: void setMaxValue(F32 max_value) {mMultiSlider->setMaxValue(max_value);} void setIncrement(F32 increment) {mMultiSlider->setIncrement(increment);} + F32 getSliderValueFromX(S32 x) const { return mMultiSlider->getSliderValueFromX(x); } + /// for adding and deleting sliders const std::string& addSlider(); const std::string& addSlider(F32 val); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 23337ddbfb..b47786c5dd 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -159,7 +159,6 @@ set(viewer_SOURCE_FILES llcurrencyuimanager.cpp llcylinder.cpp lldateutil.cpp - lldaycyclemanager.cpp lldebugmessagebox.cpp lldebugview.cpp lldeferredsounds.cpp @@ -182,7 +181,7 @@ set(viewer_SOURCE_FILES lldrawpoolwlsky.cpp lldynamictexture.cpp llemote.cpp - llenvmanager.cpp + llenvironment.cpp llestateinfomodel.cpp lleventnotifier.cpp lleventpoll.cpp @@ -222,18 +221,17 @@ set(viewer_SOURCE_FILES llfloatercolorpicker.cpp llfloaterconversationlog.cpp llfloaterconversationpreview.cpp - llfloaterdeleteenvpreset.cpp llfloaterdeleteprefpreset.cpp llfloaterdestinations.cpp llfloatereditdaycycle.cpp - llfloatereditsky.cpp - llfloatereditwater.cpp + llfloatereditextdaycycle.cpp llfloaterenvironmentsettings.cpp llfloaterevent.cpp llfloaterexperiencepicker.cpp llfloaterexperienceprofile.cpp llfloaterexperiences.cpp llfloaterfacebook.cpp + llfloaterfixedenvironment.cpp llfloaterflickr.cpp llfloaterfonttest.cpp llfloatergesture.cpp @@ -319,6 +317,7 @@ set(viewer_SOURCE_FILES llfolderviewmodelinventory.cpp llfollowcam.cpp llfriendcard.cpp + llflyoutcombobtn.cpp llgesturelistener.cpp llgesturemgr.cpp llgiveinventory.cpp @@ -421,7 +420,10 @@ set(viewer_SOURCE_FILES llpanelblockedlist.cpp llpanelclassified.cpp llpanelcontents.cpp + llpaneleditsky.cpp + llpaneleditwater.cpp llpaneleditwearable.cpp + llpanelenvironment.cpp llpanelexperiencelisteditor.cpp llpanelexperiencelog.cpp llpanelexperiencepicker.cpp @@ -535,6 +537,7 @@ set(viewer_SOURCE_FILES llsecapi.cpp llsechandler_basic.cpp llselectmgr.cpp + llsettingsvo.cpp llshareavatarhandler.cpp llsidepanelappearance.cpp llsidepanelinventory.cpp @@ -689,19 +692,13 @@ set(viewer_SOURCE_FILES llvowater.cpp llvowlsky.cpp llwatchdog.cpp - llwaterparammanager.cpp - llwaterparamset.cpp llwearableitemslist.cpp llwearablelist.cpp llweb.cpp llwebprofile.cpp llwind.cpp llwindowlistener.cpp - llwlanimator.cpp - llwldaycycle.cpp llwlhandlers.cpp - llwlparammanager.cpp - llwlparamset.cpp llworld.cpp llworldmap.cpp llworldmapmessage.cpp @@ -780,7 +777,6 @@ set(viewer_HEADER_FILES llcurrencyuimanager.h llcylinder.h lldateutil.h - lldaycyclemanager.h lldebugmessagebox.h lldebugview.h lldeferredsounds.h @@ -803,7 +799,7 @@ set(viewer_HEADER_FILES lldrawpoolwlsky.h lldynamictexture.h llemote.h - llenvmanager.h + llenvironment.h llestateinfomodel.h lleventnotifier.h lleventpoll.h @@ -844,17 +840,15 @@ set(viewer_HEADER_FILES llfloaterconversationlog.h llfloaterconversationpreview.h llfloaterdeleteprefpreset.h - llfloaterdeleteenvpreset.h llfloaterdestinations.h - llfloatereditdaycycle.h - llfloatereditsky.h - llfloatereditwater.h + llfloatereditextdaycycle.h llfloaterenvironmentsettings.h llfloaterevent.h llfloaterexperiencepicker.h llfloaterexperienceprofile.h llfloaterexperiences.h llfloaterfacebook.h + llfloaterfixedenvironment.h llfloaterflickr.h llfloaterfonttest.h llfloatergesture.h @@ -943,6 +937,7 @@ set(viewer_HEADER_FILES llfolderviewmodelinventory.h llfollowcam.h llfriendcard.h + llflyoutcombobtn.h llgesturelistener.h llgesturemgr.h llgiveinventory.h @@ -1035,7 +1030,10 @@ set(viewer_HEADER_FILES llpanelblockedlist.h llpanelclassified.h llpanelcontents.h + llpaneleditsky.h + llpaneleditwater.h llpaneleditwearable.h + llpanelenvironment.h llpanelexperiencelisteditor.h llpanelexperiencelog.h llpanelexperiencepicker.h @@ -1148,6 +1146,7 @@ set(viewer_HEADER_FILES llsecapi.h llsechandler_basic.h llselectmgr.h + llsettingsvo.h llsidepanelappearance.h llsidepanelinventory.h llsidepanelinventorysubpanel.h @@ -1304,19 +1303,13 @@ set(viewer_HEADER_FILES llvowater.h llvowlsky.h llwatchdog.h - llwaterparammanager.h - llwaterparamset.h llwearableitemslist.h llwearablelist.h llweb.h llwebprofile.h llwind.h llwindowlistener.h - llwlanimator.h - llwldaycycle.h llwlhandlers.h - llwlparammanager.h - llwlparamset.h llworld.h llworldmap.h llworldmapmessage.h @@ -2372,7 +2365,6 @@ if (LL_TESTS) include(LLAddBuildTest) SET(viewer_TEST_SOURCE_FILES llagentaccess.cpp - llwlparammanager.cpp ) set_source_files_properties( ${viewer_TEST_SOURCE_FILES} diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml index ecd7c4bc36..380d7762d6 100644 --- a/indra/newview/app_settings/logcontrol.xml +++ b/indra/newview/app_settings/logcontrol.xml @@ -35,7 +35,7 @@ </array> <key>tags</key> <array> - </array> + </array> </map> <map> <key>level</key><string>DEBUG</string> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index bbd7f65383..7bb27f290c 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10134,6 +10134,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>RenderUseAdvancedAtmospherics</key> + <map> + <key>Comment</key> + <string>Use fancy precomputed atmospherics and stuff.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>RenderUseTriStrips</key> <map> <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl index 03bdb754b5..7f1a8cce0d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl @@ -397,7 +397,9 @@ void main() float da = dot(norm.xyz, sun_dir.xyz); float final_da = max(0.0,da); - final_da = min(final_da, 1.0f); + final_da = min(final_da, 1.0f); + +// why an ad hoc gamma boost here? srgb_to_linear instead? final_da = pow(final_da, 1.0/1.3); vec4 diffuse = texture2DRect(diffuseRect, tc); diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl index 6ff860362c..89b6a52909 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl @@ -23,7 +23,7 @@ * $/LicenseInfo$ */ -uniform vec4 sunlight_color_copy; +uniform vec4 sunlight_color; uniform vec4 light_ambient; vec3 atmosAmbient(vec3 light) @@ -33,12 +33,12 @@ vec3 atmosAmbient(vec3 light) vec3 atmosAffectDirectionalLight(float lightIntensity) { - return sunlight_color_copy.rgb * lightIntensity; + return sunlight_color.rgb * lightIntensity; } vec3 atmosGetDiffuseSunlightColor() { - return sunlight_color_copy.rgb; + return sunlight_color.rgb; } vec3 scaleDownLight(vec3 light) diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl index f7832521fa..cf076d156a 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -276,10 +276,6 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) { + tmpAmbient))); //brightness of surface both sunlight and ambient - /*setSunlitColor(pow(vec3(sunlight * .5), vec3(global_gamma)) * global_gamma); - setAmblitColor(pow(vec3(tmpAmbient * .25), vec3(global_gamma)) * global_gamma); - setAdditiveColor(pow(getAdditiveColor() * vec3(1.0 - temp1), vec3(global_gamma)) * global_gamma);*/ - setSunlitColor(vec3(sunlight * .5)); setAmblitColor(vec3(tmpAmbient * .25)); setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1)); diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl index 81af1fdc8a..b2d9de6e73 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl @@ -238,8 +238,8 @@ void main() proj_tc.xyz /= proj_tc.w; - float fa = falloff+1.0; - float dist_atten = min(1.0-(dist-1.0*(1.0-fa))/fa, 1.0); + float fa = falloff + 1.0; + float dist_atten = min(1.0 - (dist - 1.0 * (1.0 - fa)) / fa, 1.0); dist_atten *= dist_atten; dist_atten *= 2.0; diff --git a/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoF.glsl b/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoF.glsl new file mode 100644 index 0000000000..d27363a60c --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoF.glsl @@ -0,0 +1,69 @@ +/** + * @file advancedAtmoF.glsl + * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2005, 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$ + */ + +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif + +in vec3 view_dir; + +uniform vec3 cameraPosLocal; +uniform vec3 sun_direction; + +uniform sampler2D transmittance_texture; +uniform sampler3D scattering_texture; +uniform sampler3D mie_scattering_texture; + +vec3 GetSolarLuminance(); +vec3 GetSkyLuminance(vec3 camPos, vec3 view_dir, float shadow_length, vec3 sun_dir, out vec3 transmittance); +vec3 GetSkyLuminanceToPoint(vec3 camPos, vec3 pos, float shadow_length, vec3 sun_dir, out vec3 transmittance); +vec3 GetSunAndSkyIlluminance(vec3 pos, vec3 norm, vec3 sun_dir, out vec3 sky_irradiance); + +void main() +{ + vec3 view_direction = normalize(view_dir); + + vec3 camPos = cameraPosLocal; + vec3 transmittance; + vec3 radiance = GetSkyLuminance(camPos, view_direction, 0.0f, sun_direction, transmittance); + + radiance *= transmittance; + + // If the view ray intersects the Sun, add the Sun radiance. + if (dot(view_direction, sun_direction) >= sun_size.y) + { + radiance = radiance + transmittance * GetSolarLuminance(); + } + + vec3 color = vec3(1.0) - exp(-radiance); + color = pow(color, vec3(1.0 / 2.2)); + + frag_color.rgb = color; + + frag_color.a = 1.0; +} + diff --git a/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoV.glsl b/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoV.glsl new file mode 100644 index 0000000000..52a7595379 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoV.glsl @@ -0,0 +1,43 @@ +/** + * @file advancedAtmoV.glsl + * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2005, 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$ + */ + +uniform mat4 modelview_projection_matrix; + +ATTRIBUTE vec3 position; + +// Inputs +uniform vec3 camPosLocal; + +out vec3 view_dir; + +void main() +{ + // World / view / projection + gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); + + // this will be normalized in the frag shader... + view_dir = position.xyz - camPosLocal.xyz; +} + diff --git a/indra/newview/app_settings/shaders/class3/windlight/cloudsF.glsl b/indra/newview/app_settings/shaders/class3/windlight/cloudsF.glsl new file mode 100644 index 0000000000..96c70651b1 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/windlight/cloudsF.glsl @@ -0,0 +1,104 @@ +/** + * @file WLCloudsF.glsl + * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2005, 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$ + */ + +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif + +///////////////////////////////////////////////////////////////////////// +// The fragment shader for the sky +///////////////////////////////////////////////////////////////////////// + +VARYING vec4 vary_CloudColorSun; +VARYING vec4 vary_CloudColorAmbient; +VARYING float vary_CloudDensity; +VARYING vec2 vary_texcoord0; +VARYING vec2 vary_texcoord1; +VARYING vec2 vary_texcoord2; +VARYING vec2 vary_texcoord3; + +uniform sampler2D cloud_noise_texture; +uniform vec4 cloud_pos_density1; +uniform vec4 cloud_pos_density2; +uniform vec4 gamma; + +/// Soft clips the light with a gamma correction +vec3 scaleSoftClip(vec3 light) { + //soft clip effect: + light = 1. - clamp(light, vec3(0.), vec3(1.)); + light = 1. - pow(light, gamma.xxx); + + return light; +} + +void main() +{ + // Set variables + vec2 uv1 = vary_texcoord0.xy; + vec2 uv2 = vary_texcoord1.xy; + + vec4 cloudColorSun = vary_CloudColorSun; + vec4 cloudColorAmbient = vary_CloudColorAmbient; + float cloudDensity = vary_CloudDensity; + vec2 uv3 = vary_texcoord2.xy; + vec2 uv4 = vary_texcoord3.xy; + + // Offset texture coords + uv1 += cloud_pos_density1.xy; //large texture, visible density + uv2 += cloud_pos_density1.xy; //large texture, self shadow + uv3 += cloud_pos_density2.xy; //small texture, visible density + uv4 += cloud_pos_density2.xy; //small texture, self shadow + + + // Compute alpha1, the main cloud opacity + float alpha1 = (texture2D(cloud_noise_texture, uv1).x - 0.5) + (texture2D(cloud_noise_texture, uv3).x - 0.5) * cloud_pos_density2.z; + alpha1 = min(max(alpha1 + cloudDensity, 0.) * 10. * cloud_pos_density1.z, 1.); + + // And smooth + alpha1 = 1. - alpha1 * alpha1; + alpha1 = 1. - alpha1 * alpha1; + + + // Compute alpha2, for self shadowing effect + // (1 - alpha2) will later be used as percentage of incoming sunlight + float alpha2 = (texture2D(cloud_noise_texture, uv2).x - 0.5); + alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.); + + // And smooth + alpha2 = 1. - alpha2; + alpha2 = 1. - alpha2 * alpha2; + + // Combine + vec4 color; + color = (cloudColorSun*(1.-alpha2) + cloudColorAmbient); + color *= 2.; + + /// Gamma correct for WL (soft clip effect). + frag_color.rgb = scaleSoftClip(color.rgb); + frag_color.a = alpha1; +} + diff --git a/indra/newview/app_settings/shaders/class3/windlight/cloudsV.glsl b/indra/newview/app_settings/shaders/class3/windlight/cloudsV.glsl new file mode 100644 index 0000000000..c1dd45cd67 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/windlight/cloudsV.glsl @@ -0,0 +1,190 @@ +/** + * @file WLCloudsV.glsl + * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2005, 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$ + */ + +uniform mat4 modelview_projection_matrix; + +ATTRIBUTE vec3 position; +ATTRIBUTE vec2 texcoord0; + +////////////////////////////////////////////////////////////////////////// +// The vertex shader for creating the atmospheric sky +/////////////////////////////////////////////////////////////////////////////// + +// Output parameters +VARYING vec4 vary_CloudColorSun; +VARYING vec4 vary_CloudColorAmbient; +VARYING float vary_CloudDensity; +VARYING vec2 vary_texcoord0; +VARYING vec2 vary_texcoord1; +VARYING vec2 vary_texcoord2; +VARYING vec2 vary_texcoord3; + +// Inputs +uniform vec3 camPosLocal; + +uniform vec4 lightnorm; +uniform vec4 sunlight_color; +uniform vec4 ambient; +uniform vec4 blue_horizon; +uniform vec4 blue_density; +uniform float haze_horizon; +uniform float haze_density; + +uniform float cloud_shadow; +uniform float density_multiplier; +uniform float max_y; + +uniform vec4 glow; + +uniform vec4 cloud_color; + +uniform float cloud_scale; + +void main() +{ + + // World / view / projection + gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); + + vary_texcoord0 = texcoord0; + + // Get relative position + vec3 P = position.xyz - camPosLocal.xyz + vec3(0,50,0); + + // Set altitude + if (P.y > 0.) + { + P *= (max_y / P.y); + } + else + { + P *= (-32000. / P.y); + } + + // Can normalize then + vec3 Pn = normalize(P); + float Plen = length(P); + + // Initialize temp variables + vec4 temp1 = vec4(0.); + vec4 temp2 = vec4(0.); + vec4 blue_weight; + vec4 haze_weight; + vec4 sunlight = sunlight_color; + vec4 light_atten; + + + // Sunlight attenuation effect (hue and brightness) due to atmosphere + // this is used later for sunlight modulation at various altitudes + light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y); + + // Calculate relative weights + temp1 = blue_density + haze_density; + blue_weight = blue_density / temp1; + haze_weight = haze_density / temp1; + + // Compute sunlight from P & lightnorm (for long rays like sky) + temp2.y = max(0., max(0., Pn.y) * 1.0 + lightnorm.y ); + temp2.y = 1. / temp2.y; + sunlight *= exp( - light_atten * temp2.y); + + // Distance + temp2.z = Plen * density_multiplier; + + // Transparency (-> temp1) + // ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati + // compiler gets confused. + temp1 = exp(-temp1 * temp2.z); + + + // Compute haze glow + temp2.x = dot(Pn, lightnorm.xyz); + temp2.x = 1. - temp2.x; + // temp2.x is 0 at the sun and increases away from sun + temp2.x = max(temp2.x, .001); + // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) + temp2.x *= glow.x; + // Higher glow.x gives dimmer glow (because next step is 1 / "angle") + temp2.x = pow(temp2.x, glow.z); + // glow.z should be negative, so we're doing a sort of (1 / "angle") function + + // Add "minimum anti-solar illumination" + temp2.x += .25; + + // Increase ambient when there are more clouds + vec4 tmpAmbient = ambient; + tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5; + + // Dim sunlight by cloud shadow percentage + sunlight *= (1. - cloud_shadow); + + // Haze color below cloud + vec4 additiveColorBelowCloud = ( blue_horizon * blue_weight * (sunlight + tmpAmbient) + + (haze_horizon * haze_weight) * (sunlight * temp2.x + tmpAmbient) + ); + + // CLOUDS + + sunlight = sunlight_color; + temp2.y = max(0., lightnorm.y * 2.); + temp2.y = 1. / temp2.y; + sunlight *= exp( - light_atten * temp2.y); + + // Cloud color out + vary_CloudColorSun = (sunlight * temp2.x) * cloud_color; + vary_CloudColorAmbient = tmpAmbient * cloud_color; + + // Attenuate cloud color by atmosphere + temp1 = sqrt(temp1); //less atmos opacity (more transparency) below clouds + vary_CloudColorSun *= temp1; + vary_CloudColorAmbient *= temp1; + vec4 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - temp1); + + // Make a nice cloud density based on the cloud_shadow value that was passed in. + vary_CloudDensity = 2. * (cloud_shadow - 0.25); + + + // Texture coords + vary_texcoord0 = texcoord0; + vary_texcoord0.xy -= 0.5; + vary_texcoord0.xy /= cloud_scale; + vary_texcoord0.xy += 0.5; + + vary_texcoord1 = vary_texcoord0; + vary_texcoord1.x += lightnorm.x * 0.0125; + vary_texcoord1.y += lightnorm.z * 0.0125; + + vary_texcoord2 = vary_texcoord0 * 16.; + vary_texcoord3 = vary_texcoord1 * 16.; + + // Combine these to minimize register use + vary_CloudColorAmbient += oHazeColorBelowCloud; + + // needs this to compile on mac + //vary_AtmosAttenuation = vec3(0.0,0.0,0.0); + + // END CLOUDS +} + diff --git a/indra/newview/app_settings/shaders/class3/windlight/skyF.glsl b/indra/newview/app_settings/shaders/class3/windlight/skyF.glsl new file mode 100644 index 0000000000..c71eaf4b13 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/windlight/skyF.glsl @@ -0,0 +1,71 @@ +/** + * @file advancedAtmoF.glsl + * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2005, 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$ + */ + +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif + +in vec3 view_dir; + +uniform vec3 cameraPosLocal; +uniform vec3 sun_direction; +uniform vec2 sun_size; + +uniform sampler2D cloud_noise_texture; +uniform sampler2D transmittance_texture; +uniform sampler3D scattering_texture; +uniform sampler3D mie_scattering_texture; + +vec3 GetSolarLuminance(); +vec3 GetSkyLuminance(vec3 camPos, vec3 view_dir, float shadow_length, vec3 sun_dir, out vec3 transmittance); +vec3 GetSkyLuminanceToPoint(vec3 camPos, vec3 pos, float shadow_length, vec3 sun_dir, out vec3 transmittance); +vec3 GetSunAndSkyIlluminance(vec3 pos, vec3 norm, vec3 sun_dir, out vec3 sky_irradiance); + +void main() +{ + vec3 view_direction = normalize(view_dir); + + vec3 camPos = cameraPosLocal; + vec3 transmittance; + vec3 radiance = GetSkyLuminance(camPos, view_direction, 0.0f, sun_direction, transmittance); + + radiance *= transmittance; + + // If the view ray intersects the Sun, add the Sun radiance. + if (dot(view_direction, sun_direction) >= sun_size.y) + { + radiance = radiance + transmittance * GetSolarLuminance(); + } + + vec3 color = vec3(1.0) - exp(-radiance); + color = pow(color, vec3(1.0 / 2.2)); + + frag_color.rgb = color; + + frag_color.a = 1.0; +} + diff --git a/indra/newview/app_settings/shaders/class3/windlight/skyV.glsl b/indra/newview/app_settings/shaders/class3/windlight/skyV.glsl new file mode 100644 index 0000000000..52a7595379 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/windlight/skyV.glsl @@ -0,0 +1,43 @@ +/** + * @file advancedAtmoV.glsl + * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2005, 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$ + */ + +uniform mat4 modelview_projection_matrix; + +ATTRIBUTE vec3 position; + +// Inputs +uniform vec3 camPosLocal; + +out vec3 view_dir; + +void main() +{ + // World / view / projection + gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); + + // this will be normalized in the frag shader... + view_dir = position.xyz - camPosLocal.xyz; +} + diff --git a/indra/newview/app_settings/shaders/class3/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class3/windlight/transportF.glsl new file mode 100644 index 0000000000..8a8e4cb0f6 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/windlight/transportF.glsl @@ -0,0 +1,53 @@ +/** + * @file transportF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, 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$ + */ + +////////////////////////////////////////////////////////// +// The fragment shader for the terrain atmospherics +////////////////////////////////////////////////////////// + +vec3 getAdditiveColor(); +vec3 getAtmosAttenuation(); + +uniform sampler2D cloudMap; +uniform vec4 cloud_pos_density1; + +vec3 atmosTransport(vec3 light) { + light *= getAtmosAttenuation().r; + light += getAdditiveColor() * 2.0; + return light; +} + +vec3 fullbrightAtmosTransport(vec3 light) { + float brightness = dot(light.rgb, vec3(0.33333)); + + return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness); +} + +vec3 fullbrightShinyAtmosTransport(vec3 light) { + float brightness = dot(light.rgb, vec3(0.33333)); + + return mix(atmosTransport(light.rgb), (light.rgb + getAdditiveColor().rgb) * (2.0 - brightness), brightness * brightness); +} + diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 2243cbdf5a..b413c21033 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -42,7 +42,6 @@ #include "llchicletbar.h" #include "llconsole.h" #include "lldonotdisturbnotificationstorage.h" -#include "llenvmanager.h" #include "llfirstuse.h" #include "llfloatercamera.h" #include "llfloaterimcontainer.h" @@ -382,6 +381,7 @@ LLAgent::LLAgent() : mAgentOriginGlobal(), mPositionGlobal(), + mLastTestGlobal(), mDistanceTraveled(0.F), mLastPositionGlobal(LLVector3d::zero), @@ -1071,6 +1071,13 @@ void LLAgent::setPositionAgent(const LLVector3 &pos_agent) pos_agent_d.setVec(pos_agent); mPositionGlobal = pos_agent_d + mAgentOriginGlobal; } + + if (((mLastTestGlobal - mPositionGlobal).lengthSquared() > 1.0) && !mOnPositionChanged.empty()) + { // If the position has changed my more than 1 meter since the last time we triggered. + // filters out some noise. + mLastTestGlobal = mPositionGlobal; + mOnPositionChanged(mFrameAgent.getOrigin(), mPositionGlobal); + } } //----------------------------------------------------------------------------- @@ -1111,6 +1118,12 @@ const LLVector3 &LLAgent::getPositionAgent() return mFrameAgent.getOrigin(); } +boost::signals2::connection LLAgent::whenPositionChanged(position_signal_t::slot_type fn) +{ + return mOnPositionChanged.connect(fn); +} + + //----------------------------------------------------------------------------- // getRegionsVisited() //----------------------------------------------------------------------------- diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 4bb4d317e8..477ec88be4 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -189,6 +189,8 @@ private: // Position //-------------------------------------------------------------------- public: + typedef boost::signals2::signal<void(const LLVector3 &position_local, const LLVector3d &position_global)> position_signal_t; + LLVector3 getPosAgentFromGlobal(const LLVector3d &pos_global) const; LLVector3d getPosGlobalFromAgent(const LLVector3 &pos_agent) const; const LLVector3d &getPositionGlobal() const; @@ -196,10 +198,16 @@ public: // Call once per frame to update position, angles (radians). void updateAgentPosition(const F32 dt, const F32 yaw, const S32 mouse_x, const S32 mouse_y); void setPositionAgent(const LLVector3 ¢er); + + boost::signals2::connection whenPositionChanged(position_signal_t::slot_type fn); + protected: void propagate(const F32 dt); // ! BUG ! Should roll into updateAgentPosition private: - mutable LLVector3d mPositionGlobal; + mutable LLVector3d mPositionGlobal; + + position_signal_t mOnPositionChanged; + LLVector3d mLastTestGlobal; //-------------------------------------------------------------------- // Velocity 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(LLPointer<LLInventoryCallback const LLUUID& category_id, BOOL notify) { - 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); @@ -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<LLInventoryCallback> 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 c0f88ef704..e4a5c58c7b 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<LLInventoryCallback> 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/llappviewer.cpp b/indra/newview/llappviewer.cpp index ce4aab20c7..b3f0a810b4 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -171,8 +171,6 @@ #include "llviewerparcelmgr.h" #include "llworldmapview.h" #include "llpostprocess.h" -#include "llwlparammanager.h" -#include "llwaterparammanager.h" #include "lldebugview.h" #include "llconsole.h" @@ -208,6 +206,7 @@ #include "llfloateroutfitsnapshot.h" #include "llfloatersnapshot.h" #include "llsidepanelinventory.h" +#include "llatmosphere.h" // includes for idle() idleShutdown() #include "llviewercontrol.h" @@ -749,7 +748,9 @@ bool LLAppViewer::init() // initialize LLWearableType translation bridge. // Memory will be cleaned up in ::cleanupClass() - LLWearableType::initClass(new LLUITranslationBridge()); + LLTranslationBridge::ptr_t trans = std::make_shared<LLUITranslationBridge>(); + LLWearableType::initClass(trans); + LLSettingsType::initClass(trans); // initialize SSE options LLVector4a::initClass(); @@ -1082,6 +1083,7 @@ bool LLAppViewer::init() } } +#if LL_RELEASE_FOR_DOWNLOAD char* PARENT = getenv("PARENT"); if (! (PARENT && std::string(PARENT) == "SL_Launcher")) { @@ -1094,6 +1096,7 @@ bool LLAppViewer::init() // him/herself in the foot. LLNotificationsUtil::add("RunLauncher"); } +#endif #if LL_WINDOWS if (gGLManager.mGLVersion < LLFeatureManager::getInstance()->getExpectedGLVersion()) @@ -1618,6 +1621,8 @@ void LLAppViewer::flushVFSIO() bool LLAppViewer::cleanup() { + LLAtmosphere::cleanupClass(); + //ditch LLVOAvatarSelf instance gAgentAvatarp = NULL; diff --git a/indra/newview/lldaycyclemanager.cpp b/indra/newview/lldaycyclemanager.cpp index 803e2b2fb2..23d442f3b6 100644 --- a/indra/newview/lldaycyclemanager.cpp +++ b/indra/newview/lldaycyclemanager.cpp @@ -30,6 +30,9 @@ #include "lldiriterator.h" +#include "llenvironment.h" +#include "llsettingsdaycycle.h" + void LLDayCycleManager::getPresetNames(preset_name_list_t& names) const { names.clear(); diff --git a/indra/newview/lldaycyclemanager.h b/indra/newview/lldaycyclemanager.h index 04db9d5dac..810212c92a 100644 --- a/indra/newview/lldaycyclemanager.h +++ b/indra/newview/lldaycyclemanager.h @@ -30,7 +30,6 @@ #include <map> #include <string> -#include "llwldaycycle.h" #include "llwlparammanager.h" /** @@ -46,14 +45,14 @@ class LLDayCycleManager : public LLSingleton<LLDayCycleManager> public: typedef std::list<std::string> preset_name_list_t; - typedef std::map<std::string, LLWLDayCycle> dc_map_t; +// typedef std::map<std::string, LLWLDayCycle> dc_map_t; typedef boost::signals2::signal<void()> modify_signal_t; void getPresetNames(preset_name_list_t& names) const; void getPresetNames(preset_name_list_t& user, preset_name_list_t& sys) const; void getUserPresetNames(preset_name_list_t& user) const; - bool getPreset(const std::string name, LLWLDayCycle& day_cycle) const; +// bool getPreset(const std::string name, LLWLDayCycle& day_cycle) const; bool getPreset(const std::string name, LLSD& day_cycle) const; bool presetExists(const std::string name) const; bool isSystemPreset(const std::string& name) const; diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index df06ad31e6..567172e647 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -46,7 +46,9 @@ #include "llworld.h" #include "pipeline.h" #include "llviewershadermgr.h" -#include "llwaterparammanager.h" +#include "llenvironment.h" +#include "llsettingssky.h" +#include "llsettingswater.h" const LLUUID TRANSPARENT_WATER_TEXTURE("2bfd3884-7e27-69b9-ba3a-3e673f680004"); const LLUUID OPAQUE_WATER_TEXTURE("43c32285-d658-1793-c123-bf86315de055"); @@ -58,10 +60,10 @@ BOOL deferred_render = FALSE; BOOL LLDrawPoolWater::sSkipScreenCopy = FALSE; BOOL LLDrawPoolWater::sNeedsReflectionUpdate = TRUE; BOOL LLDrawPoolWater::sNeedsDistortionUpdate = TRUE; -LLColor4 LLDrawPoolWater::sWaterFogColor = LLColor4(0.2f, 0.5f, 0.5f, 0.f); +//LLColor4 LLDrawPoolWater::sWaterFogColor = LLColor4(0.2f, 0.5f, 0.5f, 0.f); F32 LLDrawPoolWater::sWaterFogEnd = 0.f; -LLVector3 LLDrawPoolWater::sLightDir; +//LLVector3 LLDrawPoolWater::sLightDir; LLDrawPoolWater::LLDrawPoolWater() : LLFacePool(POOL_WATER) @@ -110,8 +112,6 @@ void LLDrawPoolWater::prerender() // got rid of modulation by light color since it got a little too // green at sunset and sl-57047 (underwater turns black at 8:00) - sWaterFogColor = LLWaterParamManager::instance().getFogColor(); - sWaterFogColor.mV[3] = 0; } @@ -488,29 +488,50 @@ void LLDrawPoolWater::shade() LLVector3 light_dir; LLColor3 light_color; - if (gSky.getSunDirection().mV[2] > LLSky::NIGHTTIME_ELEVATION_COS) - { - light_dir = gSky.getSunDirection(); - light_dir.normVec(); - light_color = gSky.getSunDiffuseColor(); - if(gSky.mVOSkyp) { - light_diffuse = gSky.mVOSkyp->getSun().getColorCached(); - light_diffuse.normVec(); - } - light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0); - light_diffuse *= light_exp + 0.25f; - } - else - { - light_dir = gSky.getMoonDirection(); - light_dir.normVec(); - light_color = gSky.getMoonDiffuseColor(); - light_diffuse = gSky.mVOSkyp->getMoon().getColorCached(); - light_diffuse.normVec(); - light_diffuse *= 0.5f; - light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0); + LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); + LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater(); + + light_dir = psky->getLightDirection(); + if (LLEnvironment::instance().getIsDayTime()) + { + light_color = psky->getSunAmbient(); + light_diffuse = psky->getSunDiffuse(); + light_diffuse.normalize(); + light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0.f); + light_diffuse *= (light_exp + 0.25f); + } + else + { + light_color = psky->getMoonAmbient(); + light_diffuse = psky->getMoonDiffuse(); + light_diffuse.normalize(); + light_diffuse *= 0.5f; + light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0.f); } +// if (gSky.getSunDirection().mV[2] > LLSky::NIGHTTIME_ELEVATION_COS) +// { +// light_dir = gSky.getSunDirection(); +// light_dir.normVec(); +// light_color = gSky.getSunDiffuseColor(); +// if(gSky.mVOSkyp) { +// light_diffuse = gSky.mVOSkyp->getSun().getColorCached(); +// light_diffuse.normVec(); +// } +// light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0); +// light_diffuse *= light_exp + 0.25f; +// } +// else +// { +// light_dir = gSky.getMoonDirection(); +// light_dir.normVec(); +// light_color = gSky.getMoonDiffuseColor(); +// light_diffuse = gSky.mVOSkyp->getMoon().getColorCached(); +// light_diffuse.normVec(); +// light_diffuse *= 0.5f; +// light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0); +// } + light_exp *= light_exp; light_exp *= light_exp; light_exp *= light_exp; @@ -518,9 +539,11 @@ void LLDrawPoolWater::shade() light_exp *= 256.f; light_exp = light_exp > 32.f ? light_exp : 32.f; + light_diffuse *= 6.f; + LLGLSLShader* shader; - F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - gAgent.getRegion()->getWaterHeight(); + F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - LLEnvironment::instance().getWaterHeight(); if (eyedepth < 0.f && LLPipeline::sWaterReflections) { @@ -551,7 +574,7 @@ void LLDrawPoolWater::shade() shader->bind(); } - sTime = (F32)LLFrameTimer::getElapsedSeconds()*0.5f; + sTime = (F32)LLFrameTimer::getElapsedSeconds() * 0.5f; S32 reftex = shader->enableTexture(LLShaderMgr::WATER_REFTEX); @@ -565,12 +588,10 @@ void LLDrawPoolWater::shade() //bind normal map S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP); - LLWaterParamManager * param_mgr = &LLWaterParamManager::instance(); - // change mWaterNormp if needed - if (mWaterNormp->getID() != param_mgr->getNormalMapID()) + if (mWaterNormp->getID() != pwater->getNormalMapID()) { - mWaterNormp = LLViewerTextureManager::getFetchedTexture(param_mgr->getNormalMapID()); + mWaterNormp = LLViewerTextureManager::getFetchedTexture(pwater->getNormalMapID()); } mWaterNormp->addTextureStats(1024.f*1024.f); @@ -588,9 +609,8 @@ void LLDrawPoolWater::shade() if (screentex > -1) { - shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV); - shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, - param_mgr->getFogDensity()); + shader->uniform3fv(LLShaderMgr::WATER_FOGCOLOR, 1, pwater->getFogColor().mV); + shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, pwater->getFogDensity()); gPipeline.mWaterDis.bindTexture(0, screentex); } @@ -600,8 +620,9 @@ void LLDrawPoolWater::shade() if (mVertexShaderLevel == 1) { - sWaterFogColor.mV[3] = param_mgr->mDensitySliderValue; - shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV); + LLColor4 fog_color(pwater->getFogColor(), 0.f); + fog_color[3] = pwater->getFogDensity(); + shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, fog_color.mV); } F32 screenRes[] = @@ -615,25 +636,20 @@ void LLDrawPoolWater::shade() S32 diffTex = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP); stop_glerror(); - light_dir.normVec(); - sLightDir = light_dir; - - light_diffuse *= 6.f; - //shader->uniformMatrix4fv("inverse_ref", 1, GL_FALSE, (GLfloat*) gGLObliqueProjectionInverse.mMatrix); shader->uniform1f(LLShaderMgr::WATER_WATERHEIGHT, eyedepth); shader->uniform1f(LLShaderMgr::WATER_TIME, sTime); shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV); shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV); shader->uniform1f(LLShaderMgr::WATER_SPECULAR_EXP, light_exp); - shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, param_mgr->getWave1Dir().mV); - shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, param_mgr->getWave2Dir().mV); + shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, pwater->getWave1Dir().mV); + shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, pwater->getWave2Dir().mV); shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV); - shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, param_mgr->getNormalScale().mV); - shader->uniform1f(LLShaderMgr::WATER_FRESNEL_SCALE, param_mgr->getFresnelScale()); - shader->uniform1f(LLShaderMgr::WATER_FRESNEL_OFFSET, param_mgr->getFresnelOffset()); - shader->uniform1f(LLShaderMgr::WATER_BLUR_MULTIPLIER, param_mgr->getBlurMultiplier()); + shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, pwater->getNormalScale().mV); + shader->uniform1f(LLShaderMgr::WATER_FRESNEL_SCALE, pwater->getFresnelScale()); + shader->uniform1f(LLShaderMgr::WATER_FRESNEL_OFFSET, pwater->getFresnelOffset()); + shader->uniform1f(LLShaderMgr::WATER_BLUR_MULTIPLIER, pwater->getBlurMultiplier()); F32 sunAngle = llmax(0.f, light_dir.mV[2]); F32 scaledAngle = 1.f - sunAngle; @@ -648,12 +664,12 @@ void LLDrawPoolWater::shade() if (LLViewerCamera::getInstance()->cameraUnderWater()) { water_color.setVec(1.f, 1.f, 1.f, 0.4f); - shader->uniform1f(LLShaderMgr::WATER_REFSCALE, param_mgr->getScaleBelow()); + shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleBelow()); } else { water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot)); - shader->uniform1f(LLShaderMgr::WATER_REFSCALE, param_mgr->getScaleAbove()); + shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleAbove()); } if (water_color.mV[3] > 0.9f) diff --git a/indra/newview/lldrawpoolwater.h b/indra/newview/lldrawpoolwater.h index aeeba179d6..55f892d249 100644 --- a/indra/newview/lldrawpoolwater.h +++ b/indra/newview/lldrawpoolwater.h @@ -46,9 +46,8 @@ public: static BOOL sSkipScreenCopy; static BOOL sNeedsReflectionUpdate; static BOOL sNeedsDistortionUpdate; - static LLVector3 sLightDir; - - static LLColor4 sWaterFogColor; +// static LLVector3 sLightDir; +// static LLColor4 sWaterFogColor; static F32 sWaterFogEnd; enum diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index 309f535c39..a28041034b 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -33,7 +33,6 @@ #include "pipeline.h" #include "llviewercamera.h" #include "llimage.h" -#include "llwlparammanager.h" #include "llviewershadermgr.h" #include "llglslshader.h" #include "llsky.h" @@ -42,6 +41,9 @@ #include "llface.h" #include "llrender.h" +#include "llenvironment.h" +#include "llatmosphere.h" + LLPointer<LLViewerTexture> LLDrawPoolWLSky::sCloudNoiseTexture = NULL; LLPointer<LLImageRaw> LLDrawPoolWLSky::sCloudNoiseRawImage = NULL; @@ -80,8 +82,6 @@ LLDrawPoolWLSky::LLDrawPoolWLSky(void) : sCloudNoiseRawImage = NULL ; } } - - LLWLParamManager::getInstance()->propagateParameters(); } LLDrawPoolWLSky::~LLDrawPoolWLSky() @@ -126,38 +126,51 @@ void LLDrawPoolWLSky::endDeferredPass(S32 pass) void LLDrawPoolWLSky::renderDome(F32 camHeightLocal, LLGLSLShader * shader) const { - LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin(); - - llassert_always(NULL != shader); - - gGL.pushMatrix(); - - //chop off translation - if (LLPipeline::sReflectionRender && origin.mV[2] > 256.f) - { - gGL.translatef(origin.mV[0], origin.mV[1], 256.f-origin.mV[2]*0.5f); - } - else - { - gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]); - } + llassert_always(NULL != shader); + + static LLStaticHashedString sCamPosLocal("camPosLocal"); + + LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin(); + + if (gPipeline.useAdvancedAtmospherics()) + { + // Draw WL Sky w/ normal cam pos (where you are) for adv atmo sky + sky_shader->uniform3f(sCamPosLocal, origin.mV[0], origin.mV[1], origin.mV[2]); + +// TBD replace this with a FS tri pass, there's little point to the tess when you have fragment shaders... + + gSky.mVOWLSkyp->drawDome(); + } + else + { + gGL.pushMatrix(); + + //chop off translation + if (LLPipeline::sReflectionRender && origin.mV[2] > 256.f) + { + gGL.translatef(origin.mV[0], origin.mV[1], 256.f-origin.mV[2]*0.5f); + } + else + { + gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]); + } - // the windlight sky dome works most conveniently in a coordinate system - // where Y is up, so permute our basis vectors accordingly. - gGL.rotatef(120.f, 1.f / F_SQRT3, 1.f / F_SQRT3, 1.f / F_SQRT3); + // the windlight sky dome works most conveniently in a coordinate system + // where Y is up, so permute our basis vectors accordingly. + gGL.rotatef(120.f, 1.f / F_SQRT3, 1.f / F_SQRT3, 1.f / F_SQRT3); - gGL.scalef(0.333f, 0.333f, 0.333f); + gGL.scalef(0.333f, 0.333f, 0.333f); - gGL.translatef(0.f,-camHeightLocal, 0.f); + gGL.translatef(0.f,-camHeightLocal, 0.f); - // Draw WL Sky - static LLStaticHashedString sCamPosLocal("camPosLocal"); - shader->uniform3f(sCamPosLocal, 0.f, camHeightLocal, 0.f); + // Draw WL Sky + shader->uniform3f(sCamPosLocal, 0.f, camHeightLocal, 0.f); - gSky.mVOWLSkyp->drawDome(); + gSky.mVOWLSkyp->drawDome(); - gGL.popMatrix(); + gGL.popMatrix(); + } } void LLDrawPoolWLSky::renderSkyHaze(F32 camHeightLocal) const @@ -168,6 +181,33 @@ void LLDrawPoolWLSky::renderSkyHaze(F32 camHeightLocal) const sky_shader->bind(); + if (gPipeline.useAdvancedAtmospherics() && gPipeline.canUseWindLightShaders() && gAtmosphere) + { + // bind precomputed textures necessary for calculating sun and sky luminance + sky_shader->bindTexture(LLShaderMgr::TRANSMITTANCE_TEX, gAtmosphere->getTransmittance()); + sky_shader->bindTexture(LLShaderMgr::SCATTER_TEX, gAtmosphere->getScattering()); + sky_shader->bindTexture(LLShaderMgr::SINGLE_MIE_SCATTER_TEX, gAtmosphere->getMieScattering()); + + static float sunSize = (float)cos(0.0005); + + sky_shader->uniform1f(LLShaderMgr::SUN_SIZE, sunSize); + + static LLVector3 solDir(0.7f, 0.2f, 0.2f); + + //neither of these appear to track with the env settings, would the real sun please stand up. + //sky_shader->uniform3fv(LLShaderMgr::DEFERRED_SUN_DIR, 1, gPipeline.mTransformedSunDir.mV); + //sky_shader->uniform3fv(LLShaderMgr::DEFERRED_SUN_DIR, 1, gSky.mVOSkyp->getSun().getDirection().mV); + solDir.normalize(); + + sky_shader->uniform3fv(LLShaderMgr::DEFERRED_SUN_DIR, 1, solDir.mV); + + // clouds are rendered along with sky in adv atmo + if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && sCloudNoiseTexture.notNull()) + { + sky_shader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, sCloudNoiseTexture); + } + } + /// Render the skydome renderDome(camHeightLocal, sky_shader); @@ -190,14 +230,15 @@ void LLDrawPoolWLSky::renderStars(void) const // *NOTE: we divide by two here and GL_ALPHA_SCALE by two below to avoid // clamping and allow the star_alpha param to brighten the stars. - bool error; LLColor4 star_alpha(LLColor4::black); - star_alpha.mV[3] = LLWLParamManager::getInstance()->mCurParams.getFloat("star_brightness", error) / 2.f; + + // *LAPRAS + star_alpha.mV[3] = LLEnvironment::instance().getCurrentSky()->getStarBrightness() / (2.f + ((rand() >> 16)/65535.0f)); // twinkle twinkle // If start_brightness is not set, exit - if( error ) + if( star_alpha.mV[3] < 0.001 ) { - LL_WARNS() << "star_brightness missing in mCurParams" << LL_ENDL; + LL_DEBUGS("SKY") << "star_brightness below threshold." << LL_ENDL; return; } @@ -310,7 +351,8 @@ void LLDrawPoolWLSky::renderDeferred(S32 pass) } LL_RECORD_BLOCK_TIME(FTM_RENDER_WL_SKY); - const F32 camHeightLocal = LLWLParamManager::getInstance()->getDomeOffset() * LLWLParamManager::getInstance()->getDomeRadius(); + + const F32 camHeightLocal = LLEnvironment::instance().getCamHeight(); LLGLSNoFog disableFog; LLGLDepthTest depth(GL_TRUE, GL_FALSE); @@ -322,8 +364,10 @@ void LLDrawPoolWLSky::renderDeferred(S32 pass) renderSkyHaze(camHeightLocal); - LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin(); - gGL.pushMatrix(); + if (!gPipeline.useAdvancedAtmospherics() && gPipeline.canUseWindLightShaders()) + { + LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin(); + gGL.pushMatrix(); gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]); @@ -340,13 +384,12 @@ void LLDrawPoolWLSky::renderDeferred(S32 pass) gDeferredStarProgram.unbind(); - gGL.popMatrix(); + gGL.popMatrix(); + } renderSkyClouds(camHeightLocal); - - gGL.setColorMask(true, true); - //gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - + + gGL.setColorMask(true, true); } void LLDrawPoolWLSky::render(S32 pass) @@ -357,7 +400,7 @@ void LLDrawPoolWLSky::render(S32 pass) } LL_RECORD_BLOCK_TIME(FTM_RENDER_WL_SKY); - const F32 camHeightLocal = LLWLParamManager::getInstance()->getDomeOffset() * LLWLParamManager::getInstance()->getDomeRadius(); + const F32 camHeightLocal = LLEnvironment::instance().getCamHeight(); LLGLSNoFog disableFog; LLGLDepthTest depth(GL_TRUE, GL_FALSE); @@ -367,8 +410,10 @@ void LLDrawPoolWLSky::render(S32 pass) renderSkyHaze(camHeightLocal); - LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin(); - gGL.pushMatrix(); + if (!gPipeline.useAdvancedAtmospherics() && gPipeline.canUseWindLightShaders()) + { + LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin(); + gGL.pushMatrix(); gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]); @@ -380,9 +425,9 @@ void LLDrawPoolWLSky::render(S32 pass) renderHeavenlyBodies(); renderStars(); - - gGL.popMatrix(); + gGL.popMatrix(); + } renderSkyClouds(camHeightLocal); diff --git a/indra/newview/lldrawpoolwlsky.h b/indra/newview/lldrawpoolwlsky.h index cd15c991ee..586219e4bc 100644 --- a/indra/newview/lldrawpoolwlsky.h +++ b/indra/newview/lldrawpoolwlsky.h @@ -39,6 +39,8 @@ public: static const U32 STAR_VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXCOORD0; + static const U32 ADV_ATMO_SKY_VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX; + LLDrawPoolWLSky(void); /*virtual*/ ~LLDrawPoolWLSky(); diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp new file mode 100644 index 0000000000..e0cfbbf79e --- /dev/null +++ b/indra/newview/llenvironment.cpp @@ -0,0 +1,1809 @@ +/** + * @file llenvmanager.cpp + * @brief Implementation of classes managing WindLight and water settings. + * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, 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 "llenvironment.h" + +#include "llagent.h" +#include "llviewercontrol.h" // for gSavedSettings +#include "llviewerregion.h" +#include "llwlhandlers.h" +#include "lltrans.h" +#include "lltrace.h" +#include "llfasttimer.h" +#include "llviewercamera.h" +#include "pipeline.h" +#include "llsky.h" + +#include "llviewershadermgr.h" + +#include "llparcel.h" +#include "llviewerparcelmgr.h" + +#include "llsdserialize.h" +#include "lldiriterator.h" + +#include "llsettingsvo.h" +#include "llnotificationsutil.h" + +#include "llregioninfomodel.h" + +#include <boost/make_shared.hpp> + +//define EXPORT_PRESETS 1 +//========================================================================= +namespace +{ + LLTrace::BlockTimerStatHandle FTM_ENVIRONMENT_UPDATE("Update Environment Tick"); + LLTrace::BlockTimerStatHandle FTM_SHADER_PARAM_UPDATE("Update Shader Parameters"); + + //--------------------------------------------------------------------- + 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; + } + + LLSettingsDay::TrackBound_t get_bounding_entries(LLSettingsDay::CycleTrack_t &track, F32 keyframe) + { + return LLSettingsDay::TrackBound_t(get_wrapping_atbefore(track, keyframe), get_wrapping_atafter(track, keyframe)); + } + + //--------------------------------------------------------------------- + class LLTrackBlenderLoopingTime : public LLSettingsBlenderTimeDelta + { + public: + LLTrackBlenderLoopingTime(const LLSettingsBase::ptr_t &target, const LLSettingsDay::ptr_t &day, S32 trackno, F64Seconds cyclelength, F64Seconds cycleoffset) : + LLSettingsBlenderTimeDelta(target, LLSettingsBase::ptr_t(), LLSettingsBase::ptr_t(), F64Seconds(1.0)), + mDay(day), + mTrackNo(0), + mCycleLength(cyclelength), + mCycleOffset(cycleoffset) + { + LLSettingsDay::TrackBound_t initial = getBoundingEntries(getAdjustedNow()); + + mInitial = (*initial.first).second; + mFinal = (*initial.second).second; + mBlendSpan = getSpanTime(initial); + + mTrackNo = selectTrackNumber(trackno); + + setOnFinished([this](const LLSettingsBlender::ptr_t &){ onFinishedSpan(); }); + } + + + void switchTrack(S32 trackno, F64) override + { + S32 use_trackno = selectTrackNumber(trackno); + + if (use_trackno == mTrackNo) + { // results in no change + return; + } + + mTrackTransitionStart = mTarget->buildDerivedClone(); + mTrackNo = use_trackno; + + F64Seconds now = getAdjustedNow() + LLEnvironment::TRANSITION_ALTITUDE; + LLSettingsDay::TrackBound_t bounds = getBoundingEntries(now); + + LLSettingsBase::ptr_t pendsetting = (*bounds.first).second->buildDerivedClone(); + F64 targetpos = convertTimeToPosition(now) - (*bounds.first).first; + F64 targetspan = get_wrapping_distance((*bounds.first).first, (*bounds.second).first); + + F64 blendf = calculateBlend(targetpos, targetspan); + pendsetting->blend((*bounds.second).second, blendf); + + reset(mTrackTransitionStart, pendsetting, LLEnvironment::TRANSITION_ALTITUDE.value()); + } + + + protected: + S32 selectTrackNumber(S32 trackno) + { + if (trackno == 0) + { // We are dealing with the water track. There is only ever one. + return 0; + } + + for (S32 test = trackno; test == 0; --test) + { // Find the track below the requested one with data. + LLSettingsDay::CycleTrack_t &track = mDay->getCycleTrack(mTrackNo); + + if (!track.empty()) + return test; + } + + return 1; + } + + LLSettingsDay::TrackBound_t getBoundingEntries(F64Seconds time) + { + LLSettingsDay::CycleTrack_t &wtrack = mDay->getCycleTrack(mTrackNo); + F64 position = convertTimeToPosition(time); + + LLSettingsDay::TrackBound_t bounds = get_bounding_entries(wtrack, position); + return bounds; + } + + F64Seconds getAdjustedNow() const + { + F64Seconds now(LLDate::now().secondsSinceEpoch()); + + return (now + mCycleOffset); + } + + F64Seconds getSpanTime(const LLSettingsDay::TrackBound_t &bounds) const + { + return mCycleLength * get_wrapping_distance((*bounds.first).first, (*bounds.second).first); + } + + F64 convertTimeToPosition(F64Seconds time) + { + F64 position = static_cast<F64>(fmod(time.value(), mCycleLength.value())) / static_cast<F64>(mCycleLength.value()); + return llclamp(position, 0.0, 1.0); + } + + private: + LLSettingsDay::ptr_t mDay; + S32 mTrackNo; + F64Seconds mCycleLength; + F64Seconds mCycleOffset; + LLSettingsBase::ptr_t mTrackTransitionStart; + + void onFinishedSpan() + { + LLSettingsDay::TrackBound_t next = getBoundingEntries(getAdjustedNow()); + F64Seconds nextspan = getSpanTime(next); + reset((*next.first).second, (*next.second).second, nextspan.value()); + } + }; + +} + +//========================================================================= +const F32Seconds LLEnvironment::TRANSITION_INSTANT(0.0f); +const F32Seconds LLEnvironment::TRANSITION_FAST(1.0f); +const F32Seconds LLEnvironment::TRANSITION_DEFAULT(5.0f); +const F32Seconds LLEnvironment::TRANSITION_SLOW(10.0f); +const F32Seconds LLEnvironment::TRANSITION_ALTITUDE(5.0f); + +const F32 LLEnvironment::SUN_DELTA_YAW(F_PI); // 180deg +const F32 LLEnvironment::NIGHTTIME_ELEVATION_COS(LLSky::NIGHTTIME_ELEVATION_COS); + +//------------------------------------------------------------------------- +LLEnvironment::LLEnvironment(): + mSelectedSky(), + mSelectedWater(), + mSelectedDay(), + mSkysById(), + mSkysByName(), + mWaterByName(), + mWaterById(), + mDayCycleByName(), + mDayCycleById(), + mUserPrefs(), + mSelectedEnvironment(LLEnvironment::ENV_LOCAL), + mCurrentTrack(1) +{ +} + +void LLEnvironment::initSingleton() +{ + LLSettingsSky::ptr_t p_default_sky = LLSettingsVOSky::buildDefaultSky(); + addSky(p_default_sky); + + LLSettingsWater::ptr_t p_default_water = LLSettingsVOWater::buildDefaultWater(); + addWater(p_default_water); + + LLSettingsDay::ptr_t p_default_day = LLSettingsVODay::buildDefaultDayCycle(); + addDayCycle(p_default_day); + + mCurrentEnvironment = std::make_shared<DayInstance>(); + mCurrentEnvironment->setSky(p_default_sky); + mCurrentEnvironment->setWater(p_default_water); + + mEnvironments[ENV_DEFAULT] = mCurrentEnvironment; + + // LEGACY! + legacyLoadAllPresets(); + + requestRegionEnvironment(); + + LLRegionInfoModel::instance().setUpdateCallback([this]() { onParcelChange(); }); + gAgent.addParcelChangedCallback([this]() { onParcelChange(); }); + + //TODO: This frequently results in one more request than we need. It isn't breaking, but should be nicer. + gAgent.addRegionChangedCallback([this]() { requestRegionEnvironment(); }); + + gAgent.whenPositionChanged([this](const LLVector3 &localpos, const LLVector3d &) { onAgentPositionHasChanged(localpos); }); +} + +LLEnvironment::~LLEnvironment() +{ +} + +void LLEnvironment::loadPreferences() +{ + mUserPrefs.load(); +} + +void LLEnvironment::updatePreferences() +{ + /*NOOP for now. TODO record prefs and store.*/ +} + +bool LLEnvironment::canEdit() const +{ + return true; +} + +bool LLEnvironment::isExtendedEnvironmentEnabled() const +{ + return !gAgent.getRegionCapability("ExtEnvironment").empty(); +} + +bool LLEnvironment::isInventoryEnabled() const +{ + return (!gAgent.getRegionCapability("UpdateSettingsAgentInventory").empty() && + !gAgent.getRegionCapability("UpdateSettingsTaskInventory").empty()); +} + + +LLEnvironment::connection_t LLEnvironment::setSkyListChange(const LLEnvironment::change_signal_t::slot_type& cb) +{ + return mSkyListChange.connect(cb); +} + +LLEnvironment::connection_t LLEnvironment::setWaterListChange(const LLEnvironment::change_signal_t::slot_type& cb) +{ + return mWaterListChange.connect(cb); +} + +LLEnvironment::connection_t LLEnvironment::setDayCycleListChange(const LLEnvironment::change_signal_t::slot_type& cb) +{ + return mDayCycleListChange.connect(cb); +} + +void LLEnvironment::onParcelChange() +{ + S32 parcel_id(INVALID_PARCEL_ID); + LLParcel* parcel = LLViewerParcelMgr::instance().getAgentParcel(); + + if (parcel) + { + parcel_id = parcel->getLocalID(); + } + + requestParcel(parcel_id); +} + +void LLEnvironment::requestRegionEnvironment() +{ + requestRegion(); +} + +void LLEnvironment::onLegacyRegionSettings(LLSD data) +{ + LLUUID regionId = data[0]["regionID"].asUUID(); + + LLSettingsDay::ptr_t regionday; + if (data[1].isUndefined()) + regionday = LLEnvironment::findDayCycleByName("Default"); + else + regionday = LLSettingsVODay::buildFromLegacyMessage(regionId, data[1], data[2], data[3]); + + clearEnvironment(ENV_PARCEL); + setEnvironment(ENV_REGION, regionday, LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET); + + updateEnvironment(); +} + +//------------------------------------------------------------------------- +F32 LLEnvironment::getCamHeight() const +{ + return (mCurrentEnvironment->getSky()->getDomeOffset() * mCurrentEnvironment->getSky()->getDomeRadius()); +} + +F32 LLEnvironment::getWaterHeight() const +{ + return gAgent.getRegion()->getWaterHeight(); +} + +bool LLEnvironment::getIsDayTime() const +{ + return mCurrentEnvironment->getSky()->getSunDirection().mV[2] > NIGHTTIME_ELEVATION_COS; +} + +//------------------------------------------------------------------------- +void LLEnvironment::setSelectedEnvironment(LLEnvironment::EnvSelection_t env, F64Seconds transition, bool forced) +{ + mSelectedEnvironment = env; + updateEnvironment(transition, forced); +} + +bool LLEnvironment::hasEnvironment(LLEnvironment::EnvSelection_t env) +{ + if ((env < ENV_EDIT) || (env >= ENV_DEFAULT) || (!mEnvironments[env])) + { + return false; + } + + return true; +} + +LLEnvironment::DayInstance::ptr_t LLEnvironment::getEnvironmentInstance(LLEnvironment::EnvSelection_t env, bool create /*= false*/) +{ + DayInstance::ptr_t environment = mEnvironments[env]; +// if (!environment && create) + if (create) + { + environment = std::make_shared<DayInstance>(); + mEnvironments[env] = environment; + } + + return environment; +} + + +void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, const LLSettingsDay::ptr_t &pday, S64Seconds daylength, S64Seconds dayoffset) +{ + if ((env < ENV_EDIT) || (env >= ENV_DEFAULT)) + { + LL_WARNS("ENVIRONMENT") << "Attempt to change invalid environment selection." << LL_ENDL; + return; + } + + DayInstance::ptr_t environment = getEnvironmentInstance(env, true); + + environment->clear(); + environment->setDay(pday, daylength, dayoffset); + environment->setSkyTrack(mCurrentTrack); + environment->animate(); + /*TODO: readjust environment*/ +} + + +void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, LLEnvironment::fixedEnvironment_t fixed) +{ + if ((env < ENV_EDIT) || (env >= ENV_DEFAULT)) + { + LL_WARNS("ENVIRONMENT") << "Attempt to change invalid environment selection." << LL_ENDL; + return; + } + + DayInstance::ptr_t environment = getEnvironmentInstance(env, true); + + environment->clear(); + environment->setSky((fixed.first) ? fixed.first : mEnvironments[ENV_DEFAULT]->getSky()); + environment->setWater((fixed.second) ? fixed.second : mEnvironments[ENV_DEFAULT]->getWater()); + + /*TODO: readjust environment*/ +} + +void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, const LLSettingsBase::ptr_t &settings) +{ + DayInstance::ptr_t environment = getEnvironmentInstance(env); + + if (env == ENV_DEFAULT) + { + LL_WARNS("ENVIRONMENT") << "Attempt to set default environment. Not allowed." << LL_ENDL; + return; + } + + if (!settings) + { + clearEnvironment(env); + return; + } + + if (settings->getSettingType() == "daycycle") + { + S64Seconds daylength(LLSettingsDay::DEFAULT_DAYLENGTH); + S64Seconds dayoffset(LLSettingsDay::DEFAULT_DAYOFFSET); + if (environment) + { + daylength = environment->getDayLength(); + dayoffset = environment->getDayOffset(); + } + setEnvironment(env, std::static_pointer_cast<LLSettingsDay>(settings), daylength, dayoffset); + } + else if (settings->getSettingType() == "sky") + { + fixedEnvironment_t fixedenv(std::static_pointer_cast<LLSettingsSky>(settings), LLSettingsWater::ptr_t()); + if (environment) + { + fixedenv.second = environment->getWater(); + } + setEnvironment(env, fixedenv); + } + else if (settings->getSettingType() == "water") + { + fixedEnvironment_t fixedenv(LLSettingsSky::ptr_t(), std::static_pointer_cast<LLSettingsWater>(settings)); + if (environment) + { + fixedenv.first = environment->getSky(); + } + setEnvironment(env, fixedenv); + } +} + + +void LLEnvironment::clearEnvironment(LLEnvironment::EnvSelection_t env) +{ + if ((env < ENV_EDIT) || (env >= ENV_DEFAULT)) + { + LL_WARNS("ENVIRONMENT") << "Attempt to change invalid environment selection." << LL_ENDL; + return; + } + + mEnvironments[env].reset(); + /*TODO: readjust environment*/ +} + +LLSettingsDay::ptr_t LLEnvironment::getEnvironmentDay(LLEnvironment::EnvSelection_t env) +{ + if ((env < ENV_EDIT) || (env > ENV_DEFAULT)) + { + LL_WARNS("ENVIRONMENT") << "Attempt to retrieve invalid environment selection." << LL_ENDL; + return LLSettingsDay::ptr_t(); + } + + DayInstance::ptr_t environment = getEnvironmentInstance(env); + + if (environment) + return environment->getDayCycle(); + + return LLSettingsDay::ptr_t(); +} + +S64Seconds LLEnvironment::getEnvironmentDayLength(EnvSelection_t env) +{ + if ((env < ENV_EDIT) || (env > ENV_DEFAULT)) + { + LL_WARNS("ENVIRONMENT") << "Attempt to retrieve invalid environment selection." << LL_ENDL; + return S64Seconds(0); + } + + DayInstance::ptr_t environment = getEnvironmentInstance(env); + + if (environment) + return environment->getDayLength(); + + return S64Seconds(0); +} + +S64Seconds LLEnvironment::getEnvironmentDayOffset(EnvSelection_t env) +{ + if ((env < ENV_EDIT) || (env > ENV_DEFAULT)) + { + LL_WARNS("ENVIRONMENT") << "Attempt to retrieve invalid environment selection." << LL_ENDL; + return S64Seconds(0); + } + + DayInstance::ptr_t environment = getEnvironmentInstance(env); + if (environment) + return environment->getDayOffset(); + + return S64Seconds(0); +} + + +LLEnvironment::fixedEnvironment_t LLEnvironment::getEnvironmentFixed(LLEnvironment::EnvSelection_t env) +{ + if (env == ENV_CURRENT) + { + fixedEnvironment_t fixed; + for (S32 idx = mSelectedEnvironment; idx < ENV_END; ++idx) + { + if (fixed.first && fixed.second) + break; + + if (idx == ENV_EDIT) + continue; // skip the edit environment. + + DayInstance::ptr_t environment = getEnvironmentInstance(static_cast<EnvSelection_t>(idx)); + if (environment) + { + if (!fixed.first) + fixed.first = environment->getSky(); + if (!fixed.second) + fixed.second = environment->getWater(); + } + } + + if (!fixed.first || !fixed.second) + LL_WARNS("ENVIRONMENT") << "Can not construct complete fixed environment. Missing Sky and/or Water." << LL_ENDL; + + return fixed; + } + + if ((env < ENV_EDIT) || (env > ENV_DEFAULT)) + { + LL_WARNS("ENVIRONMENT") << "Attempt to retrieve invalid environment selection." << LL_ENDL; + return fixedEnvironment_t(); + } + + DayInstance::ptr_t environment = getEnvironmentInstance(env); + + if (environment) + return fixedEnvironment_t(environment->getSky(), environment->getWater()); + + return fixedEnvironment_t(); +} + +LLEnvironment::DayInstance::ptr_t LLEnvironment::getSelectedEnvironmentInstance() +{ + for (S32 idx = mSelectedEnvironment; idx < ENV_DEFAULT; ++idx) + { + if (mEnvironments[idx]) + return mEnvironments[idx]; + } + + return mEnvironments[ENV_DEFAULT]; +} + + +void LLEnvironment::updateEnvironment(F64Seconds transition, bool forced) +{ + DayInstance::ptr_t pinstance = getSelectedEnvironmentInstance(); + + if ((mCurrentEnvironment != pinstance) || forced) + { + DayInstance::ptr_t trans = std::make_shared<DayTransition>( + mCurrentEnvironment->getSky(), mCurrentEnvironment->getWater(), pinstance, transition); + + trans->animate(); + + mCurrentEnvironment = trans; + } +} + +//------------------------------------------------------------------------- +void LLEnvironment::update(const LLViewerCamera * cam) +{ + LL_RECORD_BLOCK_TIME(FTM_ENVIRONMENT_UPDATE); + //F32Seconds now(LLDate::now().secondsSinceEpoch()); + static LLFrameTimer timer; + + F32Seconds delta(timer.getElapsedTimeAndResetF32()); + + mCurrentEnvironment->update(delta); + + // update clouds, sun, and general + updateCloudScroll(); + + F32 camYaw = cam->getYaw(); + + stop_glerror(); + + // *TODO: potential optimization - this block may only need to be + // executed some of the time. For example for water shaders only. + { + LLVector3 lightNorm3( getLightDirection() ); + + lightNorm3 *= LLQuaternion(-(camYaw + SUN_DELTA_YAW), LLVector3(0.f, 1.f, 0.f)); + mRotatedLight = LLVector4(lightNorm3, 0.f); + + LLViewerShaderMgr::shader_iter shaders_iter, end_shaders; + end_shaders = LLViewerShaderMgr::instance()->endShaders(); + for (shaders_iter = LLViewerShaderMgr::instance()->beginShaders(); shaders_iter != end_shaders; ++shaders_iter) + { + if ((shaders_iter->mProgramObject != 0) + && (gPipeline.canUseWindLightShaders() + || shaders_iter->mShaderGroup == LLGLSLShader::SG_WATER)) + { + shaders_iter->mUniformsDirty = TRUE; + } + } + } +} + +void LLEnvironment::updateCloudScroll() +{ + // This is a function of the environment rather than the sky, since it should + // persist through sky transitions. + static LLTimer s_cloud_timer; + + F64 delta_t = s_cloud_timer.getElapsedTimeAndResetF64(); + + if (mCurrentEnvironment->getSky()) + { + LLVector2 cloud_delta = static_cast<F32>(delta_t)* (mCurrentEnvironment->getSky()->getCloudScrollRate() - LLVector2(10.0, 10.0)) / 100.0; + mCloudScrollDelta += cloud_delta; + } + +} + +void LLEnvironment::updateGLVariablesForSettings(LLGLSLShader *shader, const LLSettingsBase::ptr_t &psetting) +{ + LL_RECORD_BLOCK_TIME(FTM_SHADER_PARAM_UPDATE); + + //_WARNS("RIDER") << "----------------------------------------------------------------" << LL_ENDL; + LLSettingsBase::parammapping_t params = psetting->getParameterMap(); + for (auto &it: params) + { + if (!psetting->mSettings.has(it.first)) + continue; + + LLSD value = psetting->mSettings[it.first]; + LLSD::Type setting_type = value.type(); + + stop_glerror(); + switch (setting_type) + { + case LLSD::TypeInteger: + shader->uniform1i(it.second, value.asInteger()); + //_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << value << LL_ENDL; + break; + case LLSD::TypeReal: + shader->uniform1f(it.second, value.asReal()); + //_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << value << LL_ENDL; + break; + + case LLSD::TypeBoolean: + shader->uniform1i(it.second, value.asBoolean() ? 1 : 0); + //_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << value << LL_ENDL; + break; + + case LLSD::TypeArray: + { + LLVector4 vect4(value); + //_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << vect4 << LL_ENDL; + shader->uniform4fv(it.second, 1, vect4.mV); + + break; + } + + // case LLSD::TypeMap: + // case LLSD::TypeString: + // case LLSD::TypeUUID: + // case LLSD::TypeURI: + // case LLSD::TypeBinary: + // case LLSD::TypeDate: + default: + break; + } + stop_glerror(); + } + //_WARNS("RIDER") << "----------------------------------------------------------------" << LL_ENDL; + + psetting->applySpecial(shader); + + if (LLPipeline::sRenderDeferred && !LLPipeline::sReflectionRender && !LLPipeline::sUnderWaterRender) + { + shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2); + } + else + { + shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0); + } + +} + +void LLEnvironment::updateShaderUniforms(LLGLSLShader *shader) +{ + if (gPipeline.canUseWindLightShaders()) + { + updateGLVariablesForSettings(shader, mCurrentEnvironment->getSky()); + updateGLVariablesForSettings(shader, mCurrentEnvironment->getWater()); + } + + if (shader->mShaderGroup == LLGLSLShader::SG_DEFAULT) + { + stop_glerror(); + shader->uniform4fv(LLShaderMgr::LIGHTNORM, 1, mRotatedLight.mV); + shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV); + stop_glerror(); + } + else if (shader->mShaderGroup == LLGLSLShader::SG_SKY) + { + stop_glerror(); + shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, getClampedLightDirection().mV); + stop_glerror(); + } + + shader->uniform1f(LLShaderMgr::SCENE_LIGHT_STRENGTH, getSceneLightStrength()); +} + +LLEnvironment::list_name_id_t LLEnvironment::getSkyList() const +{ + list_name_id_t list; + + list.reserve(mSkysByName.size()); + + for (auto &it: mSkysByName) + { + list.push_back(std::vector<name_id_t>::value_type(it.second->getName(), it.second->getId())); + } + + return list; +} + +LLEnvironment::list_name_id_t LLEnvironment::getWaterList() const +{ + list_name_id_t list; + + list.reserve(mWaterByName.size()); + + for (auto &it : mWaterByName) + { + list.push_back(std::vector<name_id_t>::value_type(it.second->getName(), it.second->getId())); + } + + return list; +} + +LLEnvironment::list_name_id_t LLEnvironment::getDayCycleList() const +{ + list_name_id_t list; + + list.reserve(mDayCycleByName.size()); + + for (auto &it: mDayCycleByName) + { + list.push_back(std::vector<name_id_t>::value_type(it.second->getName(), it.second->getId())); + } + + return list; +} + +void LLEnvironment::addSky(const LLSettingsSky::ptr_t &sky) +{ + std::string name = sky->getValue(LLSettingsSky::SETTING_NAME).asString(); + + LL_WARNS("RIDER") << "Adding sky as '" << name << "'" << LL_ENDL; + + auto result = mSkysByName.insert(namedSettingMap_t::value_type(name, sky)); // auto should be: std::pair<namedSettingMap_t::iterator, bool> + + if (!result.second) + (*(result.first)).second = sky; + mSkyListChange(); +} + +void LLEnvironment::removeSky(const std::string &name) +{ + auto it = mSkysByName.find(name); + if (it != mSkysByName.end()) + mSkysByName.erase(it); + mSkyListChange(); +} + +void LLEnvironment::clearAllSkys() +{ + mSkysByName.clear(); + mSkysById.clear(); + mSkyListChange(); +} + +void LLEnvironment::addWater(const LLSettingsWater::ptr_t &water) +{ + std::string name = water->getValue(LLSettingsWater::SETTING_NAME).asString(); + + LL_WARNS("RIDER") << "Adding water as '" << name << "'" << LL_ENDL; + + auto result = mWaterByName.insert(namedSettingMap_t::value_type(name, water)); + + if (!result.second) + (*(result.first)).second = water; + mWaterListChange(); +} + + +void LLEnvironment::removeWater(const std::string &name) +{ + auto it = mWaterByName.find(name); + if (it != mWaterByName.end()) + mWaterByName.erase(it); + mWaterListChange(); +} + +void LLEnvironment::clearAllWater() +{ + mWaterByName.clear(); + mWaterById.clear(); + mWaterListChange(); +} + +void LLEnvironment::addDayCycle(const LLSettingsDay::ptr_t &daycycle) +{ + std::string name = daycycle->getValue(LLSettingsDay::SETTING_NAME).asString(); + + LL_WARNS("RIDER") << "Adding daycycle as '" << name << "'" << LL_ENDL; + + auto result = mDayCycleByName.insert(namedSettingMap_t::value_type(name, daycycle)); + + if (!result.second) + (*(result.first)).second = daycycle; + mDayCycleListChange(); +} + +//void LLEnvironment::addDayCycle(const LLUUID &id, const LLSettingsSky::ptr_t &sky); + +void LLEnvironment::removeDayCycle(const std::string &name) +{ + auto it = mDayCycleByName.find(name); + if (it != mDayCycleByName.end()) + mDayCycleByName.erase(it); + mDayCycleListChange(); +} + +//void LLEnvironment::removeDayCycle(const LLUUID &id); +void LLEnvironment::clearAllDayCycles() +{ + mDayCycleByName.clear(); + mWaterById.clear(); + mDayCycleListChange(); +} + +LLSettingsSky::ptr_t LLEnvironment::findSkyByName(std::string name) const +{ + auto it = mSkysByName.find(name); + + if (it == mSkysByName.end()) + { + LL_WARNS("ENVIRONMENT") << "Unable to find sky with unknown name '" << name << "'" << LL_ENDL; + return LLSettingsSky::ptr_t(); + } + + return std::static_pointer_cast<LLSettingsSky>((*it).second); +} + +LLSettingsWater::ptr_t LLEnvironment::findWaterByName(std::string name) const +{ + auto it = mWaterByName.find(name); + + if (it == mWaterByName.end()) + { + LL_WARNS("ENVIRONMENT") << "Unable to find water with unknown name '" << name << "'" << LL_ENDL; + return LLSettingsWater::ptr_t(); + } + + return std::static_pointer_cast<LLSettingsWater>((*it).second); +} + +LLSettingsDay::ptr_t LLEnvironment::findDayCycleByName(std::string name) const +{ + auto it = mDayCycleByName.find(name); + + if (it == mDayCycleByName.end()) + { + LL_WARNS("ENVIRONMENT") << "Unable to find daycycle with unknown name '" << name << "'" << LL_ENDL; + return LLSettingsDay::ptr_t(); + } + + return std::static_pointer_cast<LLSettingsDay>((*it).second); +} + + +void LLEnvironment::recordEnvironment(S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envinfo) +{ + LL_WARNS("ENVIRONMENT") << "Have environment" << LL_ENDL; + + LLSettingsDay::ptr_t pday = LLSettingsVODay::buildFromEnvironmentMessage(envinfo->mDaycycleData); + + LL_WARNS("ENVIRONMENT") << "serverhash=" << envinfo->mDayHash << " viewerhash=" << pday->getHash() << LL_ENDL; + + if (envinfo->mParcelId == INVALID_PARCEL_ID) + { // the returned info applies to an entire region. + LL_WARNS("LAPRAS") << "Setting Region environment" << LL_ENDL; + setEnvironment(ENV_REGION, pday, envinfo->mDayLength, envinfo->mDayOffset); + if (parcel_id != INVALID_PARCEL_ID) + { + LL_WARNS("LAPRAS") << "Had requested parcel environment #" << parcel_id << " but got region." << LL_ENDL; + clearEnvironment(ENV_PARCEL); + } + + mTrackAltitudes = envinfo->mAltitudes; + + LL_WARNS("LAPRAS") << "Altitudes set to {" << mTrackAltitudes[0] << ", "<< mTrackAltitudes[1] << ", " << mTrackAltitudes[2] << ", " << mTrackAltitudes[3] << LL_ENDL; + } + else + { + LLParcel *parcel = LLViewerParcelMgr::instance().getAgentParcel(); + + LL_WARNS("LAPRAS") << "Have parcel environment #" << envinfo->mParcelId << LL_ENDL; + if (parcel && (parcel->getLocalID() != parcel_id)) + { + LL_WARNS("ENVIRONMENT") << "Requested parcel #" << parcel_id << " agent is on " << parcel->getLocalID() << LL_ENDL; + return; + } + + setEnvironment(ENV_PARCEL, pday, envinfo->mDayLength, envinfo->mDayOffset); + } + + /*TODO: track_altitudes*/ + updateEnvironment(); +} + +//========================================================================= +void LLEnvironment::requestRegion() +{ + if (!isExtendedEnvironmentEnabled()) + { + LLEnvironmentRequest::initiate(); + return; + } + + requestParcel(INVALID_PARCEL_ID); +} + +void LLEnvironment::updateRegion(LLSettingsDay::ptr_t &pday, S32 day_length, S32 day_offset) +{ + if (!isExtendedEnvironmentEnabled()) + { + LLEnvironmentApply::initiateRequest( LLSettingsVODay::convertToLegacy(pday) ); + return; + } + + updateParcel(INVALID_PARCEL_ID, pday, day_length, day_offset); +} + +void LLEnvironment::resetRegion() +{ + resetParcel(INVALID_PARCEL_ID); +} + +void LLEnvironment::requestParcel(S32 parcel_id) +{ + std::string coroname = + LLCoros::instance().launch("LLEnvironment::coroRequestEnvironment", + boost::bind(&LLEnvironment::coroRequestEnvironment, this, parcel_id, + [this](S32 pid, EnvironmentInfo::ptr_t envinfo) { recordEnvironment(pid, envinfo); })); +} + +void LLEnvironment::updateParcel(S32 parcel_id, LLSettingsDay::ptr_t &pday, S32 day_length, S32 day_offset) +{ + std::string coroname = + LLCoros::instance().launch("LLEnvironment::coroUpdateEnvironment", + boost::bind(&LLEnvironment::coroUpdateEnvironment, this, parcel_id, + pday, day_length, day_offset, + [this](S32 pid, EnvironmentInfo::ptr_t envinfo) { recordEnvironment(pid, envinfo); })); +} + +void LLEnvironment::resetParcel(S32 parcel_id) +{ + std::string coroname = + LLCoros::instance().launch("LLEnvironment::coroResetEnvironment", + boost::bind(&LLEnvironment::coroResetEnvironment, this, parcel_id, + [this](S32 pid, EnvironmentInfo::ptr_t envinfo) { recordEnvironment(pid, envinfo); })); +} + +void LLEnvironment::coroRequestEnvironment(S32 parcel_id, LLEnvironment::environment_apply_fn apply) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("ResetEnvironment", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + + std::string url = gAgent.getRegionCapability("ExtEnvironment"); + if (url.empty()) + return; + + LL_WARNS("LAPRAS") << "Requesting for parcel_id=" << parcel_id << LL_ENDL; + + if (parcel_id != INVALID_PARCEL_ID) + { + std::stringstream query; + + query << "?parcelid=" << parcel_id; + url += query.str(); + } + + LL_WARNS("LAPRAS") << "url=" << url << LL_ENDL; + + LLSD result = httpAdapter->getAndSuspend(httpRequest, url); + // results that come back may contain the new settings + + LLSD notify; + + LLSD httpResults = result["http_result"]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + if (!status) + { + LL_WARNS("WindlightCaps") << "Couldn't retrieve Windlight settings for " << ((parcel_id == INVALID_PARCEL_ID) ? ("region!") : ("parcel!")) << LL_ENDL; + + std::stringstream msg; + msg << status.toString() << " (Code " << status.toTerseString() << ")"; + notify = LLSD::emptyMap(); + notify["FAIL_REASON"] = msg.str(); + + } + else + { + LLSD environment = result["environment"]; + if (environment.isDefined() && apply) + { + EnvironmentInfo::ptr_t envinfo = LLEnvironment::EnvironmentInfo::extract(environment); + apply(parcel_id, envinfo); + } + } + + if (!notify.isUndefined()) + { + LLNotificationsUtil::add("WLRegionApplyFail", notify); + //LLEnvManagerNew::instance().onRegionSettingsApplyResponse(false); + } +} + +void LLEnvironment::coroUpdateEnvironment(S32 parcel_id, LLSettingsDay::ptr_t pday, S32 day_length, S32 day_offset, LLEnvironment::environment_apply_fn apply) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("ResetEnvironment", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + + std::string url = gAgent.getRegionCapability("ExtEnvironment"); + if (url.empty()) + return; + + LLSD body(LLSD::emptyMap()); + body["environment"] = LLSD::emptyMap(); + + if (day_length >= 0) + body["environment"]["day_length"] = day_length; + if (day_offset >= 0) + body["environment"]["day_offset"] = day_offset; + if (pday) + body["environment"]["day_cycle"] = pday->getSettings(); + + LL_WARNS("LAPRAS") << "Body = " << body << LL_ENDL; + + if (parcel_id != INVALID_PARCEL_ID) + { + std::stringstream query; + + query << "?parcelid=" << parcel_id; + url += query.str(); + } + + LLSD result = httpAdapter->putAndSuspend(httpRequest, url, body); + // results that come back may contain the new settings + + LLSD notify; + + LLSD httpResults = result["http_result"]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + LL_WARNS("LAPRAS") << "success=" << result["success"] << LL_ENDL; + if ((!status) || !result["success"].asBoolean()) + { + LL_WARNS("WindlightCaps") << "Couldn't update Windlight settings for " << ((parcel_id == INVALID_PARCEL_ID) ? ("region!") : ("parcel!")) << LL_ENDL; + + notify = LLSD::emptyMap(); + notify["FAIL_REASON"] = result["message"].asString(); + } + else + { + LLSD environment = result["environment"]; + if (environment.isDefined() && apply) + { + EnvironmentInfo::ptr_t envinfo = LLEnvironment::EnvironmentInfo::extract(environment); + apply(parcel_id, envinfo); + } + } + + if (!notify.isUndefined()) + { + LLNotificationsUtil::add("WLRegionApplyFail", notify); + //LLEnvManagerNew::instance().onRegionSettingsApplyResponse(false); + } +} + +void LLEnvironment::coroResetEnvironment(S32 parcel_id, environment_apply_fn apply) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("ResetEnvironment", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + + std::string url = gAgent.getRegionCapability("ExtEnvironment"); + if (url.empty()) + return; + + if (parcel_id != INVALID_PARCEL_ID) + { + std::stringstream query; + + query << "?parcelid=" << parcel_id; + url += query.str(); + } + + LLSD result = httpAdapter->deleteAndSuspend(httpRequest, url); + // results that come back may contain the new settings + + LLSD notify; + + LLSD httpResults = result["http_result"]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + LL_WARNS("LAPRAS") << "success=" << result["success"] << LL_ENDL; + if ((!status) || !result["success"].asBoolean()) + { + LL_WARNS("WindlightCaps") << "Couldn't reset Windlight settings in " << ((parcel_id == INVALID_PARCEL_ID) ? ("region!") : ("parcel!")) << LL_ENDL; + + notify = LLSD::emptyMap(); + notify["FAIL_REASON"] = result["message"].asString(); + } + else + { + LLSD environment = result["environment"]; + if (environment.isDefined() && apply) + { + EnvironmentInfo::ptr_t envinfo = LLEnvironment::EnvironmentInfo::extract(environment); + apply(parcel_id, envinfo); + } + } + + if (!notify.isUndefined()) + { + LLNotificationsUtil::add("WLRegionApplyFail", notify); + //LLEnvManagerNew::instance().onRegionSettingsApplyResponse(false); + } + +} + + +//========================================================================= +LLEnvironment::UserPrefs::UserPrefs(): + mUseRegionSettings(true), + mUseDayCycle(true), + mPersistEnvironment(false), + mWaterPresetName(), + mSkyPresetName(), + mDayCycleName() +{} + + +void LLEnvironment::UserPrefs::load() +{ + mPersistEnvironment = gSavedSettings.getBOOL("EnvironmentPersistAcrossLogin"); + + mWaterPresetName = gSavedSettings.getString("WaterPresetName"); + mSkyPresetName = gSavedSettings.getString("SkyPresetName"); + mDayCycleName = gSavedSettings.getString("DayCycleName"); + + mUseRegionSettings = mPersistEnvironment ? gSavedSettings.getBOOL("UseEnvironmentFromRegion") : true; + mUseDayCycle = mPersistEnvironment ? gSavedSettings.getBOOL("UseDayCycle") : true; +} + +void LLEnvironment::UserPrefs::store() +{ + gSavedSettings.setBOOL("EnvironmentPersistAcrossLogin", mPersistEnvironment); + if (mPersistEnvironment) + { + gSavedSettings.setString("WaterPresetName", getWaterPresetName()); + gSavedSettings.setString("SkyPresetName", getSkyPresetName()); + gSavedSettings.setString("DayCycleName", getDayCycleName()); + + gSavedSettings.setBOOL("UseEnvironmentFromRegion", getUseRegionSettings()); + gSavedSettings.setBOOL("UseDayCycle", getUseDayCycle()); + } +} + +LLEnvironment::EnvironmentInfo::EnvironmentInfo(): + mParcelId(INVALID_PARCEL_ID), + mRegionId(), + mDayLength(0), + mDayOffset(0), + mDayHash(0), + mDaycycleData(), + mAltitudes({ { 0.0, 0.0, 0.0, 0.0 } }), + mIsDefault(false), + mIsRegion(false) +{ +} + +LLEnvironment::EnvironmentInfo::ptr_t LLEnvironment::EnvironmentInfo::extract(LLSD environment) +{ + ptr_t pinfo = std::make_shared<EnvironmentInfo>(); + + if (environment.has("parcel_id")) + pinfo->mParcelId = environment["parcel_id"].asInteger(); + if (environment.has("region_id")) + pinfo->mRegionId = environment["region_id"].asUUID(); + if (environment.has("day_length")) + pinfo->mDayLength = S64Seconds(environment["day_length"].asInteger()); + if (environment.has("day_offset")) + pinfo->mDayOffset = S64Seconds(environment["day_offset"].asInteger()); + if (environment.has("day_hash")) + pinfo->mDayHash = environment["day_hash"].asInteger(); + if (environment.has("day_cycle")) + pinfo->mDaycycleData = environment["day_cycle"]; + if (environment.has("is_default")) + pinfo->mIsDefault = environment["is_default"].asBoolean(); + if (environment.has("track_altitudes")) + { + LL_WARNS("LAPRAS") << "track_altitudes=" << environment["track_altitudes"] << LL_ENDL; + + /*LAPRAS: TODO: Fix the simulator message. Shouldn't be 5, just 4*/ + int idx = 1; + for (F32 &altitude : pinfo->mAltitudes) + { + altitude = environment["track_altitudes"][idx++].asReal(); + } + } + + return pinfo; +} + +//========================================================================= +// Transitional Code. +// static +std::string LLEnvironment::getSysDir(const std::string &subdir) +{ + return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight\\"+subdir, ""); +} + +// static +std::string LLEnvironment::getUserDir(const std::string &subdir) +{ + return gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "windlight\\"+subdir, ""); +} + +LLSettingsWater::ptr_t LLEnvironment::createWaterFromLegacyPreset(const std::string filename) +{ + LLSD data = legacyLoadPreset(filename); + if (!data) + return LLSettingsWater::ptr_t(); + + std::string name(gDirUtilp->getBaseFileName(LLURI::unescape(filename), true)); + LLSettingsWater::ptr_t water = LLSettingsVOWater::buildFromLegacyPreset(name, data); + + return water; +} + +LLSettingsSky::ptr_t LLEnvironment::createSkyFromLegacyPreset(const std::string filename) +{ + LLSD data = legacyLoadPreset(filename); + if (!data) + return LLSettingsSky::ptr_t(); + + std::string name(gDirUtilp->getBaseFileName(LLURI::unescape(filename), true)); + LLSettingsSky::ptr_t sky = LLSettingsVOSky::buildFromLegacyPreset(name, data); + + return sky; +} + +LLSettingsDay::ptr_t LLEnvironment::createDayCycleFromLegacyPreset(const std::string filename) +{ + // for the moment just look it up from the preloaded. + std::string name(gDirUtilp->getBaseFileName(LLURI::unescape(filename), true)); + + LLSettingsDay::ptr_t day = instance().findDayCycleByName(name); + return day; +} + + +LLSD LLEnvironment::legacyLoadPreset(const std::string& path) +{ + llifstream xml_file; + std::string name(gDirUtilp->getBaseFileName(LLURI::unescape(path), /*strip_exten = */ true)); + + xml_file.open(path.c_str()); + if (!xml_file) + { + return LLSD(); + } + + LLSD params_data; + LLPointer<LLSDParser> parser = new LLSDXMLParser(); + parser->parse(xml_file, params_data, LLSDSerialize::SIZE_UNLIMITED); + xml_file.close(); + + return params_data; +} + +void LLEnvironment::legacyLoadAllPresets() +{ + std::string dir; + std::string file; + + // System skies + { + dir = getSysDir("skies"); + LLDirIterator dir_iter(dir, "*.xml"); + while (dir_iter.next(file)) + { + std::string path = gDirUtilp->add(dir, file); + + LLSD data = legacyLoadPreset(path); + if (data) + { + std::string name(gDirUtilp->getBaseFileName(LLURI::unescape(path), true)); + + LLSettingsSky::ptr_t sky = LLSettingsVOSky::buildFromLegacyPreset(name, data); + LLEnvironment::instance().addSky(sky); + } + } + } + + // User skies + { + dir = getUserDir("skies"); + LLDirIterator dir_iter(dir, "*.xml"); + while (dir_iter.next(file)) + { + std::string path = gDirUtilp->add(dir, file); + + LLSD data = legacyLoadPreset(path); + if (data) + { + std::string name(gDirUtilp->getBaseFileName(LLURI::unescape(path), true)); + + LLSettingsSky::ptr_t sky = LLSettingsVOSky::buildFromLegacyPreset(name, data); + LLEnvironment::instance().addSky(sky); + } + } + } + + // System water + { + dir = getSysDir("water"); + LLDirIterator dir_iter(dir, "*.xml"); + while (dir_iter.next(file)) + { + std::string path = gDirUtilp->add(dir, file); + + LLSD data = legacyLoadPreset(path); + if (data) + { + std::string name(gDirUtilp->getBaseFileName(LLURI::unescape(path), true)); + + LLSettingsWater::ptr_t water = LLSettingsVOWater::buildFromLegacyPreset(name, data); + LLEnvironment::instance().addWater(water); + } + } + } + + // User water + { + dir = getUserDir("water"); + LLDirIterator dir_iter(dir, "*.xml"); + while (dir_iter.next(file)) + { + std::string path = gDirUtilp->add(dir, file); + + LLSD data = legacyLoadPreset(path); + if (data) + { + std::string name(gDirUtilp->getBaseFileName(LLURI::unescape(path), true)); + + LLSettingsWater::ptr_t water = LLSettingsVOWater::buildFromLegacyPreset(name, data); + LLEnvironment::instance().addWater(water); + } + } + } + + // System Days + { + dir = getSysDir("days"); + LLDirIterator dir_iter(dir, "*.xml"); + while (dir_iter.next(file)) + { + std::string path = gDirUtilp->add(dir, file); + + LLSD data = legacyLoadPreset(path); + if (data) + { + std::string name(gDirUtilp->getBaseFileName(LLURI::unescape(path), true)); + + LLSettingsDay::ptr_t day = LLSettingsVODay::buildFromLegacyPreset(name, data); + /*if (day->validate()) + { + LL_INFOS() << "Adding Day Cycle " << name << "." << LL_ENDL; + LLEnvironment::instance().addDayCycle(day); + } + else + { + LL_WARNS() << "Day Cycle " << name << " was not valid. Ignoring." << LL_ENDL; + }*/ + LL_INFOS() << "Adding Day Cycle " << name << "." << LL_ENDL; + LLEnvironment::instance().addDayCycle(day); +#ifdef EXPORT_PRESETS + std::string exportfile = LLURI::escape(name) + "(new).xml"; + std::string exportpath = gDirUtilp->add(getSysDir("new"), exportfile); + + LLSD settings = day->getSettings(); + + std::ofstream daycyclefile(exportpath); + LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter(); + formatter->format(settings, daycyclefile, LLSDFormatter::OPTIONS_PRETTY); + daycyclefile.close(); +#endif + } + } + } + + // User Days + { + dir = getUserDir("days"); + LLDirIterator dir_iter(dir, "*.xml"); + while (dir_iter.next(file)) + { + std::string path = gDirUtilp->add(dir, file); + + LLSD data = legacyLoadPreset(path); + if (data) + { + std::string name(gDirUtilp->getBaseFileName(LLURI::unescape(path), true)); + + LLSettingsDay::ptr_t day = LLSettingsVODay::buildFromLegacyPreset(name, data); + LLEnvironment::instance().addDayCycle(day); + } + } + } +} + +void LLEnvironment::onAgentPositionHasChanged(const LLVector3 &localpos) +{ + S32 trackno = calculateSkyTrackForAltitude(localpos.mV[VZ]); + if (trackno == mCurrentTrack) + return; + + LL_WARNS("LAPRAS") << "Wants to switch to track #" << trackno << LL_ENDL; + + mCurrentTrack = trackno; + for (S32 env = ENV_LOCAL; env < ENV_DEFAULT; ++env) + { + if (mEnvironments[env]) + mEnvironments[env]->setSkyTrack(mCurrentTrack); + } +} + +S32 LLEnvironment::calculateSkyTrackForAltitude(F64 altitude) +{ +// //*LAPRAS* temp base on region's response. +// return llmin((static_cast<S32>(altitude) / 100) + 1, (LLSettingsDay::TRACK_MAX - 1)); + + auto it = std::find_if_not(mTrackAltitudes.begin(), mTrackAltitudes.end(), [altitude](F32 test) { return altitude > test; }); + + if (it == mTrackAltitudes.begin()) + return 1; + else if (it == mTrackAltitudes.end()) + return 4; + + return std::min(std::distance(mTrackAltitudes.begin(), it), 4LL); +} + + +//========================================================================= +LLEnvironment::DayInstance::DayInstance() : + mDayCycle(), + mSky(), + mWater(), + mDayLength(LLSettingsDay::DEFAULT_DAYLENGTH), + mDayOffset(LLSettingsDay::DEFAULT_DAYOFFSET), + mBlenderSky(), + mBlenderWater(), + mInitialized(false), + mType(TYPE_INVALID), + mSkyTrack(1) +{ } + +void LLEnvironment::DayInstance::update(F64Seconds delta) +{ + if (!mInitialized) + initialize(); + + if (mBlenderSky) + mBlenderSky->update(delta.value()); + if (mBlenderWater) + mBlenderWater->update(delta.value()); + +// if (mSky) +// mSky->update(); +// if (mWater) +// mWater->update(); +} + +void LLEnvironment::DayInstance::setDay(const LLSettingsDay::ptr_t &pday, S64Seconds daylength, S64Seconds dayoffset) +{ + if (mType == TYPE_FIXED) + LL_WARNS("ENVIRONMENT") << "Fixed day instance changed to Cycled" << LL_ENDL; + mType = TYPE_CYCLED; + mInitialized = false; + + mDayCycle = pday; + mDayLength = daylength; + mDayOffset = dayoffset; + + mBlenderSky.reset(); + mBlenderWater.reset(); + + mSky = LLSettingsVOSky::buildDefaultSky(); + mWater = LLSettingsVOWater::buildDefaultWater(); + + animate(); +} + + +void LLEnvironment::DayInstance::setSky(const LLSettingsSky::ptr_t &psky) +{ + if (mType == TYPE_CYCLED) + LL_WARNS("ENVIRONMENT") << "Cycled day instance changed to FIXED" << LL_ENDL; + mType = TYPE_FIXED; + mInitialized = false; + + mSky = psky; + mBlenderSky.reset(); +} + +void LLEnvironment::DayInstance::setWater(const LLSettingsWater::ptr_t &pwater) +{ + if (mType == TYPE_CYCLED) + LL_WARNS("ENVIRONMENT") << "Cycled day instance changed to FIXED" << LL_ENDL; + mType = TYPE_FIXED; + mInitialized = false; + + mWater = pwater; + mBlenderWater.reset(); +} + +void LLEnvironment::DayInstance::initialize() +{ + mInitialized = true; + + if (!mWater) + mWater = LLSettingsVOWater::buildDefaultWater(); + if (!mSky) + mSky = LLSettingsVOSky::buildDefaultSky(); +} + +void LLEnvironment::DayInstance::clear() +{ + mType = TYPE_INVALID; + mDayCycle.reset(); + mSky.reset(); + mWater.reset(); + mDayLength = LLSettingsDay::DEFAULT_DAYLENGTH; + mDayOffset = LLSettingsDay::DEFAULT_DAYOFFSET; + mBlenderSky.reset(); + mBlenderWater.reset(); + mSkyTrack = 1; +} + +void LLEnvironment::DayInstance::setSkyTrack(S32 trackno) +{ + mSkyTrack = trackno; + if (mBlenderSky) + { + mBlenderSky->switchTrack(trackno); + } +} + + +void LLEnvironment::DayInstance::setBlenders(const LLSettingsBlender::ptr_t &skyblend, const LLSettingsBlender::ptr_t &waterblend) +{ + mBlenderSky = skyblend; + mBlenderWater = waterblend; +} + +F64 LLEnvironment::DayInstance::secondsToKeyframe(S64Seconds seconds) +{ + F64 frame = static_cast<F64>(seconds.value() % mDayLength.value()) / static_cast<F64>(mDayLength.value()); + + return llclamp(frame, 0.0, 1.0); +} + +void LLEnvironment::DayInstance::animate() +{ + F64Seconds now(LLDate::now().secondsSinceEpoch()); + + now += mDayOffset; + + if (!mDayCycle) + return; + + LLSettingsDay::CycleTrack_t &wtrack = mDayCycle->getCycleTrack(0); + + if (wtrack.empty()) + { + mWater.reset(); + mBlenderWater.reset(); + } +// else if (wtrack.size() == 1) +// { +// mWater = std::static_pointer_cast<LLSettingsWater>((*(wtrack.begin())).second); +// mBlenderWater.reset(); +// } + else + { + mWater = LLSettingsVOWater::buildDefaultWater(); + mBlenderWater = std::make_shared<LLTrackBlenderLoopingTime>(mWater, mDayCycle, 0, mDayLength, mDayOffset); + } + + // sky, initalize to track 1 + LLSettingsDay::CycleTrack_t &track = mDayCycle->getCycleTrack(1); + + if (track.empty()) + { + mSky.reset(); + mBlenderSky.reset(); + } +// else if (track.size() == 1) +// { +// mSky = std::static_pointer_cast<LLSettingsSky>((*(track.begin())).second); +// mBlenderSky.reset(); +// } + else + { + mSky = LLSettingsVOSky::buildDefaultSky(); + mBlenderSky = std::make_shared<LLTrackBlenderLoopingTime>(mSky, mDayCycle, 1, mDayLength, mDayOffset); + mBlenderSky->switchTrack(mSkyTrack); + } +} + +//------------------------------------------------------------------------- +LLEnvironment::DayTransition::DayTransition(const LLSettingsSky::ptr_t &skystart, + const LLSettingsWater::ptr_t &waterstart, LLEnvironment::DayInstance::ptr_t &end, S64Seconds time) : + DayInstance(), + mStartSky(skystart), + mStartWater(waterstart), + mNextInstance(end), + mTransitionTime(time) +{ + +} + +void LLEnvironment::DayTransition::update(F64Seconds delta) +{ + mNextInstance->update(delta); + DayInstance::update(delta); +} + +void LLEnvironment::DayTransition::animate() +{ + mNextInstance->animate(); + + mWater = mStartWater->buildClone(); + mBlenderWater = std::make_shared<LLSettingsBlenderTimeDelta>(mWater, mStartWater, mNextInstance->getWater(), mTransitionTime); + mBlenderWater->setOnFinished( + [this](LLSettingsBlender::ptr_t blender) { + mBlenderWater.reset(); + + if (!mBlenderSky && !mBlenderWater) + LLEnvironment::instance().mCurrentEnvironment = mNextInstance; + }); + + mSky = mStartSky->buildClone(); + mBlenderSky = std::make_shared<LLSettingsBlenderTimeDelta>(mSky, mStartSky, mNextInstance->getSky(), mTransitionTime); + mBlenderSky->setOnFinished( + [this](LLSettingsBlender::ptr_t blender) { + mBlenderSky.reset(); + + if (!mBlenderSky && !mBlenderWater) + LLEnvironment::instance().mCurrentEnvironment = mNextInstance; + }); +} + +//========================================================================= +LLTrackBlenderLoopingManual::LLTrackBlenderLoopingManual(const LLSettingsBase::ptr_t &target, const LLSettingsDay::ptr_t &day, S32 trackno) : + LLSettingsBlender(target, LLSettingsBase::ptr_t(), LLSettingsBase::ptr_t()), + mDay(day), + mTrackNo(trackno), + mPosition(0.0) +{ + LLSettingsDay::TrackBound_t initial = getBoundingEntries(mPosition); + + if (initial.first != mEndMarker) + { // No frames in track + mInitial = (*initial.first).second; + mFinal = (*initial.second).second; + + LLSD initSettings = mInitial->getSettings(); + mTarget->replaceSettings(initSettings); + } +} + +F64 LLTrackBlenderLoopingManual::setPosition(F64 position) +{ + mPosition = llclamp(position, 0.0, 1.0); + + LLSettingsDay::TrackBound_t bounds = getBoundingEntries(mPosition); + + if (bounds.first == mEndMarker) + { // No frames in track. + return 0.0; + } + + mInitial = (*bounds.first).second; + mFinal = (*bounds.second).second; + + F64 spanLength = getSpanLength(bounds); + + F64 spanPos = ((mPosition < (*bounds.first).first) ? (mPosition + 1.0) : mPosition) - (*bounds.first).first; + + F64 blendf = fmod(spanPos, spanLength) / spanLength; + return LLSettingsBlender::setPosition(blendf); +} + +void LLTrackBlenderLoopingManual::switchTrack(S32 trackno, F64 position) +{ + mTrackNo = trackno; + + F64 useposition = (position < 0.0) ? mPosition : position; + + setPosition(useposition); +} + +LLSettingsDay::TrackBound_t LLTrackBlenderLoopingManual::getBoundingEntries(F64 position) +{ + LLSettingsDay::CycleTrack_t &wtrack = mDay->getCycleTrack(mTrackNo); + + mEndMarker = wtrack.end(); + + LLSettingsDay::TrackBound_t bounds = get_bounding_entries(wtrack, position); + return bounds; +} + +F64 LLTrackBlenderLoopingManual::getSpanLength(const LLSettingsDay::TrackBound_t &bounds) const +{ + return get_wrapping_distance((*bounds.first).first, (*bounds.second).first); +} diff --git a/indra/newview/llenvironment.h b/indra/newview/llenvironment.h new file mode 100644 index 0000000000..32ce99ccc9 --- /dev/null +++ b/indra/newview/llenvironment.h @@ -0,0 +1,410 @@ +/** + * @file llenvmanager.h + * @brief Declaration of classes managing WindLight and water settings. + * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, 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_ENVIRONMENT_H +#define LL_ENVIRONMENT_H + +#include "llsingleton.h" +#include "llmemory.h" +#include "llsd.h" + +#include "llsettingsbase.h" +#include "llsettingssky.h" +#include "llsettingswater.h" +#include "llsettingsdaycycle.h" + +#include <boost/signals2.hpp> + +//------------------------------------------------------------------------- +class LLViewerCamera; +class LLGLSLShader; + +//------------------------------------------------------------------------- +class LLEnvironment : public LLSingleton<LLEnvironment> +{ + LLSINGLETON(LLEnvironment); + LOG_CLASS(LLEnvironment); + +public: + static const F32Seconds TRANSITION_INSTANT; + static const F32Seconds TRANSITION_FAST; + static const F32Seconds TRANSITION_DEFAULT; + static const F32Seconds TRANSITION_SLOW; + static const F32Seconds TRANSITION_ALTITUDE; + + struct EnvironmentInfo + { + EnvironmentInfo(); + + typedef std::shared_ptr<EnvironmentInfo> ptr_t; + + S32 mParcelId; + LLUUID mRegionId; + S64Seconds mDayLength; + S64Seconds mDayOffset; + size_t mDayHash; + LLSD mDaycycleData; + std::array<F32, 4> mAltitudes; + bool mIsDefault; + bool mIsRegion; + + + static ptr_t extract(LLSD); + + }; + + enum EnvSelection_t + { + ENV_EDIT = 0, + ENV_LOCAL, + ENV_PARCEL, + ENV_REGION, + ENV_DEFAULT, + ENV_END, + ENV_CURRENT = -1, + ENV_NONE = -2 + }; + + typedef boost::signals2::connection connection_t; + + class UserPrefs + { + friend class LLEnvironment; + public: + UserPrefs(); + + bool getUseRegionSettings() const { return mUseRegionSettings; } + bool getUseDayCycle() const { return mUseDayCycle; } + bool getUseFixedSky() const { return !getUseDayCycle(); } + + std::string getWaterPresetName() const { return mWaterPresetName; } + std::string getSkyPresetName() const { return mSkyPresetName; } + std::string getDayCycleName() const { return mDayCycleName; } + + void setUseRegionSettings(bool val); + void setUseWaterPreset(const std::string& name); + void setUseSkyPreset(const std::string& name); + void setUseDayCycle(const std::string& name); + + private: + void load(); + void store(); + + bool mUseRegionSettings; + bool mUseDayCycle; + bool mPersistEnvironment; + std::string mWaterPresetName; + std::string mSkyPresetName; + std::string mDayCycleName; + }; + + typedef std::pair<LLSettingsSky::ptr_t, LLSettingsWater::ptr_t> fixedEnvironment_t; + + typedef std::map<std::string, LLSettingsBase::ptr_t> namedSettingMap_t; + typedef std::pair<std::string, LLUUID> name_id_t; + typedef std::vector<name_id_t> list_name_id_t; + typedef boost::signals2::signal<void()> change_signal_t; + typedef std::function<void(S32, EnvironmentInfo::ptr_t)> environment_apply_fn; + + typedef std::array<F32, 4> altitude_list_t; + + virtual ~LLEnvironment(); + + void loadPreferences(); + void updatePreferences(); + const UserPrefs & getPreferences() const { return mUserPrefs; } + + bool canEdit() const; + bool isExtendedEnvironmentEnabled() const; + bool isInventoryEnabled() const; + + LLSettingsSky::ptr_t getCurrentSky() const { return mCurrentEnvironment->getSky(); } + LLSettingsWater::ptr_t getCurrentWater() const { return mCurrentEnvironment->getWater(); } + + void update(const LLViewerCamera * cam); + + void updateGLVariablesForSettings(LLGLSLShader *shader, const LLSettingsBase::ptr_t &psetting); + void updateShaderUniforms(LLGLSLShader *shader); + + void setSelectedEnvironment(EnvSelection_t env, F64Seconds transition = TRANSITION_DEFAULT, bool forced = false); + EnvSelection_t getSelectedEnvironment() const { return mSelectedEnvironment; } + + bool hasEnvironment(EnvSelection_t env); + void setEnvironment(EnvSelection_t env, const LLSettingsDay::ptr_t &pday, S64Seconds daylength, S64Seconds dayoffset); + void setEnvironment(EnvSelection_t env, fixedEnvironment_t fixed); + void setEnvironment(EnvSelection_t env, const LLSettingsBase::ptr_t &fixed); + void setEnvironment(EnvSelection_t env, const LLSettingsSky::ptr_t & fixed) { setEnvironment(env, fixedEnvironment_t(fixed, LLSettingsWater::ptr_t())); } + void setEnvironment(EnvSelection_t env, const LLSettingsWater::ptr_t & fixed) { setEnvironment(env, fixedEnvironment_t(LLSettingsSky::ptr_t(), fixed)); } + void setEnvironment(EnvSelection_t env, const LLSettingsSky::ptr_t & fixeds, const LLSettingsWater::ptr_t & fixedw) { setEnvironment(env, fixedEnvironment_t(fixeds, fixedw)); } + void clearEnvironment(EnvSelection_t env); + LLSettingsDay::ptr_t getEnvironmentDay(EnvSelection_t env); + S64Seconds getEnvironmentDayLength(EnvSelection_t env); + S64Seconds getEnvironmentDayOffset(EnvSelection_t env); + fixedEnvironment_t getEnvironmentFixed(EnvSelection_t env); + LLSettingsSky::ptr_t getEnvironmentFixedSky(EnvSelection_t env) { return getEnvironmentFixed(env).first; }; + LLSettingsWater::ptr_t getEnvironmentFixedWater(EnvSelection_t env) { return getEnvironmentFixed(env).second; }; + + void updateEnvironment(F64Seconds transition = TRANSITION_DEFAULT, bool forced = false); + + void addSky(const LLSettingsSky::ptr_t &sky); + void addWater(const LLSettingsWater::ptr_t &sky); + void addDayCycle(const LLSettingsDay::ptr_t &day); + + list_name_id_t getSkyList() const; + list_name_id_t getWaterList() const; + list_name_id_t getDayCycleList() const; + + LLSettingsSky::ptr_t findSkyByName(std::string name) const; + LLSettingsWater::ptr_t findWaterByName(std::string name) const; + LLSettingsDay::ptr_t findDayCycleByName(std::string name) const; + + inline LLVector2 getCloudScrollDelta() const { return mCloudScrollDelta; } + + F32 getCamHeight() const; + F32 getWaterHeight() const; + bool getIsDayTime() const; // "Day Time" is defined as the sun above the horizon. + bool getIsNightTime() const { return !getIsDayTime(); } // "Not Day Time" + + inline F32 getSceneLightStrength() const { return mSceneLightStrength; } + inline void setSceneLightStrength(F32 light_strength) { mSceneLightStrength = light_strength; } + + inline LLVector4 getLightDirection() const { return ((mCurrentEnvironment->getSky()) ? LLVector4(mCurrentEnvironment->getSky()->getLightDirection(), 0.0f) : LLVector4()); } + inline LLVector4 getClampedLightDirection() const { return LLVector4(mCurrentEnvironment->getSky()->getClampedLightDirection(), 0.0f); } + inline LLVector4 getRotatedLight() const { return mRotatedLight; } + + static LLSettingsWater::ptr_t createWaterFromLegacyPreset(const std::string filename); + static LLSettingsSky::ptr_t createSkyFromLegacyPreset(const std::string filename); + static LLSettingsDay::ptr_t createDayCycleFromLegacyPreset(const std::string filename); + + //------------------------------------------- + connection_t setSkyListChange(const change_signal_t::slot_type& cb); + connection_t setWaterListChange(const change_signal_t::slot_type& cb); + connection_t setDayCycleListChange(const change_signal_t::slot_type& cb); + + void requestRegionEnvironment(); + + void onLegacyRegionSettings(LLSD data); + + void requestRegion(); + void updateRegion(LLSettingsDay::ptr_t &pday, S32 day_length, S32 day_offset); + void resetRegion(); + void requestParcel(S32 parcel_id); + void updateParcel(S32 parcel_id, LLSettingsDay::ptr_t &pday, S32 day_length, S32 day_offset); + void resetParcel(S32 parcel_id); + + void selectAgentEnvironment(); + + S32 calculateSkyTrackForAltitude(F64 altitude); + + const altitude_list_t & getRegionAltitudes() const { return mTrackAltitudes; } + +protected: + virtual void initSingleton(); + +private: + class DayInstance + { + public: + enum InstanceType_t + { + TYPE_INVALID, + TYPE_FIXED, + TYPE_CYCLED + }; + typedef std::shared_ptr<DayInstance> ptr_t; + + DayInstance(); + virtual ~DayInstance() { }; + + virtual void update(F64Seconds); + + void setDay(const LLSettingsDay::ptr_t &pday, S64Seconds daylength, S64Seconds dayoffset); + void setSky(const LLSettingsSky::ptr_t &psky); + void setWater(const LLSettingsWater::ptr_t &pwater); + + void initialize(); + bool isInitialized(); + + void clear(); + + void setSkyTrack(S32 trackno); + + LLSettingsDay::ptr_t getDayCycle() const { return mDayCycle; } + LLSettingsSky::ptr_t getSky() const { return mSky; } + LLSettingsWater::ptr_t getWater() const { return mWater; } + S64Seconds getDayLength() const { return mDayLength; } + S64Seconds getDayOffset() const { return mDayOffset; } + S32 getSkyTrack() const { return mSkyTrack; } + + virtual void animate(); + + void setBlenders(const LLSettingsBlender::ptr_t &skyblend, const LLSettingsBlender::ptr_t &waterblend); + + protected: + LLSettingsDay::ptr_t mDayCycle; + LLSettingsSky::ptr_t mSky; + LLSettingsWater::ptr_t mWater; + S32 mSkyTrack; + + InstanceType_t mType; + bool mInitialized; + + S64Seconds mDayLength; + S64Seconds mDayOffset; + S32 mLastTrackAltitude; + + LLSettingsBlender::ptr_t mBlenderSky; + LLSettingsBlender::ptr_t mBlenderWater; + + F64 secondsToKeyframe(S64Seconds seconds); + }; + typedef std::array<DayInstance::ptr_t, ENV_END> InstanceArray_t; + + + class DayTransition : public DayInstance + { + public: + DayTransition(const LLSettingsSky::ptr_t &skystart, const LLSettingsWater::ptr_t &waterstart, DayInstance::ptr_t &end, S64Seconds time); + virtual ~DayTransition() { }; + + virtual void update(F64Seconds); + virtual void animate(); + + protected: + LLSettingsSky::ptr_t mStartSky; + LLSettingsWater::ptr_t mStartWater; + DayInstance::ptr_t mNextInstance; + S64Seconds mTransitionTime; + }; + + static const F32 SUN_DELTA_YAW; + static const F32 NIGHTTIME_ELEVATION_COS; + + typedef std::map<LLUUID, LLSettingsBase::ptr_t> AssetSettingMap_t; + + LLVector2 mCloudScrollDelta; // cumulative cloud delta + + InstanceArray_t mEnvironments; + + EnvSelection_t mSelectedEnvironment; + DayInstance::ptr_t mCurrentEnvironment; + + LLSettingsSky::ptr_t mSelectedSky; + LLSettingsWater::ptr_t mSelectedWater; + LLSettingsDay::ptr_t mSelectedDay; + + LLSettingsBlender::ptr_t mBlenderSky; + LLSettingsBlender::ptr_t mBlenderWater; + + typedef std::vector<LLSettingsSky::ptr_t> SkyList_t; + typedef std::vector<LLSettingsWater::ptr_t> WaterList_t; + typedef std::vector<LLSettingsDay::ptr_t> DayList_t; + + namedSettingMap_t mSkysByName; + AssetSettingMap_t mSkysById; + + namedSettingMap_t mWaterByName; + AssetSettingMap_t mWaterById; + + namedSettingMap_t mDayCycleByName; + AssetSettingMap_t mDayCycleById; + + F32 mSceneLightStrength; + LLVector4 mRotatedLight; + + UserPrefs mUserPrefs; + + change_signal_t mSkyListChange; + change_signal_t mWaterListChange; + change_signal_t mDayCycleListChange; + + S32 mCurrentTrack; + altitude_list_t mTrackAltitudes; + + DayInstance::ptr_t getEnvironmentInstance(EnvSelection_t env, bool create = false); + + DayInstance::ptr_t getSelectedEnvironmentInstance(); + + + //void addSky(const LLUUID &id, const LLSettingsSky::ptr_t &sky); + void removeSky(const std::string &name); + //void removeSky(const LLUUID &id); + void clearAllSkys(); + + //void addWater(const LLUUID &id, const LLSettingsSky::ptr_t &sky); + void removeWater(const std::string &name); + //void removeWater(const LLUUID &id); + void clearAllWater(); + + //void addDayCycle(const LLUUID &id, const LLSettingsSky::ptr_t &sky); + void removeDayCycle(const std::string &name); + //void removeDayCycle(const LLUUID &id); + void clearAllDayCycles(); + + + void updateCloudScroll(); + + void onParcelChange(); + + void coroRequestEnvironment(S32 parcel_id, environment_apply_fn apply); + void coroUpdateEnvironment(S32 parcel_id, LLSettingsDay::ptr_t pday, S32 day_length, S32 day_offset, environment_apply_fn apply); + void coroResetEnvironment(S32 parcel_id, environment_apply_fn apply); + + void recordEnvironment(S32 parcel_id, EnvironmentInfo::ptr_t environment); + + void onAgentPositionHasChanged(const LLVector3 &localpos); + //========================================================================= + void legacyLoadAllPresets(); + static LLSD legacyLoadPreset(const std::string& path); + static std::string getSysDir(const std::string &subdir); + static std::string getUserDir(const std::string &subdir); + +}; + +class LLTrackBlenderLoopingManual : public LLSettingsBlender +{ +public: + LLTrackBlenderLoopingManual(const LLSettingsBase::ptr_t &target, const LLSettingsDay::ptr_t &day, S32 trackno); + + F64 setPosition(F64 position) override; + virtual void switchTrack(S32 trackno, F64 position) override; + S32 getTrack() const { return mTrackNo; } + + typedef std::shared_ptr<LLTrackBlenderLoopingManual> ptr_t; +protected: + LLSettingsDay::TrackBound_t getBoundingEntries(F64 position); + F64 getSpanLength(const LLSettingsDay::TrackBound_t &bounds) const; + +private: + LLSettingsDay::ptr_t mDay; + S32 mTrackNo; + F64 mPosition; + + LLSettingsDay::CycleTrack_t::iterator mEndMarker; +}; + +#endif // LL_ENVIRONMENT_H + diff --git a/indra/newview/llenvmanager.cpp b/indra/newview/llenvmanager.cpp deleted file mode 100644 index fa1c3b983e..0000000000 --- a/indra/newview/llenvmanager.cpp +++ /dev/null @@ -1,721 +0,0 @@ -/** - * @file llenvmanager.cpp - * @brief Implementation of classes managing WindLight and water settings. - * - * $LicenseInfo:firstyear=2009&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2011, 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 "llenvmanager.h" - -#include "llagent.h" -#include "lldaycyclemanager.h" -#include "llviewercontrol.h" // for gSavedSettings -#include "llviewerregion.h" -#include "llwaterparammanager.h" -#include "llwlhandlers.h" -#include "llwlparammanager.h" -#include "lltrans.h" - -std::string LLWLParamKey::toString() const -{ - switch (scope) - { - case SCOPE_LOCAL: - return name + std::string(" (") + LLTrans::getString("Local") + std::string(")"); - break; - case SCOPE_REGION: - return name + std::string(" (") + LLTrans::getString("Region") + std::string(")"); - break; - default: - return name + " (?)"; - } -} - -std::string LLEnvPrefs::getWaterPresetName() const -{ - if (mWaterPresetName.empty()) - { - LL_WARNS() << "Water preset name is empty" << LL_ENDL; - } - - return mWaterPresetName; -} - -std::string LLEnvPrefs::getSkyPresetName() const -{ - if (mSkyPresetName.empty()) - { - LL_WARNS() << "Sky preset name is empty" << LL_ENDL; - } - - return mSkyPresetName; -} - -std::string LLEnvPrefs::getDayCycleName() const -{ - if (mDayCycleName.empty()) - { - LL_WARNS() << "Day cycle name is empty" << LL_ENDL; - } - - return mDayCycleName; -} - -void LLEnvPrefs::setUseRegionSettings(bool val) -{ - mUseRegionSettings = val; -} - -void LLEnvPrefs::setUseWaterPreset(const std::string& name) -{ - mUseRegionSettings = false; - mWaterPresetName = name; -} - -void LLEnvPrefs::setUseSkyPreset(const std::string& name) -{ - mUseRegionSettings = false; - mUseDayCycle = false; - mSkyPresetName = name; -} - -void LLEnvPrefs::setUseDayCycle(const std::string& name) -{ - mUseRegionSettings = false; - mUseDayCycle = true; - mDayCycleName = name; -} - -//============================================================================= -LLEnvManagerNew::LLEnvManagerNew(): - mInterpNextChangeMessage(true), - mCurRegionUUID(LLUUID::null), - mLastReceivedID(LLUUID::null) -{ - - // Set default environment settings. - mUserPrefs.mUseRegionSettings = true; - mUserPrefs.mUseDayCycle = true; - mUserPrefs.mWaterPresetName = "Default"; - mUserPrefs.mSkyPresetName = "Default"; - mUserPrefs.mDayCycleName = "Default"; - - LL_DEBUGS("Windlight")<<LL_ENDL; - gAgent.addRegionChangedCallback(boost::bind(&LLEnvManagerNew::onRegionChange, this)); -} - -bool LLEnvManagerNew::getUseRegionSettings() const -{ - return mUserPrefs.getUseRegionSettings(); -} - -bool LLEnvManagerNew::getUseDayCycle() const -{ - return mUserPrefs.getUseDayCycle(); -} - -bool LLEnvManagerNew::getUseFixedSky() const -{ - return mUserPrefs.getUseFixedSky(); -} - -std::string LLEnvManagerNew::getWaterPresetName() const -{ - return mUserPrefs.getWaterPresetName(); -} - -std::string LLEnvManagerNew::getSkyPresetName() const -{ - return mUserPrefs.getSkyPresetName(); -} - -std::string LLEnvManagerNew::getDayCycleName() const -{ - return mUserPrefs.getDayCycleName(); -} - -const LLEnvironmentSettings& LLEnvManagerNew::getRegionSettings() const -{ - return !mNewRegionPrefs.isEmpty() ? mNewRegionPrefs : mCachedRegionPrefs; -} - -void LLEnvManagerNew::setRegionSettings(const LLEnvironmentSettings& new_settings) -{ - // Set region settings override that will be used locally - // until user either uploads the changes or goes to another region. - mNewRegionPrefs = new_settings; -} - -bool LLEnvManagerNew::usePrefs() -{ - LL_DEBUGS("Windlight") << "Displaying preferred environment" << LL_ENDL; - updateManagersFromPrefs(false); - return true; -} - -bool LLEnvManagerNew::useDefaults() -{ - bool rslt; - - rslt = useDefaultWater(); - rslt &= useDefaultSky(); - - return rslt; -} - -bool LLEnvManagerNew::useRegionSettings() -{ - bool rslt; - - rslt = useRegionSky(); - rslt &= useRegionWater(); - - return rslt; -} - -bool LLEnvManagerNew::useWaterPreset(const std::string& name) -{ - LL_DEBUGS("Windlight") << "Displaying water preset " << name << LL_ENDL; - LLWaterParamManager& water_mgr = LLWaterParamManager::instance(); - bool rslt = water_mgr.getParamSet(name, water_mgr.mCurParams); - llassert(rslt == true); - return rslt; -} - -bool LLEnvManagerNew::useWaterParams(const LLSD& params) -{ - LL_DEBUGS("Windlight") << "Displaying water params" << LL_ENDL; - LLWaterParamManager::instance().mCurParams.setAll(params); - return true; -} - -bool LLEnvManagerNew::useSkyPreset(const std::string& name) -{ - LLWLParamManager& sky_mgr = LLWLParamManager::instance(); - LLWLParamSet param_set; - - if (!sky_mgr.getParamSet(LLWLParamKey(name, LLEnvKey::SCOPE_LOCAL), param_set)) - { - LL_WARNS() << "No sky preset named " << name << LL_ENDL; - return false; - } - - LL_DEBUGS("Windlight") << "Displaying sky preset " << name << LL_ENDL; - sky_mgr.applySkyParams(param_set.getAll()); - return true; -} - -bool LLEnvManagerNew::useSkyParams(const LLSD& params) -{ - LL_DEBUGS("Windlight") << "Displaying sky params" << LL_ENDL; - LLWLParamManager::instance().applySkyParams(params); - return true; -} - -bool LLEnvManagerNew::useDayCycle(const std::string& name, LLEnvKey::EScope scope) -{ - LLSD params; - - if (scope == LLEnvKey::SCOPE_REGION) - { - LL_DEBUGS("Windlight") << "Displaying region day cycle " << name << LL_ENDL; - params = getRegionSettings().getWLDayCycle(); - } - else - { - LL_DEBUGS("Windlight") << "Displaying local day cycle " << name << LL_ENDL; - - if (!LLDayCycleManager::instance().getPreset(name, params)) - { - LL_WARNS() << "No day cycle named " << name << LL_ENDL; - return false; - } - } - - bool rslt = LLWLParamManager::instance().applyDayCycleParams(params, scope); - llassert(rslt == true); - return rslt; -} - -bool LLEnvManagerNew::useDayCycleParams(const LLSD& params, LLEnvKey::EScope scope, F32 time /* = 0.5*/) -{ - LL_DEBUGS("Windlight") << "Displaying day cycle params" << LL_ENDL; - return LLWLParamManager::instance().applyDayCycleParams(params, scope); -} - -void LLEnvManagerNew::setUseRegionSettings(bool val) -{ - mUserPrefs.setUseRegionSettings(val); - saveUserPrefs(); - updateManagersFromPrefs(false); -} - -void LLEnvManagerNew::setUseWaterPreset(const std::string& name) -{ - // *TODO: make sure the preset exists. - if (name.empty()) - { - LL_WARNS() << "Empty water preset name passed" << LL_ENDL; - return; - } - - mUserPrefs.setUseWaterPreset(name); - saveUserPrefs(); - updateManagersFromPrefs(false); -} - -void LLEnvManagerNew::setUseSkyPreset(const std::string& name) -{ - // *TODO: make sure the preset exists. - if (name.empty()) - { - LL_WARNS() << "Empty sky preset name passed" << LL_ENDL; - return; - } - - mUserPrefs.setUseSkyPreset(name); - saveUserPrefs(); - updateManagersFromPrefs(false); -} - -void LLEnvManagerNew::setUseDayCycle(const std::string& name) -{ - if (!LLDayCycleManager::instance().presetExists(name)) - { - LL_WARNS() << "Invalid day cycle name passed" << LL_ENDL; - return; - } - - mUserPrefs.setUseDayCycle(name); - saveUserPrefs(); - updateManagersFromPrefs(false); -} - -void LLEnvManagerNew::loadUserPrefs() -{ - // operate on members directly to avoid side effects - mUserPrefs.mWaterPresetName = gSavedSettings.getString("WaterPresetName"); - mUserPrefs.mSkyPresetName = gSavedSettings.getString("SkyPresetName"); - mUserPrefs.mDayCycleName = gSavedSettings.getString("DayCycleName"); - - bool use_region_settings = gSavedSettings.getBOOL("EnvironmentPersistAcrossLogin") ? gSavedSettings.getBOOL("UseEnvironmentFromRegion") : true; - mUserPrefs.mUseRegionSettings = use_region_settings; - mUserPrefs.mUseDayCycle = gSavedSettings.getBOOL("UseDayCycle"); - - if (mUserPrefs.mUseRegionSettings) - { - requestRegionSettings(); - } -} - -void LLEnvManagerNew::saveUserPrefs() -{ - gSavedSettings.setString("WaterPresetName", getWaterPresetName()); - gSavedSettings.setString("SkyPresetName", getSkyPresetName()); - gSavedSettings.setString("DayCycleName", getDayCycleName()); - - gSavedSettings.setBOOL("UseEnvironmentFromRegion", getUseRegionSettings()); - gSavedSettings.setBOOL("UseDayCycle", getUseDayCycle()); - - mUsePrefsChangeSignal(); -} - -void LLEnvManagerNew::setUserPrefs( - const std::string& water_preset, - const std::string& sky_preset, - const std::string& day_cycle_preset, - bool use_fixed_sky, - bool use_region_settings) -{ - // operate on members directly to avoid side effects - mUserPrefs.mWaterPresetName = water_preset; - mUserPrefs.mSkyPresetName = sky_preset; - mUserPrefs.mDayCycleName = day_cycle_preset; - - mUserPrefs.mUseRegionSettings = use_region_settings; - mUserPrefs.mUseDayCycle = !use_fixed_sky; - - saveUserPrefs(); - updateManagersFromPrefs(false); -} - -void LLEnvManagerNew::dumpUserPrefs() -{ - LL_DEBUGS("Windlight") << "WaterPresetName: " << gSavedSettings.getString("WaterPresetName") << LL_ENDL; - LL_DEBUGS("Windlight") << "SkyPresetName: " << gSavedSettings.getString("SkyPresetName") << LL_ENDL; - LL_DEBUGS("Windlight") << "DayCycleName: " << gSavedSettings.getString("DayCycleName") << LL_ENDL; - - LL_DEBUGS("Windlight") << "UseEnvironmentFromRegion: " << gSavedSettings.getBOOL("UseEnvironmentFromRegion") << LL_ENDL; - LL_DEBUGS("Windlight") << "UseDayCycle: " << gSavedSettings.getBOOL("UseDayCycle") << LL_ENDL; -} - -void LLEnvManagerNew::dumpPresets() -{ - const LLEnvironmentSettings& region_settings = getRegionSettings(); - std::string region_name = gAgent.getRegion() ? gAgent.getRegion()->getName() : "Unknown region"; - - // Dump water presets. - LL_DEBUGS("Windlight") << "Waters:" << LL_ENDL; - if (region_settings.getWaterParams().size() != 0) - { - LL_DEBUGS("Windlight") << " - " << region_name << LL_ENDL; - } - LLWaterParamManager::preset_name_list_t water_presets; - LLWaterParamManager::instance().getPresetNames(water_presets); - for (LLWaterParamManager::preset_name_list_t::const_iterator it = water_presets.begin(); it != water_presets.end(); ++it) - { - LL_DEBUGS("Windlight") << " - " << *it << LL_ENDL; - } - - // Dump sky presets. - LL_DEBUGS("Windlight") << "Skies:" << LL_ENDL; - LLWLParamManager::preset_key_list_t sky_preset_keys; - LLWLParamManager::instance().getPresetKeys(sky_preset_keys); - for (LLWLParamManager::preset_key_list_t::const_iterator it = sky_preset_keys.begin(); it != sky_preset_keys.end(); ++it) - { - std::string preset_name = it->name; - std::string item_title; - - if (it->scope == LLEnvKey::SCOPE_LOCAL) // local preset - { - item_title = preset_name; - } - else // region preset - { - item_title = preset_name + " (" + region_name + ")"; - } - LL_DEBUGS("Windlight") << " - " << item_title << LL_ENDL; - } - - // Dump day cycles. - LL_DEBUGS("Windlight") << "Days:" << LL_ENDL; - const LLSD& cur_region_dc = region_settings.getWLDayCycle(); - if (cur_region_dc.size() != 0) - { - LL_DEBUGS("Windlight") << " - " << region_name << LL_ENDL; - } - LLDayCycleManager::preset_name_list_t days; - LLDayCycleManager::instance().getPresetNames(days); - for (LLDayCycleManager::preset_name_list_t::const_iterator it = days.begin(); it != days.end(); ++it) - { - LL_DEBUGS("Windlight") << " - " << *it << LL_ENDL; - } -} - -void LLEnvManagerNew::requestRegionSettings() -{ - LL_DEBUGS("Windlight") << LL_ENDL; - LLEnvironmentRequest::initiate(); -} - -bool LLEnvManagerNew::sendRegionSettings(const LLEnvironmentSettings& new_settings) -{ - LLSD metadata; - - metadata["regionID"] = gAgent.getRegion()->getRegionID(); - // add last received update ID to outbound message so simulator can handle concurrent updates - metadata["messageID"] = mLastReceivedID; - - return LLEnvironmentApply::initiateRequest(new_settings.makePacket(metadata)); -} - -boost::signals2::connection LLEnvManagerNew::setPreferencesChangeCallback(const prefs_change_signal_t::slot_type& cb) -{ - return mUsePrefsChangeSignal.connect(cb); -} - -boost::signals2::connection LLEnvManagerNew::setRegionSettingsChangeCallback(const region_settings_change_signal_t::slot_type& cb) -{ - return mRegionSettingsChangeSignal.connect(cb); -} - -boost::signals2::connection LLEnvManagerNew::setRegionSettingsAppliedCallback(const region_settings_applied_signal_t::slot_type& cb) -{ - return mRegionSettingsAppliedSignal.connect(cb); -} - -// static -bool LLEnvManagerNew::canEditRegionSettings() -{ - LLViewerRegion* region = gAgent.getRegion(); - BOOL owner_or_god = gAgent.isGodlike() || (region && region->getOwner() == gAgent.getID()); - BOOL owner_or_god_or_manager = owner_or_god || (region && region->isEstateManager()); - - LL_DEBUGS("Windlight") << "Can edit region settings: " << (bool) owner_or_god_or_manager << LL_ENDL; - return owner_or_god_or_manager; -} - -// static -const std::string LLEnvManagerNew::getScopeString(LLEnvKey::EScope scope) -{ - switch(scope) - { - case LLEnvKey::SCOPE_LOCAL: - return LLTrans::getString("LocalSettings"); - case LLEnvKey::SCOPE_REGION: - return LLTrans::getString("RegionSettings"); - default: - return " (?)"; - } -} - -void LLEnvManagerNew::onRegionSettingsResponse(const LLSD& content) -{ - // If the message was valid, grab the UUID from it and save it for next outbound update message. - mLastReceivedID = content[0]["messageID"].asUUID(); - - // Refresh cached region settings. - LL_DEBUGS("Windlight") << "Received region environment settings: " << content << LL_ENDL; - F32 sun_hour = 0; // *TODO - LLEnvironmentSettings new_settings(content[1], content[2], content[3], sun_hour); - mCachedRegionPrefs = new_settings; - - // Load region sky presets. - LLWLParamManager::instance().refreshRegionPresets(getRegionSettings().getSkyMap()); - - // If using server settings, update managers. - if (getUseRegionSettings()) - { - updateManagersFromPrefs(mInterpNextChangeMessage); - } - - // Let interested parties know about the region settings update. - mRegionSettingsChangeSignal(); - - // reset - mInterpNextChangeMessage = false; -} - -void LLEnvManagerNew::onRegionSettingsApplyResponse(bool ok) -{ - LL_DEBUGS("Windlight") << "Applying region settings " << (ok ? "succeeded" : "failed") << LL_ENDL; - - // Clear locally modified region settings because they have just been uploaded. - mNewRegionPrefs.clear(); - - mRegionSettingsAppliedSignal(ok); -} - -//-- private methods ---------------------------------------------------------- - -// virtual -void LLEnvManagerNew::initSingleton() -{ - LL_DEBUGS("Windlight") << "Initializing LLEnvManagerNew" << LL_ENDL; - - loadUserPrefs(); - - // preferences loaded, can set params - std::string preferred_day = getDayCycleName(); - if (!useDayCycle(preferred_day, LLEnvKey::SCOPE_LOCAL)) - { - LL_WARNS() << "No day cycle named " << preferred_day << ", reverting LLWLParamManager to defaults" << LL_ENDL; - LLWLParamManager::instance().setDefaultDay(); - } - - std::string sky = getSkyPresetName(); - if (!useSkyPreset(sky)) - { - LL_WARNS() << "No sky preset named " << sky << ", falling back to defaults" << LL_ENDL; - LLWLParamManager::instance().setDefaultSky(); - - // *TODO: Fix user preferences accordingly. - } - - LLWLParamManager::instance().resetAnimator(0.5 /*noon*/, getUseDayCycle()); -} - -void LLEnvManagerNew::updateSkyFromPrefs() -{ - bool success = true; - - // Sync sky with user prefs. - if (getUseRegionSettings()) // apply region-wide settings - { - success = useRegionSky(); - } - else // apply user-specified settings - { - if (getUseDayCycle()) - { - success = useDayCycle(getDayCycleName(), LLEnvKey::SCOPE_LOCAL); - } - else - { - success = useSkyPreset(getSkyPresetName()); - } - } - - // If something went wrong, fall back to defaults. - if (!success) - { - // *TODO: fix user prefs - useDefaultSky(); - } -} - -void LLEnvManagerNew::updateWaterFromPrefs(bool interpolate) -{ - LLWaterParamManager& water_mgr = LLWaterParamManager::instance(); - LLSD target_water_params; - - // Determine new water settings based on user prefs. - - { - // Fall back to default water. - LLWaterParamSet default_water; - water_mgr.getParamSet("Default", default_water); - target_water_params = default_water.getAll(); - } - - if (getUseRegionSettings()) - { - // *TODO: make sure whether region settings belong to the current region? - const LLSD& region_water_params = getRegionSettings().getWaterParams(); - if (region_water_params.size() != 0) // region has no water settings - { - LL_DEBUGS("Windlight") << "Applying region water" << LL_ENDL; - target_water_params = region_water_params; - } - else - { - LL_DEBUGS("Windlight") << "Applying default water" << LL_ENDL; - } - } - else - { - std::string water = getWaterPresetName(); - LL_DEBUGS("Windlight") << "Applying water preset [" << water << "]" << LL_ENDL; - LLWaterParamSet params; - if (!water_mgr.getParamSet(water, params)) - { - LL_WARNS() << "No water preset named " << water << ", falling back to defaults" << LL_ENDL; - water_mgr.getParamSet("Default", params); - - // *TODO: Fix user preferences accordingly. - } - target_water_params = params.getAll(); - } - - // Sync water with user prefs. - water_mgr.applyParams(target_water_params, interpolate); -} - -void LLEnvManagerNew::updateManagersFromPrefs(bool interpolate) -{ - LL_DEBUGS("Windlight")<<LL_ENDL; - // Apply water settings. - updateWaterFromPrefs(interpolate); - - // Apply sky settings. - updateSkyFromPrefs(); -} - -bool LLEnvManagerNew::useRegionSky() -{ - const LLEnvironmentSettings& region_settings = getRegionSettings(); - - // If region is set to defaults, - if (region_settings.getSkyMap().size() == 0) - { - // well... apply the default sky settings. - useDefaultSky(); - return true; - } - - // Otherwise apply region day cycle/skies. - LL_DEBUGS("Windlight") << "Applying region sky" << LL_ENDL; - - // *TODO: Support fixed sky from region. Just do sky reset for now. - if (region_settings.getSkyMap().size() == 1) - { - // Region is set to fixed sky. Reset. - useSkyParams(region_settings.getSkyMap().beginMap()->second); - } - return useDayCycleParams( - region_settings.getWLDayCycle(), - LLEnvKey::SCOPE_REGION, - region_settings.getDayTime()); -} - -bool LLEnvManagerNew::useRegionWater() -{ - const LLEnvironmentSettings& region_settings = getRegionSettings(); - const LLSD& region_water = region_settings.getWaterParams(); - - // If region is set to defaults, - if (region_water.size() == 0) - { - // well... apply the default water settings. - return useDefaultWater(); - } - - // Otherwise apply region water. - LL_DEBUGS("Windlight") << "Applying region sky" << LL_ENDL; - return useWaterParams(region_water); -} - -bool LLEnvManagerNew::useDefaultSky() -{ - return useDayCycle("Default", LLEnvKey::SCOPE_LOCAL); -} - -bool LLEnvManagerNew::useDefaultWater() -{ - return useWaterPreset("Default"); -} - - -void LLEnvManagerNew::onRegionChange() -{ - // Avoid duplicating region setting requests - // by checking whether the region is actually changing. - LLViewerRegion* regionp = gAgent.getRegion(); - LLUUID region_uuid = regionp ? regionp->getRegionID() : LLUUID::null; - if (region_uuid != mCurRegionUUID) - { - // Clear locally modified region settings. - mNewRegionPrefs.clear(); - - // *TODO: clear environment settings of the previous region? - - // Request environment settings of the new region. - mCurRegionUUID = region_uuid; - // for region crossings, interpolate the change; for teleports, don't - mInterpNextChangeMessage = (gAgent.getTeleportState() == LLAgent::TELEPORT_NONE); - LL_DEBUGS("Windlight") << (mInterpNextChangeMessage ? "Crossed" : "Teleported") - << " to new region: " << region_uuid - << LL_ENDL; - requestRegionSettings(); - } - else - { - LL_DEBUGS("Windlight") << "disregarding region change; interp: " - << (mInterpNextChangeMessage ? "true" : "false") - << " regionp: " << regionp - << " old: " << mCurRegionUUID - << " new: " << region_uuid - << LL_ENDL; - } -} diff --git a/indra/newview/llenvmanager.h b/indra/newview/llenvmanager.h deleted file mode 100644 index 54bbf85e86..0000000000 --- a/indra/newview/llenvmanager.h +++ /dev/null @@ -1,349 +0,0 @@ -/** - * @file llenvmanager.h - * @brief Declaration of classes managing WindLight and water settings. - * - * $LicenseInfo:firstyear=2009&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2011, 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_LLENVMANAGER_H -#define LL_LLENVMANAGER_H - -#include "llmemory.h" -#include "llsd.h" - -class LLWLParamManager; -class LLWaterParamManager; -class LLWLAnimator; - -// generic key -struct LLEnvKey -{ -public: - // Note: enum ordering is important; for example, a region-level floater (1) will see local and region (all values that are <=) - typedef enum e_scope - { - SCOPE_LOCAL, // 0 - SCOPE_REGION//, // 1 - // SCOPE_ESTATE, // 2 - // etc. - } EScope; -}; - -struct LLWLParamKey : LLEnvKey -{ -public: - // scope and source of a param set (WL sky preset) - std::string name; - EScope scope; - - // for conversion from LLSD - static const int NAME_IDX = 0; - static const int SCOPE_IDX = 1; - - inline LLWLParamKey(const std::string& n, EScope s) - : name(n), scope(s) - { - } - - inline LLWLParamKey(LLSD llsd) - : name(llsd[NAME_IDX].asString()), scope(EScope(llsd[SCOPE_IDX].asInteger())) - { - } - - inline LLWLParamKey() // NOT really valid, just so std::maps can return a default of some sort - : name(""), scope(SCOPE_LOCAL) - { - } - - inline LLWLParamKey(std::string& stringVal) - { - size_t len = stringVal.length(); - if (len > 0) - { - name = stringVal.substr(0, len - 1); - scope = (EScope) atoi(stringVal.substr(len - 1, len).c_str()); - } - } - - inline std::string toStringVal() const - { - std::stringstream str; - str << name << scope; - return str.str(); - } - - inline LLSD toLLSD() const - { - LLSD llsd = LLSD::emptyArray(); - llsd.append(LLSD(name)); - llsd.append(LLSD(scope)); - return llsd; - } - - inline void fromLLSD(const LLSD& llsd) - { - name = llsd[NAME_IDX].asString(); - scope = EScope(llsd[SCOPE_IDX].asInteger()); - } - - inline bool operator <(const LLWLParamKey other) const - { - if (name < other.name) - { - return true; - } - else if (name > other.name) - { - return false; - } - else - { - return scope < other.scope; - } - } - - inline bool operator ==(const LLWLParamKey other) const - { - return (name == other.name) && (scope == other.scope); - } - - std::string toString() const; -}; - -class LLEnvironmentSettings -{ -public: - LLEnvironmentSettings() : - mWLDayCycle(LLSD::emptyMap()), - mSkyMap(LLSD::emptyMap()), - mWaterParams(LLSD::emptyMap()), - mDayTime(0.f) - {} - LLEnvironmentSettings(const LLSD& dayCycle, const LLSD& skyMap, const LLSD& waterParams, F64 dayTime) : - mWLDayCycle(dayCycle), - mSkyMap(skyMap), - mWaterParams(waterParams), - mDayTime(dayTime) - {} - ~LLEnvironmentSettings() {} - - void saveParams(const LLSD& dayCycle, const LLSD& skyMap, const LLSD& waterParams, F64 dayTime) - { - mWLDayCycle = dayCycle; - mSkyMap = skyMap; - mWaterParams = waterParams; - mDayTime = dayTime; - } - - const LLSD& getWLDayCycle() const - { - return mWLDayCycle; - } - - const LLSD& getWaterParams() const - { - return mWaterParams; - } - - const LLSD& getSkyMap() const - { - return mSkyMap; - } - - F64 getDayTime() const - { - return mDayTime; - } - - bool isEmpty() const - { - return mWLDayCycle.size() == 0; - } - - void clear() - { - *this = LLEnvironmentSettings(); - } - - LLSD makePacket(const LLSD& metadata) const - { - LLSD full_packet = LLSD::emptyArray(); - - // 0: metadata - full_packet.append(metadata); - - // 1: day cycle - full_packet.append(mWLDayCycle); - - // 2: map of sky setting names to sky settings (as LLSD) - full_packet.append(mSkyMap); - - // 3: water params - full_packet.append(mWaterParams); - - return full_packet; - } - -private: - LLSD mWLDayCycle, mWaterParams, mSkyMap; - F64 mDayTime; -}; - -/** - * User environment preferences. - */ -class LLEnvPrefs -{ -public: - LLEnvPrefs() : mUseRegionSettings(true), mUseDayCycle(true) {} - - bool getUseRegionSettings() const { return mUseRegionSettings; } - bool getUseDayCycle() const { return mUseDayCycle; } - bool getUseFixedSky() const { return !getUseDayCycle(); } - - std::string getWaterPresetName() const; - std::string getSkyPresetName() const; - std::string getDayCycleName() const; - - void setUseRegionSettings(bool val); - void setUseWaterPreset(const std::string& name); - void setUseSkyPreset(const std::string& name); - void setUseDayCycle(const std::string& name); - - bool mUseRegionSettings; - bool mUseDayCycle; - std::string mWaterPresetName; - std::string mSkyPresetName; - std::string mDayCycleName; -}; - -/** - * Setting: - * 1. Use region settings. - * 2. Use my setting: <water preset> + <fixed_sky>|<day_cycle> - */ -class LLEnvManagerNew : public LLSingleton<LLEnvManagerNew> -{ - LLSINGLETON(LLEnvManagerNew); - LOG_CLASS(LLEnvManagerNew); -public: - typedef boost::signals2::signal<void()> prefs_change_signal_t; - typedef boost::signals2::signal<void()> region_settings_change_signal_t; - typedef boost::signals2::signal<void(bool)> region_settings_applied_signal_t; - - // getters to access user env. preferences - bool getUseRegionSettings() const; - bool getUseDayCycle() const; - bool getUseFixedSky() const; - std::string getWaterPresetName() const; - std::string getSkyPresetName() const; - std::string getDayCycleName() const; - - /// @return cached env. settings of the current region. - const LLEnvironmentSettings& getRegionSettings() const; - - /** - * Set new region settings without uploading them to the region. - * - * The override will be reset when the changes are applied to the region (=uploaded) - * or user teleports to another region. - */ - void setRegionSettings(const LLEnvironmentSettings& new_settings); - - // Change environment w/o changing user preferences. - bool usePrefs(); - bool useDefaults(); - bool useRegionSettings(); - bool useWaterPreset(const std::string& name); - bool useWaterParams(const LLSD& params); - bool useSkyPreset(const std::string& name); - bool useSkyParams(const LLSD& params); - bool useDayCycle(const std::string& name, LLEnvKey::EScope scope); - bool useDayCycleParams(const LLSD& params, LLEnvKey::EScope scope, F32 time = 0.5); - - // setters for user env. preferences - void setUseRegionSettings(bool val); - void setUseWaterPreset(const std::string& name); - void setUseSkyPreset(const std::string& name); - void setUseDayCycle(const std::string& name); - void setUserPrefs( - const std::string& water_preset, - const std::string& sky_preset, - const std::string& day_cycle_preset, - bool use_fixed_sky, - bool use_region_settings); - - // debugging methods - void dumpUserPrefs(); - void dumpPresets(); - - // Misc. - void requestRegionSettings(); - bool sendRegionSettings(const LLEnvironmentSettings& new_settings); - boost::signals2::connection setPreferencesChangeCallback(const prefs_change_signal_t::slot_type& cb); - boost::signals2::connection setRegionSettingsChangeCallback(const region_settings_change_signal_t::slot_type& cb); - boost::signals2::connection setRegionSettingsAppliedCallback(const region_settings_applied_signal_t::slot_type& cb); - - static bool canEditRegionSettings(); /// @return true if we have access to editing region environment - static const std::string getScopeString(LLEnvKey::EScope scope); - - // Public callbacks. - void onRegionSettingsResponse(const LLSD& content); - void onRegionSettingsApplyResponse(bool ok); - -private: - /*virtual*/ void initSingleton(); - - void loadUserPrefs(); - void saveUserPrefs(); - - void updateSkyFromPrefs(); - void updateWaterFromPrefs(bool interpolate); - void updateManagersFromPrefs(bool interpolate); - - bool useRegionSky(); - bool useRegionWater(); - - bool useDefaultSky(); - bool useDefaultWater(); - - void onRegionChange(); - - /// Emitted when user environment preferences change. - prefs_change_signal_t mUsePrefsChangeSignal; - - /// Emitted when region environment settings update comes. - region_settings_change_signal_t mRegionSettingsChangeSignal; - - /// Emitted when agent region changes. Move to LLAgent? - region_settings_applied_signal_t mRegionSettingsAppliedSignal; - - LLEnvPrefs mUserPrefs; /// User environment preferences. - LLEnvironmentSettings mCachedRegionPrefs; /// Cached region environment settings. - LLEnvironmentSettings mNewRegionPrefs; /// Not-yet-uploaded modified region env. settings. - bool mInterpNextChangeMessage; /// Interpolate env. settings on next region change. - LLUUID mCurRegionUUID; /// To avoid duplicated region env. settings requests. - LLUUID mLastReceivedID; /// Id of last received region env. settings. -}; - -#endif // LL_LLENVMANAGER_H - diff --git a/indra/newview/llfloaterbuy.cpp b/indra/newview/llfloaterbuy.cpp index 5a9cdbba44..4d3ebcda1e 100644 --- a/indra/newview/llfloaterbuy.cpp +++ b/indra/newview/llfloaterbuy.cpp @@ -241,7 +241,7 @@ void LLFloaterBuy::inventoryChanged(LLViewerObject* obj, BOOL item_is_multi = FALSE; if (( inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_LANDMARK_VISITED || inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS) - && !(inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK)) + && !(inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_SUBTYPE_MASK)) { item_is_multi = TRUE; } diff --git a/indra/newview/llfloaterbuycontents.cpp b/indra/newview/llfloaterbuycontents.cpp index 4607b4ac41..440ec06c4e 100644 --- a/indra/newview/llfloaterbuycontents.cpp +++ b/indra/newview/llfloaterbuycontents.cpp @@ -216,7 +216,7 @@ void LLFloaterBuyContents::inventoryChanged(LLViewerObject* obj, BOOL item_is_multi = FALSE; if ((inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_LANDMARK_VISITED || inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS) - && !(inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK)) + && !(inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_SUBTYPE_MASK)) { item_is_multi = TRUE; } diff --git a/indra/newview/llfloaterdeleteenvpreset.cpp b/indra/newview/llfloaterdeleteenvpreset.cpp deleted file mode 100644 index bb11c813b4..0000000000 --- a/indra/newview/llfloaterdeleteenvpreset.cpp +++ /dev/null @@ -1,285 +0,0 @@ -/** - * @file llfloaterdeleteenvpreset.cpp - * @brief Floater to delete a water / sky / day cycle preset. - * - * $LicenseInfo:firstyear=2011&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2011, 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 "llfloaterdeleteenvpreset.h" - -// libs -#include "llbutton.h" -#include "llcombobox.h" -#include "llnotificationsutil.h" - -// newview -#include "lldaycyclemanager.h" -#include "llwaterparammanager.h" - -static bool confirmation_callback(const LLSD& notification, const LLSD& response, boost::function<void()> cb) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (option == 0) - { - cb(); - } - return false; - -} - -LLFloaterDeleteEnvPreset::LLFloaterDeleteEnvPreset(const LLSD &key) -: LLFloater(key) -, mPresetCombo(NULL) -{ -} - -// virtual -BOOL LLFloaterDeleteEnvPreset::postBuild() -{ - mPresetCombo = getChild<LLComboBox>("preset_combo"); - mPresetCombo->setCommitCallback(boost::bind(&LLFloaterDeleteEnvPreset::postPopulate, this)); - - getChild<LLButton>("delete")->setCommitCallback(boost::bind(&LLFloaterDeleteEnvPreset::onBtnDelete, this)); - getChild<LLButton>("cancel")->setCommitCallback(boost::bind(&LLFloaterDeleteEnvPreset::onBtnCancel, this)); - - // Listen to user preferences change, in which case we need to rebuild the presets list - // to disable the [new] current preset. - LLEnvManagerNew::instance().setPreferencesChangeCallback(boost::bind(&LLFloaterDeleteEnvPreset::populatePresetsList, this)); - - // Listen to presets addition/removal. - LLDayCycleManager::instance().setModifyCallback(boost::bind(&LLFloaterDeleteEnvPreset::populateDayCyclesList, this)); - LLWLParamManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterDeleteEnvPreset::populateSkyPresetsList, this)); - LLWaterParamManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterDeleteEnvPreset::populateWaterPresetsList, this)); - - return TRUE; -} - -// virtual -void LLFloaterDeleteEnvPreset::onOpen(const LLSD& key) -{ - std::string param = key.asString(); - std::string floater_title = getString(std::string("title_") + param); - std::string combo_label = getString(std::string("label_" + param)); - - // Update floater title. - setTitle(floater_title); - - // Update the combobox label. - getChild<LLUICtrl>("label")->setValue(combo_label); - - // Populate the combobox. - populatePresetsList(); -} - -void LLFloaterDeleteEnvPreset::onBtnDelete() -{ - std::string param = mKey.asString(); - std::string preset_name = mPresetCombo->getValue().asString(); - boost::function<void()> confirm_cb; - - if (param == "water") - { - // Don't allow deleting system presets. - if (LLWaterParamManager::instance().isSystemPreset(preset_name)) - { - LLNotificationsUtil::add("WLNoEditDefault"); - return; - } - - confirm_cb = boost::bind(&LLFloaterDeleteEnvPreset::onDeleteWaterPresetConfirmation, this); - } - else if (param == "sky") - { - // Don't allow deleting presets referenced by local day cycles. - if (LLDayCycleManager::instance().isSkyPresetReferenced(preset_name)) - { - LLNotificationsUtil::add("GenericAlert", LLSD().with("MESSAGE", getString("msg_sky_is_referenced"))); - return; - } - - LLWLParamManager& wl_mgr = LLWLParamManager::instance(); - - // Don't allow deleting system presets. - if (wl_mgr.isSystemPreset(preset_name)) - { - LLNotificationsUtil::add("WLNoEditDefault"); - return; - } - - confirm_cb = boost::bind(&LLFloaterDeleteEnvPreset::onDeleteSkyPresetConfirmation, this); - } - else if (param == "day_cycle") - { - LLDayCycleManager& day_mgr = LLDayCycleManager::instance(); - - // Don't allow deleting system presets. - if (day_mgr.isSystemPreset(preset_name)) - { - LLNotificationsUtil::add("WLNoEditDefault"); - return; - } - - confirm_cb = boost::bind(&LLFloaterDeleteEnvPreset::onDeleteDayCycleConfirmation, this); - } - else - { - LL_WARNS() << "Unrecognized key" << LL_ENDL; - } - - LLSD args; - args["MESSAGE"] = getString("msg_confirm_deletion"); - LLNotificationsUtil::add("GenericAlertYesCancel", args, LLSD(), - boost::bind(&confirmation_callback, _1, _2, confirm_cb)); -} - -void LLFloaterDeleteEnvPreset::onBtnCancel() -{ - closeFloater(); -} - -void LLFloaterDeleteEnvPreset::populatePresetsList() -{ - std::string param = mKey.asString(); - - if (param == "water") - { - populateWaterPresetsList(); - } - else if (param == "sky") - { - populateSkyPresetsList(); - } - else if (param == "day_cycle") - { - populateDayCyclesList(); - } - else - { - LL_WARNS() << "Unrecognized key" << LL_ENDL; - } -} - -void LLFloaterDeleteEnvPreset::populateWaterPresetsList() -{ - if (mKey.asString() != "water") return; - - mPresetCombo->removeall(); - - std::string cur_preset; - LLEnvManagerNew& env_mgr = LLEnvManagerNew::instance(); - if (!env_mgr.getUseRegionSettings()) - { - cur_preset = env_mgr.getWaterPresetName(); - } - - LLWaterParamManager::preset_name_list_t presets; - LLWaterParamManager::instance().getUserPresetNames(presets); // list only user presets - for (LLWaterParamManager::preset_name_list_t::const_iterator it = presets.begin(); it != presets.end(); ++it) - { - std::string name = *it; - - bool enabled = (name != cur_preset); // don't allow deleting current preset - mPresetCombo->add(name, ADD_BOTTOM, enabled); - } - - postPopulate(); -} - -void LLFloaterDeleteEnvPreset::populateSkyPresetsList() -{ - if (mKey.asString() != "sky") return; - - mPresetCombo->removeall(); - - std::string cur_preset; - LLEnvManagerNew& env_mgr = LLEnvManagerNew::instance(); - if (!env_mgr.getUseRegionSettings() && env_mgr.getUseFixedSky()) - { - cur_preset = env_mgr.getSkyPresetName(); - } - - LLWLParamManager::preset_name_list_t user_presets; - LLWLParamManager::instance().getUserPresetNames(user_presets); - for (LLWLParamManager::preset_name_list_t::const_iterator it = user_presets.begin(); it != user_presets.end(); ++it) - { - const std::string& name = *it; - mPresetCombo->add(name, ADD_BOTTOM, /*enabled = */ name != cur_preset); - } - - postPopulate(); -} - -void LLFloaterDeleteEnvPreset::populateDayCyclesList() -{ - if (mKey.asString() != "day_cycle") return; - - mPresetCombo->removeall(); - - std::string cur_day; - LLEnvManagerNew& env_mgr = LLEnvManagerNew::instance(); - if (!env_mgr.getUseRegionSettings() && env_mgr.getUseDayCycle()) - { - cur_day = env_mgr.getDayCycleName(); - } - - LLDayCycleManager& day_mgr = LLDayCycleManager::instance(); - LLDayCycleManager::preset_name_list_t user_days; - day_mgr.getUserPresetNames(user_days); // list only user presets - for (LLDayCycleManager::preset_name_list_t::const_iterator it = user_days.begin(); it != user_days.end(); ++it) - { - const std::string& name = *it; - mPresetCombo->add(name, ADD_BOTTOM, name != cur_day); - } - - postPopulate(); -} - -void LLFloaterDeleteEnvPreset::postPopulate() -{ - // Handle empty list and empty selection. - bool has_selection = mPresetCombo->getItemCount() > 0 && mPresetCombo->getSelectedValue().isDefined(); - - if (!has_selection) - { - mPresetCombo->setLabel(getString("combo_label")); - } - - getChild<LLButton>("delete")->setEnabled(has_selection); -} - -void LLFloaterDeleteEnvPreset::onDeleteDayCycleConfirmation() -{ - LLDayCycleManager::instance().deletePreset(mPresetCombo->getValue().asString()); -} - -void LLFloaterDeleteEnvPreset::onDeleteSkyPresetConfirmation() -{ - LLWLParamKey key(mPresetCombo->getValue().asString(), LLEnvKey::SCOPE_LOCAL); - LLWLParamManager::instance().removeParamSet(key, true); -} - -void LLFloaterDeleteEnvPreset::onDeleteWaterPresetConfirmation() -{ - LLWaterParamManager::instance().removeParamSet(mPresetCombo->getValue().asString(), true); -} diff --git a/indra/newview/llfloaterdeleteenvpreset.h b/indra/newview/llfloaterdeleteenvpreset.h deleted file mode 100644 index 1211505273..0000000000 --- a/indra/newview/llfloaterdeleteenvpreset.h +++ /dev/null @@ -1,62 +0,0 @@ -/** - * @file llfloaterdeleteenvpreset.h - * @brief Floater to delete a water / sky / day cycle preset. - * - * $LicenseInfo:firstyear=2011&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2011, 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_LLFLOATERDELETEENVPRESET_H -#define LL_LLFLOATERDELETEENVPRESET_H - -#include "llfloater.h" - -class LLComboBox; - -class LLFloaterDeleteEnvPreset : public LLFloater -{ - LOG_CLASS(LLFloaterDeleteEnvPreset); - -public: - LLFloaterDeleteEnvPreset(const LLSD &key); - - /*virtual*/ BOOL postBuild(); - /*virtual*/ void onOpen(const LLSD& key); - - void onBtnDelete(); - void onBtnCancel(); - -private: - void populatePresetsList(); - void populateWaterPresetsList(); - void populateSkyPresetsList(); - void populateDayCyclesList(); - - void postPopulate(); - - void onDeleteDayCycleConfirmation(); - void onDeleteSkyPresetConfirmation(); - void onDeleteWaterPresetConfirmation(); - - LLComboBox* mPresetCombo; -}; - -#endif // LL_LLFLOATERDELETEENVPRESET_H diff --git a/indra/newview/llfloatereditdaycycle.cpp b/indra/newview/llfloatereditdaycycle.cpp index 5c0991b0b3..4ddedbf7df 100644 --- a/indra/newview/llfloatereditdaycycle.cpp +++ b/indra/newview/llfloatereditdaycycle.cpp @@ -41,11 +41,11 @@ // newview #include "llagent.h" -#include "lldaycyclemanager.h" -#include "llenvmanager.h" #include "llregioninfomodel.h" #include "llviewerregion.h" -#include "llwlparammanager.h" + +#include "llenvironment.h" +#include "lltrans.h" const F32 LLFloaterEditDayCycle::sHoursPerDay = 24.0f; @@ -114,7 +114,8 @@ void LLFloaterEditDayCycle::onClose(bool app_quitting) { if (!app_quitting) // there's no point to change environment if we're quitting { - LLEnvManagerNew::instance().usePrefs(); // revert changes made to current day cycle + LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_EDIT); + LLEnvironment::instance().updateEnvironment(); } } @@ -127,6 +128,7 @@ void LLFloaterEditDayCycle::draw() void LLFloaterEditDayCycle::initCallbacks(void) { +#if 0 mDayCycleNameEditor->setKeystrokeCallback(boost::bind(&LLFloaterEditDayCycle::onDayCycleNameEdited, this), NULL); mDayCyclesCombo->setCommitCallback(boost::bind(&LLFloaterEditDayCycle::onDayCycleSelected, this)); mDayCyclesCombo->setTextEntryCallback(boost::bind(&LLFloaterEditDayCycle::onDayCycleNameEdited, this)); @@ -147,51 +149,55 @@ void LLFloaterEditDayCycle::initCallbacks(void) env_mgr.setRegionSettingsChangeCallback(boost::bind(&LLFloaterEditDayCycle::onRegionSettingsChange, this)); gAgent.addRegionChangedCallback(boost::bind(&LLFloaterEditDayCycle::onRegionChange, this)); env_mgr.setRegionSettingsAppliedCallback(boost::bind(&LLFloaterEditDayCycle::onRegionSettingsApplied, this, _1)); - // Connect to day cycle manager events. LLDayCycleManager::instance().setModifyCallback(boost::bind(&LLFloaterEditDayCycle::onDayCycleListChange, this)); // Connect to sky preset list changes. LLWLParamManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterEditDayCycle::onSkyPresetListChange, this)); + // Connect to region info updates. LLRegionInfoModel::instance().setUpdateCallback(boost::bind(&LLFloaterEditDayCycle::onRegionInfoUpdate, this)); +#endif } void LLFloaterEditDayCycle::syncTimeSlider() { +#if 0 // set time mTimeSlider->setCurSliderValue((F32)LLWLParamManager::getInstance()->mAnimator.getDayTime() * sHoursPerDay); +#endif } void LLFloaterEditDayCycle::loadTrack() { - // clear the slider - mKeysSlider->clear(); - mSliderToKey.clear(); - - // add sliders - - LL_DEBUGS() << "Adding " << LLWLParamManager::getInstance()->mDay.mTimeMap.size() << " keys to slider" << LL_ENDL; - - LLWLDayCycle& cur_dayp = LLWLParamManager::instance().mDay; - for (std::map<F32, LLWLParamKey>::iterator it = cur_dayp.mTimeMap.begin(); it != cur_dayp.mTimeMap.end(); ++it) - { - addSliderKey(it->first * sHoursPerDay, it->second); - } - - // set drop-down menu to match preset of currently-selected keyframe (one is automatically selected initially) - const std::string& cur_sldr = mKeysSlider->getCurSlider(); - if (strlen(cur_sldr.c_str()) > 0) // only do this if there is a curSldr, otherwise we put an invalid entry into the map - { - mSkyPresetsCombo->selectByValue(mSliderToKey[cur_sldr].keyframe.toStringVal()); - } - - syncTimeSlider(); +// // clear the slider +// mKeysSlider->clear(); +// mSliderToKey.clear(); +// +// // add sliders +// +// LL_DEBUGS() << "Adding " << LLWLParamManager::getInstance()->mDay.mTimeMap.size() << " keys to slider" << LL_ENDL; +// +// LLWLDayCycle& cur_dayp = LLWLParamManager::instance().mDay; +// for (std::map<F32, LLWLParamKey>::iterator it = cur_dayp.mTimeMap.begin(); it != cur_dayp.mTimeMap.end(); ++it) +// { +// addSliderKey(it->first * sHoursPerDay, it->second); +// } +// +// // set drop-down menu to match preset of currently-selected keyframe (one is automatically selected initially) +// const std::string& cur_sldr = mKeysSlider->getCurSlider(); +// if (strlen(cur_sldr.c_str()) > 0) // only do this if there is a curSldr, otherwise we put an invalid entry into the map +// { +// mSkyPresetsCombo->selectByValue(mSliderToKey[cur_sldr].keyframe.toStringVal()); +// } +// +// syncTimeSlider(); } void LLFloaterEditDayCycle::applyTrack() { +#if 0 LL_DEBUGS() << "Applying track (" << mSliderToKey.size() << ")" << LL_ENDL; // if no keys, do nothing @@ -220,10 +226,12 @@ void LLFloaterEditDayCycle::applyTrack() LLWLParamManager::getInstance()->mAnimator.update( LLWLParamManager::getInstance()->mCurParams); +#endif } void LLFloaterEditDayCycle::refreshSkyPresetsList() { +#if 0 // Don't allow selecting region skies for a local day cycle, // because thus we may end up with invalid day cycle. bool include_region_skies = getSelectedDayCycle().scope == LLEnvKey::SCOPE_REGION; @@ -269,10 +277,12 @@ void LLFloaterEditDayCycle::refreshSkyPresetsList() // set defaults on combo boxes mSkyPresetsCombo->selectFirstItem(); +#endif } void LLFloaterEditDayCycle::refreshDayCyclesList() { +#if 0 llassert(isNewDay() == false); mDayCyclesCombo->removeall(); @@ -308,10 +318,12 @@ void LLFloaterEditDayCycle::refreshDayCyclesList() } mDayCyclesCombo->setLabel(getString("combo_label")); +#endif } void LLFloaterEditDayCycle::onTimeSliderMoved() { +#if 0 /// get the slider value F32 val = mTimeSlider->getCurSliderValue() / sHoursPerDay; @@ -322,10 +334,12 @@ void LLFloaterEditDayCycle::onTimeSliderMoved() // then call update once LLWLParamManager::getInstance()->mAnimator.update( LLWLParamManager::getInstance()->mCurParams); +#endif } void LLFloaterEditDayCycle::onKeyTimeMoved() { +#if 0 if (mKeysSlider->getValue().size() == 0) { return; @@ -351,10 +365,12 @@ void LLFloaterEditDayCycle::onKeyTimeMoved() mTimeCtrl->setTime24(time24); applyTrack(); +#endif } void LLFloaterEditDayCycle::onKeyTimeChanged() { +#if 0 // if no keys, skipped if (mSliderToKey.size() == 0) { @@ -372,10 +388,12 @@ void LLFloaterEditDayCycle::onKeyTimeChanged() mSliderToKey[cur_sldr].time = time; applyTrack(); +#endif } void LLFloaterEditDayCycle::onKeyPresetChanged() { +#if 0 // do nothing if no sliders if (mKeysSlider->getValue().size() == 0) { @@ -399,10 +417,12 @@ void LLFloaterEditDayCycle::onKeyPresetChanged() // Apply changes to current day cycle. applyTrack(); +#endif } void LLFloaterEditDayCycle::onAddKey() { +#if 0 llassert_always(mSliderToKey.size() == mKeysSlider->getValue().size()); S32 max_sliders; @@ -420,6 +440,7 @@ void LLFloaterEditDayCycle::onAddKey() break; } +#if 0 if ((S32)mSliderToKey.size() >= max_sliders) { LLSD args; @@ -428,6 +449,7 @@ void LLFloaterEditDayCycle::onAddKey() LLNotificationsUtil::add("DayCycleTooManyKeyframes", args, LLSD(), LLNotificationFunctorRegistry::instance().DONOTHING); return; } +#endif // add the slider key std::string key_val = mSkyPresetsCombo->getSelectedValue().asString(); @@ -439,8 +461,10 @@ void LLFloaterEditDayCycle::onAddKey() // apply the change to current day cycles applyTrack(); +#endif } +#if 0 void LLFloaterEditDayCycle::addSliderKey(F32 time, LLWLParamKey keyframe) { // make a slider @@ -460,7 +484,9 @@ void LLFloaterEditDayCycle::addSliderKey(F32 time, LLWLParamKey keyframe) llassert_always(mSliderToKey.size() == mKeysSlider->getValue().size()); } +#endif +#if 0 LLWLParamKey LLFloaterEditDayCycle::getSelectedDayCycle() { LLWLParamKey dc_key; @@ -487,6 +513,7 @@ LLWLParamKey LLFloaterEditDayCycle::getSelectedDayCycle() return dc_key; } +#endif bool LLFloaterEditDayCycle::isNewDay() const { @@ -495,6 +522,7 @@ bool LLFloaterEditDayCycle::isNewDay() const void LLFloaterEditDayCycle::dumpTrack() { +#if 0 LL_DEBUGS("Windlight") << "Dumping day cycle" << LL_ENDL; LLWLDayCycle& cur_dayp = LLWLParamManager::instance().mDay; @@ -505,6 +533,7 @@ void LLFloaterEditDayCycle::dumpTrack() S32 m = (S32) ((time - h) * 60.0f); LL_DEBUGS("Windlight") << llformat("(%.3f) %02d:%02d", time, h, m) << " => " << it->second.name << LL_ENDL; } +#endif } void LLFloaterEditDayCycle::enableEditing(bool enable) @@ -518,6 +547,7 @@ void LLFloaterEditDayCycle::enableEditing(bool enable) void LLFloaterEditDayCycle::reset() { +#if 0 // clear the slider mKeysSlider->clear(); mSliderToKey.clear(); @@ -543,10 +573,12 @@ void LLFloaterEditDayCycle::reset() // Disable controls until a day cycle to edit is selected. enableEditing(false); } +#endif } void LLFloaterEditDayCycle::saveRegionDayCycle() { +#if 0 LLEnvManagerNew& env_mgr = LLEnvManagerNew::instance(); LLWLDayCycle& cur_dayp = LLWLParamManager::instance().mDay; // the day cycle being edited @@ -570,6 +602,7 @@ void LLFloaterEditDayCycle::saveRegionDayCycle() setApplyProgress(true); #endif +#endif } void LLFloaterEditDayCycle::setApplyProgress(bool started) @@ -595,6 +628,7 @@ bool LLFloaterEditDayCycle::getApplyProgress() const void LLFloaterEditDayCycle::onDeleteKey() { +#if 0 if (mSliderToKey.size() == 0) { return; @@ -624,10 +658,12 @@ void LLFloaterEditDayCycle::onDeleteKey() mTimeCtrl->setTime24(time24); applyTrack(); +#endif } void LLFloaterEditDayCycle::onRegionSettingsChange() { +#if 0 LL_DEBUGS("Windlight") << "Region settings changed" << LL_ENDL; if (getApplyProgress()) // our region settings have being applied @@ -643,10 +679,12 @@ void LLFloaterEditDayCycle::onRegionSettingsChange() closeFloater(); } +#endif } void LLFloaterEditDayCycle::onRegionChange() { +#if 0 LL_DEBUGS("Windlight") << "Region changed" << LL_ENDL; // If we're editing the region day cycle @@ -654,6 +692,7 @@ void LLFloaterEditDayCycle::onRegionChange() { reset(); // undoes all unsaved changes } +#endif } void LLFloaterEditDayCycle::onRegionSettingsApplied(bool success) @@ -669,6 +708,7 @@ void LLFloaterEditDayCycle::onRegionSettingsApplied(bool success) void LLFloaterEditDayCycle::onRegionInfoUpdate() { +#if 0 LL_DEBUGS("Windlight") << "Region info updated" << LL_ENDL; bool can_edit = true; @@ -680,17 +720,22 @@ void LLFloaterEditDayCycle::onRegionInfoUpdate() } enableEditing(can_edit); +#endif } void LLFloaterEditDayCycle::onDayCycleNameEdited() { +#if 0 // Disable saving a day cycle having empty name. LLWLParamKey key = getSelectedDayCycle(); mSaveButton->setEnabled(!key.name.empty()); +#endif } void LLFloaterEditDayCycle::onDayCycleSelected() { +#if 0 + LLSD day_data; LLWLParamKey dc_key = getSelectedDayCycle(); bool can_edit = true; @@ -722,12 +767,13 @@ void LLFloaterEditDayCycle::onDayCycleSelected() F32 slider_time = mTimeSlider->getCurSliderValue() / sHoursPerDay; LLWLParamManager::instance().applyDayCycleParams(day_data, dc_key.scope, slider_time); loadTrack(); - - enableEditing(can_edit); +#endif + enableEditing(false); } void LLFloaterEditDayCycle::onBtnSave() { +#if 0 LLDayCycleManager& day_mgr = LLDayCycleManager::instance(); LLWLParamKey selected_day = getSelectedDayCycle(); @@ -763,6 +809,7 @@ void LLFloaterEditDayCycle::onBtnSave() // new preset, hence no confirmation needed onSaveConfirmed(); } +#endif } void LLFloaterEditDayCycle::onBtnCancel() @@ -785,6 +832,7 @@ bool LLFloaterEditDayCycle::onSaveAnswer(const LLSD& notification, const LLSD& r void LLFloaterEditDayCycle::onSaveConfirmed() { +#if 0 std::string name = getSelectedDayCycle().name; // Save preset. @@ -798,7 +846,7 @@ void LLFloaterEditDayCycle::onSaveConfirmed() LL_DEBUGS("Windlight") << name << " is now the new preferred day cycle" << LL_ENDL; LLEnvManagerNew::instance().setUseDayCycle(name); } - +#endif closeFloater(); } diff --git a/indra/newview/llfloatereditdaycycle.h b/indra/newview/llfloatereditdaycycle.h index e6e4fe39c1..50d60a2b56 100644 --- a/indra/newview/llfloatereditdaycycle.h +++ b/indra/newview/llfloatereditdaycycle.h @@ -29,8 +29,6 @@ #include "llfloater.h" -#include "llwlparammanager.h" // for LLWLParamKey - class LLCheckBoxCtrl; class LLComboBox; class LLLineEditor; @@ -70,10 +68,10 @@ private: void refreshDayCyclesList(); /// add a slider to the track - void addSliderKey(F32 time, LLWLParamKey keyframe); +// void addSliderKey(F32 time, LLWLParamKey keyframe); void initCallbacks(); - LLWLParamKey getSelectedDayCycle(); +// LLWLParamKey getSelectedDayCycle(); bool isNewDay() const; void dumpTrack(); void enableEditing(bool enable); @@ -109,15 +107,15 @@ private: static std::string getRegionName(); /// convenience class for holding keyframes mapped to sliders - struct SliderKey - { - public: - SliderKey(LLWLParamKey kf, F32 t) : keyframe(kf), time(t) {} - SliderKey() : keyframe(), time(0.f) {} // Don't use this default constructor - - LLWLParamKey keyframe; - F32 time; - }; +// struct SliderKey +// { +// public: +// SliderKey(LLWLParamKey kf, F32 t) : keyframe(kf), time(t) {} +// SliderKey() : keyframe(), time(0.f) {} // Don't use this default constructor +// +// LLWLParamKey keyframe; +// F32 time; +// }; static const F32 sHoursPerDay; @@ -131,7 +129,7 @@ private: LLButton* mSaveButton; // map of sliders to parameters - std::map<std::string, SliderKey> mSliderToKey; +// std::map<std::string, SliderKey> mSliderToKey; }; #endif // LL_LLFLOATEREDITDAYCYCLE_H diff --git a/indra/newview/llfloatereditextdaycycle.cpp b/indra/newview/llfloatereditextdaycycle.cpp new file mode 100644 index 0000000000..706dd99fc9 --- /dev/null +++ b/indra/newview/llfloatereditextdaycycle.cpp @@ -0,0 +1,1080 @@ +/** + * @file llfloatereditextdaycycle.cpp + * @brief Floater to create or edit a day cycle + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, 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 "llfloatereditextdaycycle.h" + +// libs +#include "llbutton.h" +#include "llcallbacklist.h" +#include "llcheckboxctrl.h" +#include "llcombobox.h" +#include "llloadingindicator.h" +#include "llmultisliderctrl.h" +#include "llnotifications.h" +#include "llnotificationsutil.h" +#include "llspinctrl.h" +#include "lltimectrl.h" +#include "lltabcontainer.h" +#include "llfilepicker.h" + +#include "llsettingsvo.h" +#include "llinventorymodel.h" +#include "llviewerparcelmgr.h" + +// newview +#include "llagent.h" +#include "llparcel.h" +#include "llflyoutcombobtn.h" //Todo: make a proper UI element/button/panel instead +#include "llregioninfomodel.h" +#include "llviewerregion.h" +#include "llpaneleditwater.h" +#include "llpaneleditsky.h" + +#include "llenvironment.h" +#include "lltrans.h" + +//========================================================================= +namespace { + const std::string track_tabs[] = { + "water_track", + "sky1_track", + "sky2_track", + "sky3_track", + "sky4_track", + }; + + // For flyout + const std::string XML_FLYOUTMENU_FILE("menu_save_settings.xml"); + // From menu_save_settings.xml, consider moving into flyout since it should be supported by flyout either way + const std::string ACTION_SAVE("save_settings"); + const std::string ACTION_SAVEAS("save_as_new_settings"); + const std::string ACTION_APPLY_LOCAL("apply_local"); + const std::string ACTION_APPLY_PARCEL("apply_parcel"); + const std::string ACTION_APPLY_REGION("apply_region"); + + const F32 DAY_CYCLE_PLAY_TIME_SECONDS = 60; + + const F32 FRAME_SLOP_FACTOR = 0.025f; +} + +//========================================================================= +const std::string LLFloaterEditExtDayCycle::KEY_INVENTORY_ID("inventory_id"); +const std::string LLFloaterEditExtDayCycle::KEY_LIVE_ENVIRONMENT("live_environment"); +const std::string LLFloaterEditExtDayCycle::KEY_DAY_LENGTH("day_length"); + +//========================================================================= +LLFloaterEditExtDayCycle::LLFloaterEditExtDayCycle(const LLSD &key) : + LLFloater(key), + mFlyoutControl(NULL), + mCancelButton(NULL), + mDayLength(0), + mCurrentTrack(4), + mTimeSlider(NULL), + mFramesSlider(NULL), + mCurrentTimeLabel(NULL), + mImportButton(nullptr), + mInventoryId(), + mInventoryItem(nullptr), + mSkyBlender(), + mWaterBlender(), + mScratchSky(), + mScratchWater(), + mIsPlaying(false) +{ + + mCommitCallbackRegistrar.add("DayCycle.Track", [this](LLUICtrl *ctrl, const LLSD &data) { onTrackSelectionCallback(data); }); + mCommitCallbackRegistrar.add("DayCycle.PlayActions", [this](LLUICtrl *ctrl, const LLSD &data) { onPlayActionCallback(data); }); + + mScratchSky = LLSettingsVOSky::buildDefaultSky(); + mScratchWater = LLSettingsVOWater::buildDefaultWater(); +} + +LLFloaterEditExtDayCycle::~LLFloaterEditExtDayCycle() +{ + // Todo: consider remaking mFlyoutControl into full view class that initializes intself with floater, + // complete with postbuild, e t c... + delete mFlyoutControl; +} + +// virtual +BOOL LLFloaterEditExtDayCycle::postBuild() +{ + getChild<LLLineEditor>("day_cycle_name")->setKeystrokeCallback(boost::bind(&LLFloaterEditExtDayCycle::onCommitName, this, _1, _2), NULL); + + mCancelButton = getChild<LLButton>("cancel_btn", true); + mAddFrameButton = getChild<LLButton>("add_frame", true); + mDeleteFrameButton = getChild<LLButton>("delete_frame", true); + mTimeSlider = getChild<LLMultiSliderCtrl>("WLTimeSlider"); + mFramesSlider = getChild<LLMultiSliderCtrl>("WLDayCycleFrames"); + mSkyTabLayoutContainer = getChild<LLView>("frame_settings_sky", true); + mWaterTabLayoutContainer = getChild<LLView>("frame_settings_water", true); + mCurrentTimeLabel = getChild<LLTextBox>("current_time", true); + mImportButton = getChild<LLButton>("btn_import", true); + + mFlyoutControl = new LLFlyoutComboBtnCtrl(this, "save_btn", "btn_flyout", XML_FLYOUTMENU_FILE); + mFlyoutControl->setAction([this](LLUICtrl *ctrl, const LLSD &data) { onButtonApply(ctrl, data); }); + + mCancelButton->setCommitCallback([this](LLUICtrl *ctrl, const LLSD &data) { onBtnCancel(); }); + mTimeSlider->setCommitCallback([this](LLUICtrl *ctrl, const LLSD &data) { onTimeSliderMoved(); }); + mAddFrameButton->setCommitCallback([this](LLUICtrl *ctrl, const LLSD &data) { onAddTrack(); }); + mDeleteFrameButton->setCommitCallback([this](LLUICtrl *ctrl, const LLSD &data) { onRemoveTrack(); }); + mImportButton->setCommitCallback([this](LLUICtrl *, const LLSD &){ onButtonImport(); }); + + mFramesSlider->setCommitCallback([this](LLUICtrl *, const LLSD &data) { onFrameSliderCallback(data); }); + mFramesSlider->setDoubleClickCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask){ onFrameSliderDoubleClick(x, y, mask); }); + mFramesSlider->setMouseDownCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask){ onFrameSliderMouseDown(x, y, mask); }); + mFramesSlider->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask){ onFrameSliderMouseUp(x, y, mask); }); + + mTimeSlider->addSlider(0); + + //getChild<LLButton>("sky1_track", true)->setToggleState(true); + + return TRUE; +} + +void LLFloaterEditExtDayCycle::onOpen(const LLSD& key) +{ + LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT); + LLEnvironment::instance().updateEnvironment(); + + mEditingEnv = LLEnvironment::ENV_NONE; + mEditDay.reset(); + if (key.has(KEY_INVENTORY_ID)) + { + loadInventoryItem(key[KEY_INVENTORY_ID].asUUID()); + } + else if (key.has(KEY_LIVE_ENVIRONMENT)) + { + LLEnvironment::EnvSelection_t env = static_cast<LLEnvironment::EnvSelection_t>(key[KEY_LIVE_ENVIRONMENT].asInteger()); + + loadLiveEnvironment(env); + } + else + { + loadLiveEnvironment(LLEnvironment::ENV_DEFAULT); + } + + mDayLength.value(0); + if (key.has(KEY_DAY_LENGTH)) + { + mDayLength.value(key[KEY_DAY_LENGTH].asReal()); + } + + // time labels + mCurrentTimeLabel->setTextArg("[PRCNT]", std::string("0")); + const S32 max_elm = 5; + if (mDayLength.value() != 0) + { + S32Hours hrs; + S32Minutes minutes; + S64Seconds total; + LLUIString formatted_label = getString("time_label"); + for (int i = 0; i < max_elm; i++) + { + total = ((mDayLength / (max_elm - 1)) * i); + hrs = total; + minutes = total - hrs; + + formatted_label.setArg("[HH]", llformat("%d", hrs.value())); + formatted_label.setArg("[MM]", llformat("%d", abs(minutes.value()))); + getChild<LLTextBox>("p" + llformat("%d", i), true)->setTextArg("[DSC]", formatted_label.getString()); + } + hrs = mDayLength; + minutes = mDayLength - hrs; + formatted_label.setArg("[HH]", llformat("%d", hrs.value())); + formatted_label.setArg("[MM]", llformat("%d", abs(minutes.value()))); + mCurrentTimeLabel->setTextArg("[DSC]", formatted_label.getString()); + } + else + { + for (int i = 0; i < max_elm; i++) + { + getChild<LLTextBox>("p" + llformat("%d", i), true)->setTextArg("[DSC]", std::string()); + } + mCurrentTimeLabel->setTextArg("[DSC]", std::string()); + } + + const LLEnvironment::altitude_list_t &altitudes = LLEnvironment::instance().getRegionAltitudes(); + + for (S32 idx = 1; idx < 4; ++idx) + { + std::stringstream label; + label << altitudes[idx] << "m"; + getChild<LLButton>(track_tabs[idx + 1], true)->setTextArg("[DSC]", label.str()); + } + +} + +void LLFloaterEditExtDayCycle::onClose(bool app_quitting) +{ + // there's no point to change environment if we're quitting + // or if we already restored environment + if (!app_quitting && LLEnvironment::instance().getSelectedEnvironment() == LLEnvironment::ENV_EDIT) + { + LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); + } + stopPlay(); +} + +void LLFloaterEditExtDayCycle::onVisibilityChange(BOOL new_visibility) +{ + if (new_visibility) + { + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, mScratchSky, mScratchWater); + LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT); + } + else + { + LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); + stopPlay(); + } +} + +void LLFloaterEditExtDayCycle::refresh() +{ + if (mEditDay) + { + LLLineEditor* name_field = getChild<LLLineEditor>("day_cycle_name"); + name_field->setText(mEditDay->getName()); + } + + bool is_inventory_avail = canUseInventory(); + + mFlyoutControl->setMenuItemEnabled(ACTION_SAVE, is_inventory_avail); + mFlyoutControl->setMenuItemEnabled(ACTION_SAVEAS, is_inventory_avail); + + + LLFloater::refresh(); +} + + +void LLFloaterEditExtDayCycle::onButtonApply(LLUICtrl *ctrl, const LLSD &data) +{ + std::string ctrl_action = ctrl->getName(); + + if (ctrl_action == ACTION_SAVE) + { + doApplyUpdateInventory(); + } + else if (ctrl_action == ACTION_SAVEAS) + { + doApplyCreateNewInventory(); + } + else if ((ctrl_action == ACTION_APPLY_LOCAL) || + (ctrl_action == ACTION_APPLY_PARCEL) || + (ctrl_action == ACTION_APPLY_REGION)) + { + doApplyEnvironment(ctrl_action); + } + else + { + LL_WARNS("ENVIRONMENT") << "Unknown settings action '" << ctrl_action << "'" << LL_ENDL; + } +} + +void LLFloaterEditExtDayCycle::onBtnCancel() +{ + closeFloater(); // will restore env +} + +void LLFloaterEditExtDayCycle::onButtonImport() +{ + doImportFromDisk(); +} + +void LLFloaterEditExtDayCycle::onAddTrack() +{ + // todo: 2.5% safety zone + std::string sldr_key = mFramesSlider->getCurSlider(); + F32 frame = mTimeSlider->getCurSliderValue(); + LLSettingsBase::ptr_t setting; + if (mEditDay->getSettingsAtKeyframe(frame, mCurrentTrack).get() != NULL) + { + return; + } + + if (mCurrentTrack == LLSettingsDay::TRACK_WATER) + { + // scratch water should always have the current water settings. + setting = mScratchWater->buildClone(); + mEditDay->setWaterAtKeyframe(std::dynamic_pointer_cast<LLSettingsWater>(setting), frame); + } + else + { + // scratch sky should always have the current sky settings. + setting = mScratchSky->buildClone(); + mEditDay->setSkyAtKeyframe(std::dynamic_pointer_cast<LLSettingsSky>(setting), frame, mCurrentTrack); + } + + addSliderFrame(frame, setting); + updateTabs(); +} + +void LLFloaterEditExtDayCycle::onRemoveTrack() +{ + std::string sldr_key = mFramesSlider->getCurSlider(); + if (!sldr_key.empty()) + { + return; + } + removeCurrentSliderFrame(); + updateButtons(); +} + +void LLFloaterEditExtDayCycle::onCommitName(class LLLineEditor* caller, void* user_data) +{ + mEditDay->setName(caller->getText()); +} + +void LLFloaterEditExtDayCycle::onTrackSelectionCallback(const LLSD& user_data) +{ + U32 track_index = user_data.asInteger(); // 1-5 + selectTrack(track_index); +} + +void LLFloaterEditExtDayCycle::onPlayActionCallback(const LLSD& user_data) +{ + std::string action = user_data.asString(); + F32 frame = mTimeSlider->getCurSliderValue(); + if (action == "play") + { + startPlay(); + } + else if (action == "pause") + { + stopPlay(); + } + else if (mSliderKeyMap.size() != 0) + { + F32 new_frame = 0; + if (action == "forward") + { + new_frame = mEditDay->getUpperBoundFrame(mCurrentTrack, frame); + } + else if (action == "back") + { + new_frame = mEditDay->getLowerBoundFrame(mCurrentTrack, frame - (mTimeSlider->getIncrement() / 2)); + } + selectFrame(new_frame); + stopPlay(); + } +} + +void LLFloaterEditExtDayCycle::onFrameSliderCallback(const LLSD &data) +{ + //LL_WARNS("LAPRAS") << "LLFloaterEditExtDayCycle::onFrameSliderCallback(" << data << ")" << LL_ENDL; + + std::string curslider = mFramesSlider->getCurSlider(); + + LL_WARNS("LAPRAS") << "Current slider set to \"" << curslider << "\"" << LL_ENDL; + F32 sliderpos(0.0); + + if (curslider.empty()) + { + S32 x(0), y(0); + LLUI::getMousePositionLocal(mFramesSlider, &x, &y); + + sliderpos = mFramesSlider->getSliderValueFromX(x); + } + else + { + sliderpos = mFramesSlider->getCurSliderValue(); + } + + mTimeSlider->setCurSliderValue(sliderpos); +// if (mSliderKeyMap.size() == 0) +// { +// mLastFrameSlider.clear(); +// return; +// } +// // make sure we have a slider +// const std::string& cur_sldr = mFramesSlider->getCurSlider(); +// if (cur_sldr.empty()) +// { +// mLastFrameSlider.clear(); +// return; +// } +// +// F32 new_frame = mFramesSlider->getCurSliderValue(); +// // todo: add safety 2.5% checks +// keymap_t::iterator iter = mSliderKeyMap.find(cur_sldr); +// if (iter != mSliderKeyMap.end() && mEditDay->getSettingsAtKeyframe(new_frame, mCurrentTrack).get() == NULL) +// { +// if (gKeyboard->currentMask(TRUE) == MASK_SHIFT) +// { +// LL_DEBUGS() << "Copying frame from " << iter->second.mFrame << " to " << new_frame << LL_ENDL; +// LLSettingsBase::ptr_t new_settings; +// +// // mEditDay still remembers old position, add copy at new position +// if (mCurrentTrack == LLSettingsDay::TRACK_WATER) +// { +// LLSettingsWaterPtr_t water_ptr = std::dynamic_pointer_cast<LLSettingsWater>(iter->second.pSettings)->buildClone(); +// mEditDay->setWaterAtKeyframe(water_ptr, new_frame); +// new_settings = water_ptr; +// } +// else +// { +// LLSettingsSkyPtr_t sky_ptr = std::dynamic_pointer_cast<LLSettingsSky>(iter->second.pSettings)->buildClone(); +// mEditDay->setSkyAtKeyframe(sky_ptr, new_frame, mCurrentTrack); +// new_settings = sky_ptr; +// } +// +// // mSliderKeyMap still remembers old position, for simplicity, just move it to be identical to slider +// F32 old_frame = iter->second.mFrame; +// iter->second.mFrame = new_frame; +// // slider already moved old frame, create new one in old place +// addSliderFrame(old_frame, new_settings, false /*because we are going to reselect new one*/); +// // reselect new frame +// mFramesSlider->setCurSlider(iter->first); +// } +// else +// { +// LL_DEBUGS() << "Moving frame from " << iter->second.mFrame << " to " << new_frame << LL_ENDL; +// if (mEditDay->moveTrackKeyframe(mCurrentTrack, iter->second.mFrame, new_frame)) +// { +// iter->second.mFrame = new_frame; +// } +// } +// } +// +// mTimeSlider->setCurSliderValue(new_frame); +// +// if (mLastFrameSlider != cur_sldr) +// { +// // technically should not be possible for both frame and slider to change +// // but for safety, assume that they can change independently and both +// mLastFrameSlider = cur_sldr; +// updateTabs(); +// } +// else +// { +// updateButtons(); +// updateTimeAndLabel(); +// } +} + +void LLFloaterEditExtDayCycle::onFrameSliderDoubleClick(S32 x, S32 y, MASK mask) +{ + onAddTrack(); +} + +void LLFloaterEditExtDayCycle::onFrameSliderMouseDown(S32 x, S32 y, MASK mask) +{ + stopPlay(); + F32 sliderpos = mFramesSlider->getSliderValueFromX(x); + + std::string slidername = mFramesSlider->getCurSlider(); + + if (!slidername.empty()) + { + F32 sliderval = mFramesSlider->getSliderValue(slidername); + + LL_WARNS("LAPRAS") << "Selected vs mouse delta = " << (sliderval - sliderpos) << LL_ENDL; + + if (fabs(sliderval - sliderpos) > FRAME_SLOP_FACTOR) + { + mFramesSlider->resetCurSlider(); + } + } + LL_WARNS("LAPRAS") << "DOWN: X=" << x << " Y=" << y << " MASK=" << mask << " Position=" << sliderpos << LL_ENDL; +} + +void LLFloaterEditExtDayCycle::onFrameSliderMouseUp(S32 x, S32 y, MASK mask) +{ + F32 sliderpos = mFramesSlider->getSliderValueFromX(x); + + LL_WARNS("LAPRAS") << " UP: X=" << x << " Y=" << y << " MASK=" << mask << " Position=" << sliderpos << LL_ENDL; + mTimeSlider->setCurSliderValue(sliderpos); + selectFrame(sliderpos); +} + +void LLFloaterEditExtDayCycle::onTimeSliderMoved() +{ + selectFrame(mTimeSlider->getCurSliderValue()); +} + +void LLFloaterEditExtDayCycle::selectTrack(U32 track_index, bool force ) +{ + mCurrentTrack = track_index; + LLButton* button = getChild<LLButton>(track_tabs[track_index], true); + if (button->getToggleState() && !force) + { + return; + } + + for (int i = 0; i < LLSettingsDay::TRACK_MAX; i++) // use max value + { + getChild<LLButton>(track_tabs[i], true)->setToggleState(i == track_index); + } + + bool show_water = (mCurrentTrack == LLSettingsDay::TRACK_WATER); + mSkyTabLayoutContainer->setVisible(!show_water); + mWaterTabLayoutContainer->setVisible(show_water); + updateSlider(); +} + +void LLFloaterEditExtDayCycle::selectFrame(F32 frame) +{ + mFramesSlider->resetCurSlider(); + + + keymap_t::iterator iter = mSliderKeyMap.begin(); + keymap_t::iterator end_iter = mSliderKeyMap.end(); + while (iter != end_iter) + { + if (fabs(iter->second.mFrame - frame) <= FRAME_SLOP_FACTOR) + { + mFramesSlider->setCurSlider(iter->first); + frame = iter->second.mFrame; + break; + } + iter++; + } + + mTimeSlider->setCurSliderValue(frame); + // block or update tabs according to new selection + updateTabs(); +} + +void LLFloaterEditExtDayCycle::clearTabs() +{ + // Note: If this doesn't look good, init panels with default settings. It might be better looking + if (mCurrentTrack == LLSettingsDay::TRACK_WATER) + { + const LLSettingsWaterPtr_t p_water = LLSettingsWaterPtr_t(NULL); + updateWaterTabs(p_water); + } + else + { + const LLSettingsSkyPtr_t p_sky = LLSettingsSkyPtr_t(NULL); + updateSkyTabs(p_sky); + } + updateButtons(); + updateTimeAndLabel(); +} + +void LLFloaterEditExtDayCycle::updateTabs() +{ + reblendSettings(); + syncronizeTabs(); + + updateButtons(); + updateTimeAndLabel(); +} + +void LLFloaterEditExtDayCycle::updateWaterTabs(const LLSettingsWaterPtr_t &p_water) +{ + LLView* tab_container = mWaterTabLayoutContainer->getChild<LLView>("water_tabs"); //can't extract panels directly, since it is in 'tuple' + LLPanelSettingsWaterMainTab* panel = dynamic_cast<LLPanelSettingsWaterMainTab*>(tab_container->getChildView("water_panel")); + if (panel) + { + panel->setWater(p_water); + } +} + +void LLFloaterEditExtDayCycle::updateSkyTabs(const LLSettingsSkyPtr_t &p_sky) +{ + LLView* tab_container = mSkyTabLayoutContainer->getChild<LLView>("sky_tabs"); //can't extract panels directly, since they are in 'tuple' + + LLPanelSettingsSky* panel; + panel = dynamic_cast<LLPanelSettingsSky*>(tab_container->getChildView("atmosphere_panel")); + if (panel) + { + panel->setSky(p_sky); + } + panel = dynamic_cast<LLPanelSettingsSky*>(tab_container->getChildView("clouds_panel")); + if (panel) + { + panel->setSky(p_sky); + } + panel = dynamic_cast<LLPanelSettingsSky*>(tab_container->getChildView("moon_panel")); + if (panel) + { + panel->setSky(p_sky); + } +} + +void LLFloaterEditExtDayCycle::setWaterTabsEnabled(BOOL enable) +{ + LLView* tab_container = mWaterTabLayoutContainer->getChild<LLView>("water_tabs"); //can't extract panels directly, since it is in 'tuple' + LLPanelSettingsWaterMainTab* panel = dynamic_cast<LLPanelSettingsWaterMainTab*>(tab_container->getChildView("water_panel")); + if (panel) + { + panel->setEnabled(enable); + panel->setAllChildrenEnabled(enable); + } +} + +void LLFloaterEditExtDayCycle::setSkyTabsEnabled(BOOL enable) +{ + LLView* tab_container = mSkyTabLayoutContainer->getChild<LLView>("sky_tabs"); //can't extract panels directly, since they are in 'tuple' + + LLPanelSettingsSky* panel; + panel = dynamic_cast<LLPanelSettingsSky*>(tab_container->getChildView("atmosphere_panel")); + if (panel) + { + panel->setEnabled(enable); + panel->setAllChildrenEnabled(enable); + } + panel = dynamic_cast<LLPanelSettingsSky*>(tab_container->getChildView("clouds_panel")); + if (panel) + { + panel->setEnabled(enable); + panel->setAllChildrenEnabled(enable); + } + panel = dynamic_cast<LLPanelSettingsSky*>(tab_container->getChildView("moon_panel")); + if (panel) + { + panel->setEnabled(enable); + panel->setAllChildrenEnabled(enable); + } +} + +void LLFloaterEditExtDayCycle::updateButtons() +{ + F32 frame = mTimeSlider->getCurSliderValue(); + LLSettingsBase::ptr_t settings = mEditDay->getSettingsAtKeyframe(frame, mCurrentTrack); + bool can_add = settings.get() == NULL; + mAddFrameButton->setEnabled(can_add); + mDeleteFrameButton->setEnabled(!can_add); +} + +void LLFloaterEditExtDayCycle::updateSlider() +{ + F32 frame_position = mTimeSlider->getCurSliderValue(); + mFramesSlider->clear(); + mSliderKeyMap.clear(); + + LLSettingsDay::CycleTrack_t track = mEditDay->getCycleTrack(mCurrentTrack); + for (auto &track_frame : track) + { + addSliderFrame(track_frame.first, track_frame.second, false); + } + + if (mSliderKeyMap.size() > 0) + { + // update positions + mLastFrameSlider = mFramesSlider->getCurSlider(); + updateTabs(); + } + else + { + // disable panels + clearTabs(); + mLastFrameSlider.clear(); + } + + selectFrame(frame_position); +} + +void LLFloaterEditExtDayCycle::updateTimeAndLabel() +{ + F32 time = mTimeSlider->getCurSliderValue(); + mCurrentTimeLabel->setTextArg("[PRCNT]", llformat("%.0f", time * 100)); + if (mDayLength.value() != 0) + { + LLUIString formatted_label = getString("time_label"); + + S64Seconds total = (mDayLength * time); + S32Hours hrs = total; + S32Minutes minutes = total - hrs; + + formatted_label.setArg("[HH]", llformat("%d", hrs.value())); + formatted_label.setArg("[MM]", llformat("%d", abs(minutes.value()))); + mCurrentTimeLabel->setTextArg("[DSC]", formatted_label.getString()); + } + else + { + mCurrentTimeLabel->setTextArg("[DSC]", std::string()); + } + + // Update blender here: +} + +void LLFloaterEditExtDayCycle::addSliderFrame(const F32 frame, LLSettingsBase::ptr_t &setting, bool update_ui) +{ + // multi slider distinguishes elements by key/name in string format + // store names to map to be able to recall dependencies + std::string new_slider = mFramesSlider->addSlider(frame); + mSliderKeyMap[new_slider] = FrameData(frame, setting); + + if (update_ui) + { + mLastFrameSlider = new_slider; + mTimeSlider->setCurSliderValue(frame); + updateTabs(); + } +} + +void LLFloaterEditExtDayCycle::removeCurrentSliderFrame() +{ + std::string sldr = mFramesSlider->getCurSlider(); + if (sldr.empty()) + { + return; + } + mFramesSlider->deleteCurSlider(); + keymap_t::iterator iter = mSliderKeyMap.find(sldr); + if (iter != mSliderKeyMap.end()) + { + LL_DEBUGS() << "Removing frame from " << iter->second.mFrame << LL_ENDL; + mSliderKeyMap.erase(iter); + mEditDay->removeTrackKeyframe(mCurrentTrack, iter->second.mFrame); + } + + mLastFrameSlider = mFramesSlider->getCurSlider(); + mTimeSlider->setCurSliderValue(mFramesSlider->getCurSliderValue()); + updateTabs(); +} + +//------------------------------------------------------------------------- + +LLFloaterEditExtDayCycle::connection_t LLFloaterEditExtDayCycle::setEditCommitSignal(LLFloaterEditExtDayCycle::edit_commit_signal_t::slot_type cb) +{ + return mCommitSignal.connect(cb); +} + +void LLFloaterEditExtDayCycle::loadInventoryItem(const LLUUID &inventoryId) +{ + if (inventoryId.isNull()) + { + LL_WARNS("SETTINGS") << "Attempt to load NULL inventory ID" << LL_ENDL; + mInventoryItem = nullptr; + mInventoryId.setNull(); + return; + } + + mInventoryId = inventoryId; + LL_INFOS("SETTINGS") << "Setting edit inventory item to " << mInventoryId << "." << LL_ENDL; + mInventoryItem = gInventory.getItem(mInventoryId); + + if (!mInventoryItem) + { + LL_WARNS("SETTINGS") << "Could not find inventory item with Id = " << mInventoryId << LL_ENDL; + mInventoryId.setNull(); + mInventoryItem = nullptr; + return; + } + + if (mInventoryItem->getAssetUUID().isNull()) + { + LL_WARNS("SETTINGS") << "Asset ID in inventory item is NULL (" << mInventoryId << ")" << LL_ENDL; + mInventoryId.setNull(); + mInventoryItem = nullptr; + return; + } + + LLSettingsVOBase::getSettingsAsset(mInventoryItem->getAssetUUID(), + [this](LLUUID asset_id, LLSettingsBase::ptr_t settins, S32 status, LLExtStat) { onAssetLoaded(asset_id, settins, status); }); +} + +void LLFloaterEditExtDayCycle::onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status) +{ + mEditDay = std::dynamic_pointer_cast<LLSettingsDay>(settings); + updateEditEnvironment(); + syncronizeTabs(); + refresh(); +} + +void LLFloaterEditExtDayCycle::loadLiveEnvironment(LLEnvironment::EnvSelection_t env) +{ + mEditingEnv = env; + for (S32 idx = static_cast<S32>(env); idx <= LLEnvironment::ENV_DEFAULT; ++idx) + { + LLSettingsDay::ptr_t day = LLEnvironment::instance().getEnvironmentDay(static_cast<LLEnvironment::EnvSelection_t>(idx)); + + if (day) + { + mEditDay = day->buildClone(); + break; + } + } + + if (!mEditDay) + { + LL_WARNS("SETTINGS") << "Unable to load environment " << env << " building default." << LL_ENDL; + mEditDay = LLSettingsVODay::buildDefaultDayCycle(); + } + + updateEditEnvironment(); + syncronizeTabs(); + refresh(); +} + +void LLFloaterEditExtDayCycle::updateEditEnvironment(void) +{ + + S32 skytrack = (mCurrentTrack) ? mCurrentTrack : 1; + mSkyBlender = std::make_shared<LLTrackBlenderLoopingManual>(mScratchSky, mEditDay, skytrack); + mWaterBlender = std::make_shared<LLTrackBlenderLoopingManual>(mScratchWater, mEditDay, LLSettingsDay::TRACK_WATER); + + selectTrack(1, true); + + reblendSettings(); + + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, mScratchSky, mScratchWater); +} + +void LLFloaterEditExtDayCycle::syncronizeTabs() +{ + // This should probably get moved into "updateTabs" + + F32 frame = mTimeSlider->getCurSliderValue(); + bool canedit(false); + + LLSettingsWater::ptr_t psettingWater; + LLTabContainer * tabs = mWaterTabLayoutContainer->getChild<LLTabContainer>("water_tabs"); + if (mCurrentTrack == LLSettingsDay::TRACK_WATER) + { + canedit = true; + psettingWater = std::static_pointer_cast<LLSettingsWater>(mEditDay->getSettingsAtKeyframe(frame, LLSettingsDay::TRACK_WATER)); + if (!psettingWater) + { + canedit = false; + psettingWater = mScratchWater; + } + } + else + { + psettingWater = mScratchWater; + } + + S32 count = tabs->getTabCount(); + for (S32 idx = 0; idx < count; ++idx) + { + LLSettingsEditPanel *panel = static_cast<LLSettingsEditPanel *>(tabs->getPanelByIndex(idx)); + if (panel) + { + panel->setSettings(psettingWater); + panel->setEnabled(canedit); + panel->setAllChildrenEnabled(canedit); + panel->refresh(); + } + } + + LLSettingsSky::ptr_t psettingSky; + + canedit = false; + tabs = mSkyTabLayoutContainer->getChild<LLTabContainer>("sky_tabs"); + if (mCurrentTrack != LLSettingsDay::TRACK_WATER) + { + canedit = true; + psettingSky = std::static_pointer_cast<LLSettingsSky>(mEditDay->getSettingsAtKeyframe(frame, mCurrentTrack)); + if (!psettingSky) + { + canedit = false; + psettingSky = mScratchSky; + } + } + else + { + psettingSky = mScratchSky; + } + + count = tabs->getTabCount(); + for (S32 idx = 0; idx < count; ++idx) + { + LLSettingsEditPanel *panel = static_cast<LLSettingsEditPanel *>(tabs->getPanelByIndex(idx)); + if (panel) + { + panel->setSettings(psettingSky); + panel->setEnabled(canedit); + panel->setAllChildrenEnabled(canedit); + panel->refresh(); + } + } + + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, psettingSky, psettingWater); +} + +void LLFloaterEditExtDayCycle::reblendSettings() +{ + F64 position = mTimeSlider->getCurSliderValue(); + + if ((mSkyBlender->getTrack() != mCurrentTrack) && (mCurrentTrack != LLSettingsDay::TRACK_WATER)) + { + mSkyBlender->switchTrack(mCurrentTrack, position); + } + else + mSkyBlender->setPosition(position); + + mWaterBlender->setPosition(position); +} + +void LLFloaterEditExtDayCycle::doApplyCreateNewInventory() +{ + // This method knows what sort of settings object to create. + LLSettingsVOBase::createInventoryItem(mEditDay, [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); +} + +void LLFloaterEditExtDayCycle::doApplyUpdateInventory() +{ + if (mInventoryId.isNull()) + LLSettingsVOBase::createInventoryItem(mEditDay, [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); + else + LLSettingsVOBase::updateInventoryItem(mEditDay, mInventoryId, [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryUpdated(asset_id, inventory_id, results); }); +} + +void LLFloaterEditExtDayCycle::doApplyEnvironment(const std::string &where) +{ + LLEnvironment::EnvSelection_t env(LLEnvironment::ENV_DEFAULT); + bool updateSimulator(where != ACTION_APPLY_LOCAL); + + if (where == ACTION_APPLY_LOCAL) + env = LLEnvironment::ENV_LOCAL; + else if (where == ACTION_APPLY_PARCEL) + env = LLEnvironment::ENV_PARCEL; + else if (where == ACTION_APPLY_REGION) + env = LLEnvironment::ENV_REGION; + else + { + LL_WARNS("ENVIRONMENT") << "Unknown apply '" << where << "'" << LL_ENDL; + return; + } + + LLEnvironment::instance().setEnvironment(env, mEditDay); + if (updateSimulator) + { + LL_WARNS("ENVIRONMENT") << "Attempting apply" << LL_ENDL; + } +} + +void LLFloaterEditExtDayCycle::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results) +{ + LL_WARNS("ENVIRONMENT") << "Inventory item " << inventory_id << " has been created with asset " << asset_id << " results are:" << results << LL_ENDL; + + setFocus(TRUE); // Call back the focus... + loadInventoryItem(inventory_id); +} + +void LLFloaterEditExtDayCycle::onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results) +{ + LL_WARNS("ENVIRONMENT") << "Inventory item " << inventory_id << " has been updated with asset " << asset_id << " results are:" << results << LL_ENDL; + + if (inventory_id != mInventoryId) + { + loadInventoryItem(inventory_id); + } +} + +void LLFloaterEditExtDayCycle::doImportFromDisk() +{ // Load a a legacy Windlight XML from disk. + + LLFilePicker& picker = LLFilePicker::instance(); + if (picker.getOpenFile(LLFilePicker::FFLOAD_XML)) + { + std::string filename = picker.getFirstFile(); + + LL_WARNS("LAPRAS") << "Selected file: " << filename << LL_ENDL; + LLSettingsDay::ptr_t legacyday = LLEnvironment::createDayCycleFromLegacyPreset(filename); + + if (!legacyday) + { // *TODO* Put up error dialog here. Could not create water from filename + return; + } + + mEditDay = legacyday; + mCurrentTrack = 1; + updateSlider(); + updateEditEnvironment(); + syncronizeTabs(); + refresh(); + } +} + +bool LLFloaterEditExtDayCycle::canUseInventory() const +{ + return LLEnvironment::instance().isInventoryEnabled(); +} + +bool LLFloaterEditExtDayCycle::canApplyRegion() const +{ + return gAgent.canManageEstate(); +} + +bool LLFloaterEditExtDayCycle::canApplyParcel() const +{ + LLParcelSelectionHandle handle(LLViewerParcelMgr::instance().getParcelSelection()); + LLParcel *parcel(nullptr); + + if (handle) + parcel = handle->getParcel(); + if (!parcel) + parcel = LLViewerParcelMgr::instance().getAgentParcel(); + + if (!parcel) + return false; + + return parcel->allowModifyBy(gAgent.getID(), gAgent.getGroupID()) && + LLEnvironment::instance().isExtendedEnvironmentEnabled(); +} + +void LLFloaterEditExtDayCycle::startPlay() +{ + mIsPlaying = true; + mFramesSlider->resetCurSlider(); + mPlayTimer.reset(); + mPlayTimer.start(); + gIdleCallbacks.addFunction(onIdlePlay, this); + mPlayStartFrame = mTimeSlider->getCurSliderValue(); + + getChild<LLView>("play_layout", true)->setVisible(FALSE); + getChild<LLView>("pause_layout", true)->setVisible(TRUE); +} + +void LLFloaterEditExtDayCycle::stopPlay() +{ + if (!mIsPlaying) + return; + + mIsPlaying = false; + gIdleCallbacks.deleteFunction(onIdlePlay, this); + mPlayTimer.stop(); + F32 frame = mTimeSlider->getCurSliderValue(); + selectFrame(frame); + + getChild<LLView>("play_layout", true)->setVisible(TRUE); + getChild<LLView>("pause_layout", true)->setVisible(FALSE); +} + +//static +void LLFloaterEditExtDayCycle::onIdlePlay(void* user_data) +{ + LLFloaterEditExtDayCycle* self = (LLFloaterEditExtDayCycle*)user_data; + + F32 prcnt_played = self->mPlayTimer.getElapsedTimeF32() / DAY_CYCLE_PLAY_TIME_SECONDS; + F32 new_frame = fmod(self->mPlayStartFrame + prcnt_played, 1.f); + + self->mTimeSlider->setCurSliderValue(new_frame); // will do the rounding + self->mSkyBlender->setPosition(new_frame); + self->mWaterBlender->setPosition(new_frame); + self->syncronizeTabs(); + +} + + diff --git a/indra/newview/llfloatereditextdaycycle.h b/indra/newview/llfloatereditextdaycycle.h new file mode 100644 index 0000000000..bee5e17b95 --- /dev/null +++ b/indra/newview/llfloatereditextdaycycle.h @@ -0,0 +1,187 @@ +/** + * @file llfloatereditextdaycycle.h + * @brief Floater to create or edit a day cycle + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, 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_LLFLOATEREDITEXTDAYCYCLE_H +#define LL_LLFLOATEREDITEXTDAYCYCLE_H + +#include "llfloater.h" +#include "llsettingsdaycycle.h" +#include <boost/signals2.hpp> + +#include "llenvironment.h" + +class LLCheckBoxCtrl; +class LLComboBox; +class LLFlyoutComboBtnCtrl; +class LLLineEditor; +class LLMultiSliderCtrl; +class LLTextBox; +class LLTimeCtrl; + +class LLInventoryItem; + +typedef std::shared_ptr<LLSettingsBase> LLSettingsBasePtr_t; + +/** + * Floater for creating or editing a day cycle. + */ +class LLFloaterEditExtDayCycle : public LLFloater +{ + LOG_CLASS(LLFloaterEditExtDayCycle); + +public: + // **RIDER** + static const std::string KEY_INVENTORY_ID; + static const std::string KEY_LIVE_ENVIRONMENT; + static const std::string KEY_DAY_LENGTH; + // **RIDER** + + typedef boost::signals2::signal<void(LLSettingsDay::ptr_t)> edit_commit_signal_t; + typedef boost::signals2::connection connection_t; + + LLFloaterEditExtDayCycle(const LLSD &key); + ~LLFloaterEditExtDayCycle(); + + //void openFloater(LLSettingsDay::ptr_t settings, S64Seconds daylength = S64Seconds(0), S64Seconds dayoffset = S64Seconds(0)); + + BOOL postBuild(); + void onOpen(const LLSD& key); + void onClose(bool app_quitting); + + void onVisibilityChange(BOOL new_visibility); + + connection_t setEditCommitSignal(edit_commit_signal_t::slot_type cb); + + virtual void refresh(); + +private: + + // flyout response/click + void onButtonApply(LLUICtrl *ctrl, const LLSD &data); + void onBtnCancel(); + void onButtonImport(); + void onAddTrack(); + void onRemoveTrack(); + void onCommitName(class LLLineEditor* caller, void* user_data); + void onTrackSelectionCallback(const LLSD& user_data); + void onPlayActionCallback(const LLSD& user_data); + // time slider moved + void onTimeSliderMoved(); + // a frame moved or frame selection changed + void onFrameSliderCallback(const LLSD &); + void onFrameSliderDoubleClick(S32 x, S32 y, MASK mask); + void onFrameSliderMouseDown(S32 x, S32 y, MASK mask); + void onFrameSliderMouseUp(S32 x, S32 y, MASK mask); + + void selectTrack(U32 track_index, bool force = false); + void selectFrame(F32 frame); + void clearTabs(); + void updateTabs(); + void updateWaterTabs(const LLSettingsWaterPtr_t &p_water); + void updateSkyTabs(const LLSettingsSkyPtr_t &p_sky); + void setWaterTabsEnabled(BOOL enable); + void setSkyTabsEnabled(BOOL enable); + void updateButtons(); + void updateSlider(); //track to slider + void updateTimeAndLabel(); + void addSliderFrame(const F32 frame, LLSettingsBase::ptr_t &setting, bool update_ui = true); + void removeCurrentSliderFrame(); + + // **RIDER** + void loadInventoryItem(const LLUUID &inventoryId); + void onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status); + void loadLiveEnvironment(LLEnvironment::EnvSelection_t env); + + void doImportFromDisk(); + void doApplyCreateNewInventory(); + void doApplyUpdateInventory(); + void doApplyEnvironment(const std::string &where); + void onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results); + void onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results); + + bool canUseInventory() const; + bool canApplyRegion() const; + bool canApplyParcel() const; + + void updateEditEnvironment(); + void syncronizeTabs(); + void reblendSettings(); + + // **RIDER** + + // play functions + void startPlay(); + void stopPlay(); + static void onIdlePlay(void *); + + LLSettingsDay::ptr_t mEditDay; // edited copy + S64Seconds mDayLength; + U32 mCurrentTrack; + std::string mLastFrameSlider; + + LLButton* mCancelButton; + LLButton* mAddFrameButton; + LLButton* mDeleteFrameButton; + LLButton* mImportButton; + + LLMultiSliderCtrl* mTimeSlider; + LLMultiSliderCtrl* mFramesSlider; + LLView* mSkyTabLayoutContainer; + LLView* mWaterTabLayoutContainer; + LLTextBox* mCurrentTimeLabel; + + // **RIDER** + LLUUID mInventoryId; + LLInventoryItem * mInventoryItem; + LLEnvironment::EnvSelection_t mEditingEnv; + LLTrackBlenderLoopingManual::ptr_t mSkyBlender; + LLTrackBlenderLoopingManual::ptr_t mWaterBlender; + LLSettingsSky::ptr_t mScratchSky; + LLSettingsWater::ptr_t mScratchWater; + // **RIDER** + + LLFlyoutComboBtnCtrl * mFlyoutControl; + + LLFrameTimer mPlayTimer; + F32 mPlayStartFrame; // an env frame + bool mIsPlaying; + + edit_commit_signal_t mCommitSignal; + + // For map of sliders to parameters + class FrameData + { + public: + FrameData() : mFrame(0) {}; + FrameData(F32 frame, LLSettingsBase::ptr_t settings) : mFrame(frame), pSettings(settings) {}; + F32 mFrame; + LLSettingsBase::ptr_t pSettings; + }; + typedef std::map<std::string, FrameData> keymap_t; + keymap_t mSliderKeyMap; //slider's keys vs old_frames&settings, shadows mFramesSlider +}; + +#endif // LL_LLFloaterEditExtDayCycle_H diff --git a/indra/newview/llfloatereditsky.cpp b/indra/newview/llfloatereditsky.cpp deleted file mode 100644 index d809211ea7..0000000000 --- a/indra/newview/llfloatereditsky.cpp +++ /dev/null @@ -1,922 +0,0 @@ -/** - * @file llfloatereditsky.cpp - * @brief Floater to create or edit a sky preset - * - * $LicenseInfo:firstyear=2011&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2011, 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 "llfloatereditsky.h" - -// libs -#include "llbutton.h" -#include "llcheckboxctrl.h" -#include "llcombobox.h" -#include "llmultisliderctrl.h" -#include "llnotifications.h" -#include "llnotificationsutil.h" -#include "llsliderctrl.h" -#include "lltabcontainer.h" -#include "lltimectrl.h" - -// newview -#include "llagent.h" -#include "llcolorswatch.h" -#include "llregioninfomodel.h" -#include "llviewerregion.h" - -static const F32 WL_SUN_AMBIENT_SLIDER_SCALE = 3.0f; -static const F32 WL_BLUE_HORIZON_DENSITY_SCALE = 2.0f; -static const F32 WL_CLOUD_SLIDER_SCALE = 1.0f; - -static F32 sun_pos_to_time24(F32 sun_pos) -{ - return fmodf(sun_pos * 24.0f + 6, 24.0f); -} - -static F32 time24_to_sun_pos(F32 time24) -{ - F32 sun_pos = fmodf((time24 - 6) / 24.0f, 1.0f); - if (sun_pos < 0) ++sun_pos; - return sun_pos; -} - -LLFloaterEditSky::LLFloaterEditSky(const LLSD &key) -: LLFloater(key) -, mSkyPresetNameEditor(NULL) -, mSkyPresetCombo(NULL) -, mMakeDefaultCheckBox(NULL) -, mSaveButton(NULL) -{ -} - -// virtual -BOOL LLFloaterEditSky::postBuild() -{ - mSkyPresetNameEditor = getChild<LLLineEditor>("sky_preset_name"); - mSkyPresetCombo = getChild<LLComboBox>("sky_preset_combo"); - mMakeDefaultCheckBox = getChild<LLCheckBoxCtrl>("make_default_cb"); - mSaveButton = getChild<LLButton>("save"); - - initCallbacks(); - - // Create the sun position scrubber on the slider. - getChild<LLMultiSliderCtrl>("WLSunPos")->addSlider(12.f); - - return TRUE; -} - -// virtual -void LLFloaterEditSky::onOpen(const LLSD& key) -{ - bool new_preset = isNewPreset(); - std::string param = key.asString(); - std::string floater_title = getString(std::string("title_") + param); - std::string hint = getString(std::string("hint_" + param)); - - // Update floater title. - setTitle(floater_title); - - // Update the hint at the top. - getChild<LLUICtrl>("hint")->setValue(hint); - - // Hide the hint to the right of the combo if we're invoked to create a new preset. - getChildView("note")->setVisible(!new_preset); - - // Switch between the sky presets combobox and preset name input field. - mSkyPresetCombo->setVisible(!new_preset); - mSkyPresetNameEditor->setVisible(new_preset); - - reset(); -} - -// virtual -void LLFloaterEditSky::onClose(bool app_quitting) -{ - if (!app_quitting) // there's no point to change environment if we're quitting - { - LLEnvManagerNew::instance().usePrefs(); // revert changes made to current environment - } -} - -// virtual -void LLFloaterEditSky::draw() -{ - syncControls(); - LLFloater::draw(); -} - -void LLFloaterEditSky::initCallbacks(void) -{ - // *TODO: warn user if a region environment update comes while we're editing a region sky preset. - - mSkyPresetNameEditor->setKeystrokeCallback(boost::bind(&LLFloaterEditSky::onSkyPresetNameEdited, this), NULL); - mSkyPresetCombo->setCommitCallback(boost::bind(&LLFloaterEditSky::onSkyPresetSelected, this)); - mSkyPresetCombo->setTextEntryCallback(boost::bind(&LLFloaterEditSky::onSkyPresetNameEdited, this)); - - mSaveButton->setCommitCallback(boost::bind(&LLFloaterEditSky::onBtnSave, this)); - getChild<LLButton>("cancel")->setCommitCallback(boost::bind(&LLFloaterEditSky::onBtnCancel, this)); - - LLEnvManagerNew::instance().setRegionSettingsChangeCallback(boost::bind(&LLFloaterEditSky::onRegionSettingsChange, this)); - LLWLParamManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterEditSky::onSkyPresetListChange, this)); - - // Connect to region info updates. - LLRegionInfoModel::instance().setUpdateCallback(boost::bind(&LLFloaterEditSky::onRegionInfoUpdate, this)); - - //------------------------------------------------------------------------- - - LLWLParamManager& param_mgr = LLWLParamManager::instance(); - - // blue horizon - getChild<LLUICtrl>("WLBlueHorizon")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlMoved, this, _1, ¶m_mgr.mBlueHorizon)); - - // haze density, horizon, mult, and altitude - getChild<LLUICtrl>("WLHazeDensity")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, ¶m_mgr.mHazeDensity)); - getChild<LLUICtrl>("WLHazeHorizon")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, ¶m_mgr.mHazeHorizon)); - getChild<LLUICtrl>("WLDensityMult")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, ¶m_mgr.mDensityMult)); - getChild<LLUICtrl>("WLMaxAltitude")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, ¶m_mgr.mMaxAlt)); - - // blue density - getChild<LLUICtrl>("WLBlueDensity")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlMoved, this, _1, ¶m_mgr.mBlueDensity)); - - // Lighting - - // sunlight - getChild<LLUICtrl>("WLSunlight")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlMoved, this, _1, ¶m_mgr.mSunlight)); - - // glow - getChild<LLUICtrl>("WLGlowR")->setCommitCallback(boost::bind(&LLFloaterEditSky::onGlowRMoved, this, _1, ¶m_mgr.mGlow)); - getChild<LLUICtrl>("WLGlowB")->setCommitCallback(boost::bind(&LLFloaterEditSky::onGlowBMoved, this, _1, ¶m_mgr.mGlow)); - - // ambient - getChild<LLUICtrl>("WLAmbient")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlMoved, this, _1, ¶m_mgr.mAmbient)); - - // time of day - getChild<LLUICtrl>("WLSunPos")->setCommitCallback(boost::bind(&LLFloaterEditSky::onSunMoved, this, _1, ¶m_mgr.mLightnorm)); // multi-slider - getChild<LLTimeCtrl>("WLDayTime")->setCommitCallback(boost::bind(&LLFloaterEditSky::onTimeChanged, this)); // time ctrl - getChild<LLUICtrl>("WLEastAngle")->setCommitCallback(boost::bind(&LLFloaterEditSky::onSunMoved, this, _1, ¶m_mgr.mLightnorm)); - - // Clouds - - // Cloud Color - getChild<LLUICtrl>("WLCloudColor")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlMoved, this, _1, ¶m_mgr.mCloudColor)); - - // Cloud - getChild<LLUICtrl>("WLCloudX")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlRMoved, this, _1, ¶m_mgr.mCloudMain)); - getChild<LLUICtrl>("WLCloudY")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlGMoved, this, _1, ¶m_mgr.mCloudMain)); - getChild<LLUICtrl>("WLCloudDensity")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlBMoved, this, _1, ¶m_mgr.mCloudMain)); - - // Cloud Detail - getChild<LLUICtrl>("WLCloudDetailX")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlRMoved, this, _1, ¶m_mgr.mCloudDetail)); - getChild<LLUICtrl>("WLCloudDetailY")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlGMoved, this, _1, ¶m_mgr.mCloudDetail)); - getChild<LLUICtrl>("WLCloudDetailDensity")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlBMoved, this, _1, ¶m_mgr.mCloudDetail)); - - // Cloud extras - getChild<LLUICtrl>("WLCloudCoverage")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, ¶m_mgr.mCloudCoverage)); - getChild<LLUICtrl>("WLCloudScale")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, ¶m_mgr.mCloudScale)); - getChild<LLUICtrl>("WLCloudLockX")->setCommitCallback(boost::bind(&LLFloaterEditSky::onCloudScrollXToggled, this, _1)); - getChild<LLUICtrl>("WLCloudLockY")->setCommitCallback(boost::bind(&LLFloaterEditSky::onCloudScrollYToggled, this, _1)); - getChild<LLUICtrl>("WLCloudScrollX")->setCommitCallback(boost::bind(&LLFloaterEditSky::onCloudScrollXMoved, this, _1)); - getChild<LLUICtrl>("WLCloudScrollY")->setCommitCallback(boost::bind(&LLFloaterEditSky::onCloudScrollYMoved, this, _1)); - getChild<LLUICtrl>("WLDistanceMult")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, ¶m_mgr.mDistanceMult)); - - // Dome - getChild<LLUICtrl>("WLGamma")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, ¶m_mgr.mWLGamma)); - getChild<LLUICtrl>("WLStarAlpha")->setCommitCallback(boost::bind(&LLFloaterEditSky::onStarAlphaMoved, this, _1)); -} - -//================================================================================================= - -void LLFloaterEditSky::syncControls() -{ - bool err; - - LLWLParamManager * param_mgr = LLWLParamManager::getInstance(); - - LLWLParamSet& cur_params = param_mgr->mCurParams; - - // blue horizon - param_mgr->mBlueHorizon = cur_params.getVector(param_mgr->mBlueHorizon.mName, err); - setColorSwatch("WLBlueHorizon", param_mgr->mBlueHorizon, WL_BLUE_HORIZON_DENSITY_SCALE); - - // haze density, horizon, mult, and altitude - param_mgr->mHazeDensity = cur_params.getFloat(param_mgr->mHazeDensity.mName, err); - childSetValue("WLHazeDensity", (F32) param_mgr->mHazeDensity); - param_mgr->mHazeHorizon = cur_params.getFloat(param_mgr->mHazeHorizon.mName, err); - childSetValue("WLHazeHorizon", (F32) param_mgr->mHazeHorizon); - param_mgr->mDensityMult = cur_params.getFloat(param_mgr->mDensityMult.mName, err); - childSetValue("WLDensityMult", ((F32) param_mgr->mDensityMult) * param_mgr->mDensityMult.mult); - param_mgr->mMaxAlt = cur_params.getFloat(param_mgr->mMaxAlt.mName, err); - childSetValue("WLMaxAltitude", (F32) param_mgr->mMaxAlt); - - // blue density - param_mgr->mBlueDensity = cur_params.getVector(param_mgr->mBlueDensity.mName, err); - setColorSwatch("WLBlueDensity", param_mgr->mBlueDensity, WL_BLUE_HORIZON_DENSITY_SCALE); - - // Lighting - - // sunlight - param_mgr->mSunlight = cur_params.getVector(param_mgr->mSunlight.mName, err); - setColorSwatch("WLSunlight", param_mgr->mSunlight, WL_SUN_AMBIENT_SLIDER_SCALE); - - // glow - param_mgr->mGlow = cur_params.getVector(param_mgr->mGlow.mName, err); - childSetValue("WLGlowR", 2 - param_mgr->mGlow.r / 20.0f); - childSetValue("WLGlowB", -param_mgr->mGlow.b / 5.0f); - - // ambient - param_mgr->mAmbient = cur_params.getVector(param_mgr->mAmbient.mName, err); - setColorSwatch("WLAmbient", param_mgr->mAmbient, WL_SUN_AMBIENT_SLIDER_SCALE); - - F32 time24 = sun_pos_to_time24(param_mgr->mCurParams.getFloat("sun_angle",err) / F_TWO_PI); - getChild<LLMultiSliderCtrl>("WLSunPos")->setCurSliderValue(time24, TRUE); - getChild<LLTimeCtrl>("WLDayTime")->setTime24(time24); - childSetValue("WLEastAngle", param_mgr->mCurParams.getFloat("east_angle",err) / F_TWO_PI); - - // Clouds - - // Cloud Color - param_mgr->mCloudColor = cur_params.getVector(param_mgr->mCloudColor.mName, err); - setColorSwatch("WLCloudColor", param_mgr->mCloudColor, WL_CLOUD_SLIDER_SCALE); - - // Cloud - param_mgr->mCloudMain = cur_params.getVector(param_mgr->mCloudMain.mName, err); - childSetValue("WLCloudX", param_mgr->mCloudMain.r); - childSetValue("WLCloudY", param_mgr->mCloudMain.g); - childSetValue("WLCloudDensity", param_mgr->mCloudMain.b); - - // Cloud Detail - param_mgr->mCloudDetail = cur_params.getVector(param_mgr->mCloudDetail.mName, err); - childSetValue("WLCloudDetailX", param_mgr->mCloudDetail.r); - childSetValue("WLCloudDetailY", param_mgr->mCloudDetail.g); - childSetValue("WLCloudDetailDensity", param_mgr->mCloudDetail.b); - - // Cloud extras - param_mgr->mCloudCoverage = cur_params.getFloat(param_mgr->mCloudCoverage.mName, err); - param_mgr->mCloudScale = cur_params.getFloat(param_mgr->mCloudScale.mName, err); - childSetValue("WLCloudCoverage", (F32) param_mgr->mCloudCoverage); - childSetValue("WLCloudScale", (F32) param_mgr->mCloudScale); - - // cloud scrolling - bool lockX = !param_mgr->mCurParams.getEnableCloudScrollX(); - bool lockY = !param_mgr->mCurParams.getEnableCloudScrollY(); - childSetValue("WLCloudLockX", lockX); - childSetValue("WLCloudLockY", lockY); - - // disable if locked, enable if not - if (lockX) - { - childDisable("WLCloudScrollX"); - } - else - { - childEnable("WLCloudScrollX"); - } - if (lockY) - { - childDisable("WLCloudScrollY"); - } - else - { - childEnable("WLCloudScrollY"); - } - - // *HACK cloud scrolling is off my an additive of 10 - childSetValue("WLCloudScrollX", param_mgr->mCurParams.getCloudScrollX() - 10.0f); - childSetValue("WLCloudScrollY", param_mgr->mCurParams.getCloudScrollY() - 10.0f); - - param_mgr->mDistanceMult = cur_params.getFloat(param_mgr->mDistanceMult.mName, err); - childSetValue("WLDistanceMult", (F32) param_mgr->mDistanceMult); - - // Tweak extras - - param_mgr->mWLGamma = cur_params.getFloat(param_mgr->mWLGamma.mName, err); - childSetValue("WLGamma", (F32) param_mgr->mWLGamma); - - childSetValue("WLStarAlpha", param_mgr->mCurParams.getStarBrightness()); -} - -void LLFloaterEditSky::setColorSwatch(const std::string& name, const WLColorControl& from_ctrl, F32 k) -{ - // Set the value, dividing it by <k> first. - LLVector4 color_vec = from_ctrl; - getChild<LLColorSwatchCtrl>(name)->set(LLColor4(color_vec / k)); -} - -// color control callbacks -void LLFloaterEditSky::onColorControlMoved(LLUICtrl* ctrl, WLColorControl* color_ctrl) -{ - LLWLParamManager::getInstance()->mAnimator.deactivate(); - - LLColorSwatchCtrl* swatch = static_cast<LLColorSwatchCtrl*>(ctrl); - LLVector4 color_vec(swatch->get().mV); - - // Set intensity to maximum of the RGB values. - color_vec.mV[3] = llmax(color_vec.mV[0], llmax(color_vec.mV[1], color_vec.mV[2])); - - // Multiply RGB values by the appropriate factor. - F32 k = WL_CLOUD_SLIDER_SCALE; - if (color_ctrl->isSunOrAmbientColor) - { - k = WL_SUN_AMBIENT_SLIDER_SCALE; - } - if (color_ctrl->isBlueHorizonOrDensity) - { - k = WL_BLUE_HORIZON_DENSITY_SCALE; - } - - color_vec *= k; // intensity isn't affected by the multiplication - - // Apply the new RGBI value. - *color_ctrl = color_vec; - color_ctrl->update(LLWLParamManager::getInstance()->mCurParams); - LLWLParamManager::getInstance()->propagateParameters(); -} - -void LLFloaterEditSky::onColorControlRMoved(LLUICtrl* ctrl, void* userdata) -{ - LLWLParamManager::getInstance()->mAnimator.deactivate(); - - LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); - WLColorControl* color_ctrl = static_cast<WLColorControl *>(userdata); - - color_ctrl->r = sldr_ctrl->getValueF32(); - if (color_ctrl->isSunOrAmbientColor) - { - color_ctrl->r *= WL_SUN_AMBIENT_SLIDER_SCALE; - } - if (color_ctrl->isBlueHorizonOrDensity) - { - color_ctrl->r *= WL_BLUE_HORIZON_DENSITY_SCALE; - } - - // move i if it's the max - if (color_ctrl->r >= color_ctrl->g && color_ctrl->r >= color_ctrl->b && color_ctrl->hasSliderName) - { - color_ctrl->i = color_ctrl->r; - std::string name = color_ctrl->mSliderName; - name.append("I"); - - if (color_ctrl->isSunOrAmbientColor) - { - childSetValue(name, color_ctrl->r / WL_SUN_AMBIENT_SLIDER_SCALE); - } - else if (color_ctrl->isBlueHorizonOrDensity) - { - childSetValue(name, color_ctrl->r / WL_BLUE_HORIZON_DENSITY_SCALE); - } - else - { - childSetValue(name, color_ctrl->r); - } - } - - color_ctrl->update(LLWLParamManager::getInstance()->mCurParams); - - LLWLParamManager::getInstance()->propagateParameters(); -} - -void LLFloaterEditSky::onColorControlGMoved(LLUICtrl* ctrl, void* userdata) -{ - LLWLParamManager::getInstance()->mAnimator.deactivate(); - - LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); - WLColorControl* color_ctrl = static_cast<WLColorControl *>(userdata); - - color_ctrl->g = sldr_ctrl->getValueF32(); - if (color_ctrl->isSunOrAmbientColor) - { - color_ctrl->g *= WL_SUN_AMBIENT_SLIDER_SCALE; - } - if (color_ctrl->isBlueHorizonOrDensity) - { - color_ctrl->g *= WL_BLUE_HORIZON_DENSITY_SCALE; - } - - // move i if it's the max - if (color_ctrl->g >= color_ctrl->r && color_ctrl->g >= color_ctrl->b && color_ctrl->hasSliderName) - { - color_ctrl->i = color_ctrl->g; - std::string name = color_ctrl->mSliderName; - name.append("I"); - - if (color_ctrl->isSunOrAmbientColor) - { - childSetValue(name, color_ctrl->g / WL_SUN_AMBIENT_SLIDER_SCALE); - } - else if (color_ctrl->isBlueHorizonOrDensity) - { - childSetValue(name, color_ctrl->g / WL_BLUE_HORIZON_DENSITY_SCALE); - } - else - { - childSetValue(name, color_ctrl->g); - } - } - - color_ctrl->update(LLWLParamManager::getInstance()->mCurParams); - - LLWLParamManager::getInstance()->propagateParameters(); -} - -void LLFloaterEditSky::onColorControlBMoved(LLUICtrl* ctrl, void* userdata) -{ - LLWLParamManager::getInstance()->mAnimator.deactivate(); - - LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); - WLColorControl* color_ctrl = static_cast<WLColorControl *>(userdata); - - color_ctrl->b = sldr_ctrl->getValueF32(); - if (color_ctrl->isSunOrAmbientColor) - { - color_ctrl->b *= WL_SUN_AMBIENT_SLIDER_SCALE; - } - if (color_ctrl->isBlueHorizonOrDensity) - { - color_ctrl->b *= WL_BLUE_HORIZON_DENSITY_SCALE; - } - - // move i if it's the max - if (color_ctrl->b >= color_ctrl->r && color_ctrl->b >= color_ctrl->g && color_ctrl->hasSliderName) - { - color_ctrl->i = color_ctrl->b; - std::string name = color_ctrl->mSliderName; - name.append("I"); - - if (color_ctrl->isSunOrAmbientColor) - { - childSetValue(name, color_ctrl->b / WL_SUN_AMBIENT_SLIDER_SCALE); - } - else if (color_ctrl->isBlueHorizonOrDensity) - { - childSetValue(name, color_ctrl->b / WL_BLUE_HORIZON_DENSITY_SCALE); - } - else - { - childSetValue(name, color_ctrl->b); - } - } - - color_ctrl->update(LLWLParamManager::getInstance()->mCurParams); - - LLWLParamManager::getInstance()->propagateParameters(); -} - -/// GLOW SPECIFIC CODE -void LLFloaterEditSky::onGlowRMoved(LLUICtrl* ctrl, void* userdata) -{ - LLWLParamManager::getInstance()->mAnimator.deactivate(); - - LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); - WLColorControl* color_ctrl = static_cast<WLColorControl *>(userdata); - - // scaled by 20 - color_ctrl->r = (2 - sldr_ctrl->getValueF32()) * 20; - - color_ctrl->update(LLWLParamManager::getInstance()->mCurParams); - LLWLParamManager::getInstance()->propagateParameters(); -} - -/// \NOTE that we want NEGATIVE (-) B -void LLFloaterEditSky::onGlowBMoved(LLUICtrl* ctrl, void* userdata) -{ - LLWLParamManager::getInstance()->mAnimator.deactivate(); - - LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); - WLColorControl* color_ctrl = static_cast<WLColorControl *>(userdata); - - /// \NOTE that we want NEGATIVE (-) B and NOT by 20 as 20 is too big - color_ctrl->b = -sldr_ctrl->getValueF32() * 5; - - color_ctrl->update(LLWLParamManager::getInstance()->mCurParams); - LLWLParamManager::getInstance()->propagateParameters(); -} - -void LLFloaterEditSky::onFloatControlMoved(LLUICtrl* ctrl, void* userdata) -{ - LLWLParamManager::getInstance()->mAnimator.deactivate(); - - LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); - WLFloatControl * floatControl = static_cast<WLFloatControl *>(userdata); - - floatControl->x = sldr_ctrl->getValueF32() / floatControl->mult; - - floatControl->update(LLWLParamManager::getInstance()->mCurParams); - LLWLParamManager::getInstance()->propagateParameters(); -} - - -// Lighting callbacks - -// time of day -void LLFloaterEditSky::onSunMoved(LLUICtrl* ctrl, void* userdata) -{ - LLWLParamManager::getInstance()->mAnimator.deactivate(); - - LLMultiSliderCtrl* sun_msldr = getChild<LLMultiSliderCtrl>("WLSunPos"); - LLSliderCtrl* east_sldr = getChild<LLSliderCtrl>("WLEastAngle"); - LLTimeCtrl* time_ctrl = getChild<LLTimeCtrl>("WLDayTime"); - WLColorControl* color_ctrl = static_cast<WLColorControl *>(userdata); - - F32 time24 = sun_msldr->getCurSliderValue(); - time_ctrl->setTime24(time24); // sync the time ctrl with the new sun position - - // get the two angles - LLWLParamManager * param_mgr = LLWLParamManager::getInstance(); - - param_mgr->mCurParams.setSunAngle(F_TWO_PI * time24_to_sun_pos(time24)); - param_mgr->mCurParams.setEastAngle(F_TWO_PI * east_sldr->getValueF32()); - - // set the sun vector - color_ctrl->r = -sin(param_mgr->mCurParams.getEastAngle()) * - cos(param_mgr->mCurParams.getSunAngle()); - color_ctrl->g = sin(param_mgr->mCurParams.getSunAngle()); - color_ctrl->b = cos(param_mgr->mCurParams.getEastAngle()) * - cos(param_mgr->mCurParams.getSunAngle()); - color_ctrl->i = 1.f; - - color_ctrl->update(param_mgr->mCurParams); - param_mgr->propagateParameters(); -} - -void LLFloaterEditSky::onTimeChanged() -{ - F32 time24 = getChild<LLTimeCtrl>("WLDayTime")->getTime24(); - getChild<LLMultiSliderCtrl>("WLSunPos")->setCurSliderValue(time24, TRUE); - onSunMoved(getChild<LLUICtrl>("WLSunPos"), &LLWLParamManager::instance().mLightnorm); -} - -void LLFloaterEditSky::onStarAlphaMoved(LLUICtrl* ctrl) -{ - LLWLParamManager::getInstance()->mAnimator.deactivate(); - - LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); - - LLWLParamManager::getInstance()->mCurParams.setStarBrightness(sldr_ctrl->getValueF32()); -} - -// Clouds -void LLFloaterEditSky::onCloudScrollXMoved(LLUICtrl* ctrl) -{ - LLWLParamManager::getInstance()->mAnimator.deactivate(); - - LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); - // *HACK all cloud scrolling is off by an additive of 10. - LLWLParamManager::getInstance()->mCurParams.setCloudScrollX(sldr_ctrl->getValueF32() + 10.0f); -} - -void LLFloaterEditSky::onCloudScrollYMoved(LLUICtrl* ctrl) -{ - LLWLParamManager::getInstance()->mAnimator.deactivate(); - - LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); - - // *HACK all cloud scrolling is off by an additive of 10. - LLWLParamManager::getInstance()->mCurParams.setCloudScrollY(sldr_ctrl->getValueF32() + 10.0f); -} - -void LLFloaterEditSky::onCloudScrollXToggled(LLUICtrl* ctrl) -{ - LLWLParamManager::getInstance()->mAnimator.deactivate(); - - LLCheckBoxCtrl* cb_ctrl = static_cast<LLCheckBoxCtrl*>(ctrl); - - bool lock = cb_ctrl->get(); - LLWLParamManager::getInstance()->mCurParams.setEnableCloudScrollX(!lock); - - LLSliderCtrl* sldr = getChild<LLSliderCtrl>("WLCloudScrollX"); - - if (cb_ctrl->get()) - { - sldr->setEnabled(false); - } - else - { - sldr->setEnabled(true); - } - -} - -void LLFloaterEditSky::onCloudScrollYToggled(LLUICtrl* ctrl) -{ - LLWLParamManager::getInstance()->mAnimator.deactivate(); - - LLCheckBoxCtrl* cb_ctrl = static_cast<LLCheckBoxCtrl*>(ctrl); - bool lock = cb_ctrl->get(); - LLWLParamManager::getInstance()->mCurParams.setEnableCloudScrollY(!lock); - - LLSliderCtrl* sldr = getChild<LLSliderCtrl>("WLCloudScrollY"); - - if (cb_ctrl->get()) - { - sldr->setEnabled(false); - } - else - { - sldr->setEnabled(true); - } -} - -//================================================================================================= - -void LLFloaterEditSky::reset() -{ - if (isNewPreset()) - { - mSkyPresetNameEditor->setValue(LLSD()); - mSaveButton->setEnabled(FALSE); // will be enabled as soon as users enters a name - } - else - { - refreshSkyPresetsList(); - - // Disable controls until a sky preset to edit is selected. - enableEditing(false); - } -} - -bool LLFloaterEditSky::isNewPreset() const -{ - return mKey.asString() == "new"; -} - -void LLFloaterEditSky::refreshSkyPresetsList() -{ - mSkyPresetCombo->removeall(); - - LLWLParamManager::preset_name_list_t region_presets, user_presets, sys_presets; - LLWLParamManager::instance().getPresetNames(region_presets, user_presets, sys_presets); - -#if 0 // Disable editing region skies until the workflow is clear enough. - // Add region presets. - std::string region_name = gAgent.getRegion() ? gAgent.getRegion()->getName() : LLTrans::getString("Unknown"); - for (LLWLParamManager::preset_name_list_t::const_iterator it = region_presets.begin(); it != region_presets.end(); ++it) - { - std::string item_title = *it + " (" + region_name + ")"; - mSkyPresetCombo->add(item_title, LLWLParamKey(*it, LLEnvKey::SCOPE_REGION).toLLSD()); - } - if (region_presets.size() > 0) - { - mSkyPresetCombo->addSeparator(); - } -#endif - - // Add user presets. - for (LLWLParamManager::preset_name_list_t::const_iterator it = user_presets.begin(); it != user_presets.end(); ++it) - { - mSkyPresetCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toLLSD()); - } - if (user_presets.size() > 0) - { - mSkyPresetCombo->addSeparator(); - } - - // Add system presets. - for (LLWLParamManager::preset_name_list_t::const_iterator it = sys_presets.begin(); it != sys_presets.end(); ++it) - { - mSkyPresetCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toLLSD()); - } - - mSkyPresetCombo->setLabel(getString("combo_label")); -} - -void LLFloaterEditSky::enableEditing(bool enable) -{ - // Enable/disable the tab and their contents. - LLTabContainer* tab_container = getChild<LLTabContainer>("WindLight Tabs"); - tab_container->setEnabled(enable); - for (S32 i = 0; i < tab_container->getTabCount(); ++i) - { - tab_container->enableTabButton(i, enable); - tab_container->getPanelByIndex(i)->setCtrlsEnabled(enable); - } - - // Enable/disable saving. - mSaveButton->setEnabled(enable); - mMakeDefaultCheckBox->setEnabled(enable); -} - -void LLFloaterEditSky::saveRegionSky() -{ - LLWLParamKey key(getSelectedSkyPreset()); - llassert(key.scope == LLEnvKey::SCOPE_REGION); - - LL_DEBUGS("Windlight") << "Saving region sky preset: " << key.name << LL_ENDL; - LLWLParamManager& wl_mgr = LLWLParamManager::instance(); - wl_mgr.mCurParams.mName = key.name; - wl_mgr.setParamSet(key, wl_mgr.mCurParams); - - // *TODO: save to cached region settings. - LL_WARNS("Windlight") << "Saving region sky is not fully implemented yet" << LL_ENDL; -} - -LLWLParamKey LLFloaterEditSky::getSelectedSkyPreset() -{ - LLWLParamKey key; - - if (mSkyPresetNameEditor->getVisible()) - { - key.name = mSkyPresetNameEditor->getText(); - key.scope = LLEnvKey::SCOPE_LOCAL; - } - else - { - LLSD combo_val = mSkyPresetCombo->getValue(); - - if (!combo_val.isArray()) // manually typed text - { - key.name = combo_val.asString(); - key.scope = LLEnvKey::SCOPE_LOCAL; - } - else - { - key.fromLLSD(combo_val); - } - } - - return key; -} - -void LLFloaterEditSky::onSkyPresetNameEdited() -{ - // Disable saving a sky preset having empty name. - LLWLParamKey key = getSelectedSkyPreset(); - mSaveButton->setEnabled(!key.name.empty()); -} - -void LLFloaterEditSky::onSkyPresetSelected() -{ - LLWLParamKey key = getSelectedSkyPreset(); - LLWLParamSet sky_params; - - if (!LLWLParamManager::instance().getParamSet(key, sky_params)) - { - // Manually entered string? - LL_WARNS("Windlight") << "No sky preset named " << key.toString() << LL_ENDL; - return; - } - - LLEnvManagerNew::instance().useSkyParams(sky_params.getAll()); - //syncControls(); - - bool can_edit = (key.scope == LLEnvKey::SCOPE_LOCAL || LLEnvManagerNew::canEditRegionSettings()); - enableEditing(can_edit); - - mMakeDefaultCheckBox->setEnabled(key.scope == LLEnvKey::SCOPE_LOCAL); -} - -bool LLFloaterEditSky::onSaveAnswer(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - - // If they choose save, do it. Otherwise, don't do anything - if (option == 0) - { - onSaveConfirmed(); - } - - return false; -} - -void LLFloaterEditSky::onSaveConfirmed() -{ - // Save current params to the selected preset. - LLWLParamKey key(getSelectedSkyPreset()); - - LL_DEBUGS("Windlight") << "Saving sky preset " << key.name << LL_ENDL; - LLWLParamManager& wl_mgr = LLWLParamManager::instance(); - if (wl_mgr.hasParamSet(key)) - { - wl_mgr.setParamSet(key, wl_mgr.mCurParams); - } - else - { - wl_mgr.addParamSet(key, wl_mgr.mCurParams); - } - - wl_mgr.savePreset(key); - - // Change preference if requested. - if (mMakeDefaultCheckBox->getValue()) - { - LL_DEBUGS("Windlight") << key.name << " is now the new preferred sky preset" << LL_ENDL; - LLEnvManagerNew::instance().setUseSkyPreset(key.name); - } - - closeFloater(); -} - -void LLFloaterEditSky::onBtnSave() -{ - LLWLParamKey selected_sky = getSelectedSkyPreset(); - LLWLParamManager& wl_mgr = LLWLParamManager::instance(); - - if (selected_sky.scope == LLEnvKey::SCOPE_REGION) - { - saveRegionSky(); - closeFloater(); - return; - } - - std::string name = selected_sky.name; - if (name.empty()) - { - // *TODO: show an alert - LL_WARNS() << "Empty sky preset name" << LL_ENDL; - return; - } - - // Don't allow overwriting system presets. - if (wl_mgr.isSystemPreset(name)) - { - LLNotificationsUtil::add("WLNoEditDefault"); - return; - } - - // Save, ask for confirmation for overwriting an existing preset. - if (wl_mgr.hasParamSet(selected_sky)) - { - LLNotificationsUtil::add("WLSavePresetAlert", LLSD(), LLSD(), boost::bind(&LLFloaterEditSky::onSaveAnswer, this, _1, _2)); - } - else - { - // new preset, hence no confirmation needed - onSaveConfirmed(); - } -} - -void LLFloaterEditSky::onBtnCancel() -{ - closeFloater(); -} - -void LLFloaterEditSky::onSkyPresetListChange() -{ - LLWLParamKey key = getSelectedSkyPreset(); // preset being edited - if (!LLWLParamManager::instance().hasParamSet(key)) - { - // Preset we've been editing doesn't exist anymore. Close the floater. - closeFloater(false); - } - else - { - // A new preset has been added. - // Refresh the presets list, though it may not make sense as the floater is about to be closed. - refreshSkyPresetsList(); - } -} - -void LLFloaterEditSky::onRegionSettingsChange() -{ - // If creating a new sky, don't bother. - if (isNewPreset()) - { - return; - } - - if (getSelectedSkyPreset().scope == LLEnvKey::SCOPE_REGION) // if editing a region sky - { - // reset the floater to its initial state - reset(); - - // *TODO: Notify user? - } - else // editing a local sky - { - refreshSkyPresetsList(); - } -} - -void LLFloaterEditSky::onRegionInfoUpdate() -{ - bool can_edit = true; - - // If we've selected a region sky preset for editing. - if (getSelectedSkyPreset().scope == LLEnvKey::SCOPE_REGION) - { - // check whether we have the access - can_edit = LLEnvManagerNew::canEditRegionSettings(); - } - - enableEditing(can_edit); -} diff --git a/indra/newview/llfloatereditsky.h b/indra/newview/llfloatereditsky.h deleted file mode 100644 index a06c4fc5fa..0000000000 --- a/indra/newview/llfloatereditsky.h +++ /dev/null @@ -1,113 +0,0 @@ -/** - * @file llfloatereditsky.h - * @brief Floater to create or edit a sky preset - * - * $LicenseInfo:firstyear=2011&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2011, 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_LLFLOATEREDITSKY_H -#define LL_LLFLOATEREDITSKY_H - -#include "llfloater.h" -#include "llwlparammanager.h" - -class LLButton; -class LLCheckBoxCtrl; -class LLComboBox; -class LLLineEditor; - -/** - * Floater for creating or editing a sky preset. - */ -class LLFloaterEditSky : public LLFloater -{ - LOG_CLASS(LLFloaterEditSky); - -public: - LLFloaterEditSky(const LLSD &key); - - /*virtual*/ BOOL postBuild(); - /*virtual*/ void onOpen(const LLSD& key); - /*virtual*/ void onClose(bool app_quitting); - /*virtual*/ void draw(); - -private: - void initCallbacks(void); - - //-- WL stuff begins ------------------------------------------------------ - - void syncControls(); /// sync up sliders with parameters - - void setColorSwatch(const std::string& name, const WLColorControl& from_ctrl, F32 k); - - // general purpose callbacks for dealing with color controllers - void onColorControlMoved(LLUICtrl* ctrl, WLColorControl* color_ctrl); - void onColorControlRMoved(LLUICtrl* ctrl, void* userdata); - void onColorControlGMoved(LLUICtrl* ctrl, void* userdata); - void onColorControlBMoved(LLUICtrl* ctrl, void* userdata); - void onFloatControlMoved(LLUICtrl* ctrl, void* userdata); - - // lighting callbacks for glow - void onGlowRMoved(LLUICtrl* ctrl, void* userdata); - void onGlowBMoved(LLUICtrl* ctrl, void* userdata); - - // lighting callbacks for sun - void onSunMoved(LLUICtrl* ctrl, void* userdata); - void onTimeChanged(); - - // for handling when the star slider is moved to adjust the alpha - void onStarAlphaMoved(LLUICtrl* ctrl); - - // handle cloud scrolling - void onCloudScrollXMoved(LLUICtrl* ctrl); - void onCloudScrollYMoved(LLUICtrl* ctrl); - void onCloudScrollXToggled(LLUICtrl* ctrl); - void onCloudScrollYToggled(LLUICtrl* ctrl); - - //-- WL stuff ends -------------------------------------------------------- - - void reset(); /// reset the floater to its initial state - bool isNewPreset() const; - void refreshSkyPresetsList(); - void enableEditing(bool enable); - void saveRegionSky(); - LLWLParamKey getSelectedSkyPreset(); - - void onSkyPresetNameEdited(); - void onSkyPresetSelected(); - bool onSaveAnswer(const LLSD& notification, const LLSD& response); - void onSaveConfirmed(); - - void onBtnSave(); - void onBtnCancel(); - - void onSkyPresetListChange(); - void onRegionSettingsChange(); - void onRegionInfoUpdate(); - - LLLineEditor* mSkyPresetNameEditor; - LLComboBox* mSkyPresetCombo; - LLCheckBoxCtrl* mMakeDefaultCheckBox; - LLButton* mSaveButton; -}; - -#endif // LL_LLFLOATEREDITSKY_H diff --git a/indra/newview/llfloatereditwater.cpp b/indra/newview/llfloatereditwater.cpp deleted file mode 100644 index 43b44eae37..0000000000 --- a/indra/newview/llfloatereditwater.cpp +++ /dev/null @@ -1,772 +0,0 @@ -/** - * @file llfloatereditwater.cpp - * @brief Floater to create or edit a water preset - * - * $LicenseInfo:firstyear=2011&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2011, 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 "llfloatereditwater.h" - -// libs -#include "llbutton.h" -#include "llcheckboxctrl.h" -#include "llcolorswatch.h" -#include "llcombobox.h" -//#include "llnotifications.h" -#include "llnotificationsutil.h" -#include "llsliderctrl.h" -#include "lltexturectrl.h" - -// newview -#include "llagent.h" -#include "llregioninfomodel.h" -#include "llviewerregion.h" -#include "llwaterparammanager.h" - -#undef max // Fixes a Windows compiler error - -LLFloaterEditWater::LLFloaterEditWater(const LLSD &key) -: LLFloater(key) -, mWaterPresetNameEditor(NULL) -, mWaterPresetCombo(NULL) -, mMakeDefaultCheckBox(NULL) -, mSaveButton(NULL) -{ -} - -// virtual -BOOL LLFloaterEditWater::postBuild() -{ - mWaterPresetNameEditor = getChild<LLLineEditor>("water_preset_name"); - mWaterPresetCombo = getChild<LLComboBox>("water_preset_combo"); - mMakeDefaultCheckBox = getChild<LLCheckBoxCtrl>("make_default_cb"); - mSaveButton = getChild<LLButton>("save"); - - initCallbacks(); - refreshWaterPresetsList(); - syncControls(); - - return TRUE; -} - -// virtual -void LLFloaterEditWater::onOpen(const LLSD& key) -{ - bool new_preset = isNewPreset(); - std::string param = key.asString(); - std::string floater_title = getString(std::string("title_") + param); - std::string hint = getString(std::string("hint_" + param)); - - // Update floater title. - setTitle(floater_title); - - // Update the hint at the top. - getChild<LLUICtrl>("hint")->setValue(hint); - - // Hide the hint to the right of the combo if we're invoked to create a new preset. - getChildView("note")->setVisible(!new_preset); - - // Switch between the water presets combobox and preset name input field. - mWaterPresetCombo->setVisible(!new_preset); - mWaterPresetNameEditor->setVisible(new_preset); - - reset(); -} - -// virtual -void LLFloaterEditWater::onClose(bool app_quitting) -{ - if (!app_quitting) // there's no point to change environment if we're quitting - { - LLEnvManagerNew::instance().usePrefs(); // revert changes made to current environment - } -} - -// virtual -void LLFloaterEditWater::draw() -{ - syncControls(); - LLFloater::draw(); -} - -void LLFloaterEditWater::initCallbacks(void) -{ - mWaterPresetNameEditor->setKeystrokeCallback(boost::bind(&LLFloaterEditWater::onWaterPresetNameEdited, this), NULL); - mWaterPresetCombo->setCommitCallback(boost::bind(&LLFloaterEditWater::onWaterPresetSelected, this)); - mWaterPresetCombo->setTextEntryCallback(boost::bind(&LLFloaterEditWater::onWaterPresetNameEdited, this)); - - mSaveButton->setCommitCallback(boost::bind(&LLFloaterEditWater::onBtnSave, this)); - getChild<LLButton>("cancel")->setCommitCallback(boost::bind(&LLFloaterEditWater::onBtnCancel, this)); - - LLEnvManagerNew::instance().setRegionSettingsChangeCallback(boost::bind(&LLFloaterEditWater::onRegionSettingsChange, this)); - LLWaterParamManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterEditWater::onWaterPresetListChange, this)); - - // Connect to region info updates. - LLRegionInfoModel::instance().setUpdateCallback(boost::bind(&LLFloaterEditWater::onRegionInfoUpdate, this)); - - //------------------------------------------------------------------------- - - LLWaterParamManager& water_mgr = LLWaterParamManager::instance(); - - getChild<LLUICtrl>("WaterFogColor")->setCommitCallback(boost::bind(&LLFloaterEditWater::onWaterFogColorMoved, this, _1, &water_mgr.mFogColor)); - //getChild<LLUICtrl>("WaterGlow")->setCommitCallback(boost::bind(&LLFloaterEditWater::onColorControlAMoved, this, _1, &water_mgr.mFogColor)); - - // fog density - getChild<LLUICtrl>("WaterFogDensity")->setCommitCallback(boost::bind(&LLFloaterEditWater::onExpFloatControlMoved, this, _1, &water_mgr.mFogDensity)); - getChild<LLUICtrl>("WaterUnderWaterFogMod")->setCommitCallback(boost::bind(&LLFloaterEditWater::onFloatControlMoved, this, _1, &water_mgr.mUnderWaterFogMod)); - - // blue density - getChild<LLUICtrl>("WaterNormalScaleX")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector3ControlXMoved, this, _1, &water_mgr.mNormalScale)); - getChild<LLUICtrl>("WaterNormalScaleY")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector3ControlYMoved, this, _1, &water_mgr.mNormalScale)); - getChild<LLUICtrl>("WaterNormalScaleZ")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector3ControlZMoved, this, _1, &water_mgr.mNormalScale)); - - // fresnel - getChild<LLUICtrl>("WaterFresnelScale")->setCommitCallback(boost::bind(&LLFloaterEditWater::onFloatControlMoved, this, _1, &water_mgr.mFresnelScale)); - getChild<LLUICtrl>("WaterFresnelOffset")->setCommitCallback(boost::bind(&LLFloaterEditWater::onFloatControlMoved, this, _1, &water_mgr.mFresnelOffset)); - - // scale above/below - getChild<LLUICtrl>("WaterScaleAbove")->setCommitCallback(boost::bind(&LLFloaterEditWater::onFloatControlMoved, this, _1, &water_mgr.mScaleAbove)); - getChild<LLUICtrl>("WaterScaleBelow")->setCommitCallback(boost::bind(&LLFloaterEditWater::onFloatControlMoved, this, _1, &water_mgr.mScaleBelow)); - - // blur mult - getChild<LLUICtrl>("WaterBlurMult")->setCommitCallback(boost::bind(&LLFloaterEditWater::onFloatControlMoved, this, _1, &water_mgr.mBlurMultiplier)); - - // wave direction - getChild<LLUICtrl>("WaterWave1DirX")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector2ControlXMoved, this, _1, &water_mgr.mWave1Dir)); - getChild<LLUICtrl>("WaterWave1DirY")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector2ControlYMoved, this, _1, &water_mgr.mWave1Dir)); - getChild<LLUICtrl>("WaterWave2DirX")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector2ControlXMoved, this, _1, &water_mgr.mWave2Dir)); - getChild<LLUICtrl>("WaterWave2DirY")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector2ControlYMoved, this, _1, &water_mgr.mWave2Dir)); - - LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("WaterNormalMap"); - texture_ctrl->setDefaultImageAssetID(DEFAULT_WATER_NORMAL); - texture_ctrl->setCommitCallback(boost::bind(&LLFloaterEditWater::onNormalMapPicked, this, _1)); -} - -//============================================================================= - -void LLFloaterEditWater::syncControls() -{ - // *TODO: Eliminate slow getChild() calls. - - bool err; - - LLWaterParamManager& water_mgr = LLWaterParamManager::instance(); - - LLWaterParamSet& current_params = water_mgr.mCurParams; - - // blue horizon - water_mgr.mFogColor = current_params.getVector4(water_mgr.mFogColor.mName, err); - - LLColor4 col = water_mgr.getFogColor(); - //getChild<LLUICtrl>("WaterGlow")->setValue(col.mV[3]); - col.mV[3] = 1.0f; - getChild<LLColorSwatchCtrl>("WaterFogColor")->set(col); - - // fog and wavelets - water_mgr.mFogDensity.mExp = - log(current_params.getFloat(water_mgr.mFogDensity.mName, err)) / - log(water_mgr.mFogDensity.mBase); - water_mgr.setDensitySliderValue(water_mgr.mFogDensity.mExp); - getChild<LLUICtrl>("WaterFogDensity")->setValue(water_mgr.mFogDensity.mExp); - - water_mgr.mUnderWaterFogMod.mX = - current_params.getFloat(water_mgr.mUnderWaterFogMod.mName, err); - getChild<LLUICtrl>("WaterUnderWaterFogMod")->setValue(water_mgr.mUnderWaterFogMod.mX); - - water_mgr.mNormalScale = current_params.getVector3(water_mgr.mNormalScale.mName, err); - getChild<LLUICtrl>("WaterNormalScaleX")->setValue(water_mgr.mNormalScale.mX); - getChild<LLUICtrl>("WaterNormalScaleY")->setValue(water_mgr.mNormalScale.mY); - getChild<LLUICtrl>("WaterNormalScaleZ")->setValue(water_mgr.mNormalScale.mZ); - - // Fresnel - water_mgr.mFresnelScale.mX = current_params.getFloat(water_mgr.mFresnelScale.mName, err); - getChild<LLUICtrl>("WaterFresnelScale")->setValue(water_mgr.mFresnelScale.mX); - water_mgr.mFresnelOffset.mX = current_params.getFloat(water_mgr.mFresnelOffset.mName, err); - getChild<LLUICtrl>("WaterFresnelOffset")->setValue(water_mgr.mFresnelOffset.mX); - - // Scale Above/Below - water_mgr.mScaleAbove.mX = current_params.getFloat(water_mgr.mScaleAbove.mName, err); - getChild<LLUICtrl>("WaterScaleAbove")->setValue(water_mgr.mScaleAbove.mX); - water_mgr.mScaleBelow.mX = current_params.getFloat(water_mgr.mScaleBelow.mName, err); - getChild<LLUICtrl>("WaterScaleBelow")->setValue(water_mgr.mScaleBelow.mX); - - // blur mult - water_mgr.mBlurMultiplier.mX = current_params.getFloat(water_mgr.mBlurMultiplier.mName, err); - getChild<LLUICtrl>("WaterBlurMult")->setValue(water_mgr.mBlurMultiplier.mX); - - // wave directions - water_mgr.mWave1Dir = current_params.getVector2(water_mgr.mWave1Dir.mName, err); - getChild<LLUICtrl>("WaterWave1DirX")->setValue(water_mgr.mWave1Dir.mX); - getChild<LLUICtrl>("WaterWave1DirY")->setValue(water_mgr.mWave1Dir.mY); - - water_mgr.mWave2Dir = current_params.getVector2(water_mgr.mWave2Dir.mName, err); - getChild<LLUICtrl>("WaterWave2DirX")->setValue(water_mgr.mWave2Dir.mX); - getChild<LLUICtrl>("WaterWave2DirY")->setValue(water_mgr.mWave2Dir.mY); - - LLTextureCtrl* textCtrl = getChild<LLTextureCtrl>("WaterNormalMap"); - textCtrl->setImageAssetID(water_mgr.getNormalMapID()); -} - -// color control callbacks -void LLFloaterEditWater::onColorControlRMoved(LLUICtrl* ctrl, WaterColorControl* color_ctrl) -{ - LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); - - color_ctrl->mR = sldr_ctrl->getValueF32(); - - // move i if it's the max - if (color_ctrl->mR >= color_ctrl->mG - && color_ctrl->mR >= color_ctrl->mB - && color_ctrl->mHasSliderName) - { - color_ctrl->mI = color_ctrl->mR; - std::string name = color_ctrl->mSliderName; - name.append("I"); - - getChild<LLUICtrl>(name)->setValue(color_ctrl->mR); - } - - color_ctrl->update(LLWaterParamManager::getInstance()->mCurParams); - - LLWaterParamManager::getInstance()->propagateParameters(); -} - -void LLFloaterEditWater::onColorControlGMoved(LLUICtrl* ctrl, WaterColorControl* color_ctrl) -{ - LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); - - color_ctrl->mG = sldr_ctrl->getValueF32(); - - // move i if it's the max - if (color_ctrl->mG >= color_ctrl->mR - && color_ctrl->mG >= color_ctrl->mB - && color_ctrl->mHasSliderName) - { - color_ctrl->mI = color_ctrl->mG; - std::string name = color_ctrl->mSliderName; - name.append("I"); - - getChild<LLUICtrl>(name)->setValue(color_ctrl->mG); - - } - - color_ctrl->update(LLWaterParamManager::getInstance()->mCurParams); - - LLWaterParamManager::getInstance()->propagateParameters(); -} - -void LLFloaterEditWater::onColorControlBMoved(LLUICtrl* ctrl, WaterColorControl* color_ctrl) -{ - LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); - - color_ctrl->mB = sldr_ctrl->getValueF32(); - - // move i if it's the max - if (color_ctrl->mB >= color_ctrl->mR - && color_ctrl->mB >= color_ctrl->mG - && color_ctrl->mHasSliderName) - { - color_ctrl->mI = color_ctrl->mB; - std::string name = color_ctrl->mSliderName; - name.append("I"); - - getChild<LLUICtrl>(name)->setValue(color_ctrl->mB); - } - - color_ctrl->update(LLWaterParamManager::getInstance()->mCurParams); - - LLWaterParamManager::getInstance()->propagateParameters(); -} - -void LLFloaterEditWater::onColorControlAMoved(LLUICtrl* ctrl, WaterColorControl* color_ctrl) -{ - LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); - - color_ctrl->mA = sldr_ctrl->getValueF32(); - - color_ctrl->update(LLWaterParamManager::getInstance()->mCurParams); - - LLWaterParamManager::getInstance()->propagateParameters(); -} - - -void LLFloaterEditWater::onColorControlIMoved(LLUICtrl* ctrl, WaterColorControl* color_ctrl) -{ - LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); - - color_ctrl->mI = sldr_ctrl->getValueF32(); - - // only for sliders where we pass a name - if (color_ctrl->mHasSliderName) - { - // set it to the top - F32 maxVal = std::max(std::max(color_ctrl->mR, color_ctrl->mG), color_ctrl->mB); - F32 iVal; - - iVal = color_ctrl->mI; - - // get the names of the other sliders - std::string rName = color_ctrl->mSliderName; - rName.append("R"); - std::string gName = color_ctrl->mSliderName; - gName.append("G"); - std::string bName = color_ctrl->mSliderName; - bName.append("B"); - - // handle if at 0 - if (iVal == 0) - { - color_ctrl->mR = 0; - color_ctrl->mG = 0; - color_ctrl->mB = 0; - - // if all at the start - // set them all to the intensity - } - else if (maxVal == 0) - { - color_ctrl->mR = iVal; - color_ctrl->mG = iVal; - color_ctrl->mB = iVal; - } - else - { - // add delta amounts to each - F32 delta = (iVal - maxVal) / maxVal; - color_ctrl->mR *= (1.0f + delta); - color_ctrl->mG *= (1.0f + delta); - color_ctrl->mB *= (1.0f + delta); - } - - // set the sliders to the new vals - getChild<LLUICtrl>(rName)->setValue(color_ctrl->mR); - getChild<LLUICtrl>(gName)->setValue(color_ctrl->mG); - getChild<LLUICtrl>(bName)->setValue(color_ctrl->mB); - } - - // now update the current parameters and send them to shaders - color_ctrl->update(LLWaterParamManager::getInstance()->mCurParams); - LLWaterParamManager::getInstance()->propagateParameters(); -} - -// vector control callbacks -void LLFloaterEditWater::onVector3ControlXMoved(LLUICtrl* ctrl, WaterVector3Control* vector_ctrl) -{ - LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); - - vector_ctrl->mX = sldr_ctrl->getValueF32(); - - vector_ctrl->update(LLWaterParamManager::getInstance()->mCurParams); - - LLWaterParamManager::getInstance()->propagateParameters(); -} - -// vector control callbacks -void LLFloaterEditWater::onVector3ControlYMoved(LLUICtrl* ctrl, WaterVector3Control* vector_ctrl) -{ - LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); - - vector_ctrl->mY = sldr_ctrl->getValueF32(); - - vector_ctrl->update(LLWaterParamManager::getInstance()->mCurParams); - - LLWaterParamManager::getInstance()->propagateParameters(); -} - -// vector control callbacks -void LLFloaterEditWater::onVector3ControlZMoved(LLUICtrl* ctrl, WaterVector3Control* vector_ctrl) -{ - LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); - - vector_ctrl->mZ = sldr_ctrl->getValueF32(); - - vector_ctrl->update(LLWaterParamManager::getInstance()->mCurParams); - - LLWaterParamManager::getInstance()->propagateParameters(); -} - - -// vector control callbacks -void LLFloaterEditWater::onVector2ControlXMoved(LLUICtrl* ctrl, WaterVector2Control* vector_ctrl) -{ - LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); - - vector_ctrl->mX = sldr_ctrl->getValueF32(); - - vector_ctrl->update(LLWaterParamManager::getInstance()->mCurParams); - - LLWaterParamManager::getInstance()->propagateParameters(); -} - -// vector control callbacks -void LLFloaterEditWater::onVector2ControlYMoved(LLUICtrl* ctrl, WaterVector2Control* vector_ctrl) -{ - LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); - - vector_ctrl->mY = sldr_ctrl->getValueF32(); - - vector_ctrl->update(LLWaterParamManager::getInstance()->mCurParams); - - LLWaterParamManager::getInstance()->propagateParameters(); -} - -void LLFloaterEditWater::onFloatControlMoved(LLUICtrl* ctrl, WaterFloatControl* floatControl) -{ - LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); - - floatControl->mX = sldr_ctrl->getValueF32() / floatControl->mMult; - - floatControl->update(LLWaterParamManager::getInstance()->mCurParams); - LLWaterParamManager::getInstance()->propagateParameters(); -} - -void LLFloaterEditWater::onExpFloatControlMoved(LLUICtrl* ctrl, WaterExpFloatControl* expFloatControl) -{ - LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl); - - F32 val = sldr_ctrl->getValueF32(); - expFloatControl->mExp = val; - LLWaterParamManager::getInstance()->setDensitySliderValue(val); - - expFloatControl->update(LLWaterParamManager::getInstance()->mCurParams); - LLWaterParamManager::getInstance()->propagateParameters(); -} - -void LLFloaterEditWater::onWaterFogColorMoved(LLUICtrl* ctrl, WaterColorControl* color_ctrl) -{ - LLColorSwatchCtrl* swatch = static_cast<LLColorSwatchCtrl*>(ctrl); - *color_ctrl = swatch->get(); - - color_ctrl->update(LLWaterParamManager::getInstance()->mCurParams); - LLWaterParamManager::getInstance()->propagateParameters(); -} - -void LLFloaterEditWater::onNormalMapPicked(LLUICtrl* ctrl) -{ - LLTextureCtrl* textCtrl = static_cast<LLTextureCtrl*>(ctrl); - LLUUID textID = textCtrl->getImageAssetID(); - LLWaterParamManager::getInstance()->setNormalMapID(textID); -} - -//============================================================================= - -void LLFloaterEditWater::reset() -{ - if (isNewPreset()) - { - mWaterPresetNameEditor->setValue(LLSD()); - mSaveButton->setEnabled(FALSE); // will be enabled as soon as users enters a name - } - else - { - refreshWaterPresetsList(); - - // Disable controls until a water preset to edit is selected. - enableEditing(false); - } -} - -bool LLFloaterEditWater::isNewPreset() const -{ - return mKey.asString() == "new"; -} - -void LLFloaterEditWater::refreshWaterPresetsList() -{ - mWaterPresetCombo->removeall(); - -#if 0 // *TODO: enable when we have a clear workflow to edit existing region environment - // If the region already has water params, add them to the list. - const LLEnvironmentSettings& region_settings = LLEnvManagerNew::instance().getRegionSettings(); - if (region_settings.getWaterParams().size() != 0) - { - const std::string& region_name = gAgent.getRegion()->getName(); - mWaterPresetCombo->add(region_name, LLSD().with(0, region_name).with(1, LLEnvKey::SCOPE_REGION)); - mWaterPresetCombo->addSeparator(); - } -#endif - - std::list<std::string> user_presets, system_presets; - LLWaterParamManager::instance().getPresetNames(user_presets, system_presets); - - // Add local user presets first. - for (std::list<std::string>::const_iterator it = user_presets.begin(); it != user_presets.end(); ++it) - { - const std::string& name = *it; - mWaterPresetCombo->add(name, LLSD().with(0, name).with(1, LLEnvKey::SCOPE_LOCAL)); // [<name>, <scope>] - } - - if (user_presets.size() > 0) - { - mWaterPresetCombo->addSeparator(); - } - - // Add local system presets. - for (std::list<std::string>::const_iterator it = system_presets.begin(); it != system_presets.end(); ++it) - { - const std::string& name = *it; - mWaterPresetCombo->add(name, LLSD().with(0, name).with(1, LLEnvKey::SCOPE_LOCAL)); // [<name>, <scope>] - } - - mWaterPresetCombo->setLabel(getString("combo_label")); -} - -void LLFloaterEditWater::enableEditing(bool enable) -{ - // Enable/disable water controls. - getChild<LLPanel>("panel_water_preset")->setCtrlsEnabled(enable); - - // Enable/disable saving. - mSaveButton->setEnabled(enable); - mMakeDefaultCheckBox->setEnabled(enable); -} - -void LLFloaterEditWater::saveRegionWater() -{ - llassert(getCurrentScope() == LLEnvKey::SCOPE_REGION); // make sure we're editing region water - - LL_DEBUGS("Windlight") << "Saving region water preset" << LL_ENDL; - - //LLWaterParamSet region_water = water_mgr.mCurParams; - - // *TODO: save to cached region settings. - LL_WARNS("Windlight") << "Saving region water is not fully implemented yet" << LL_ENDL; -} - -std::string LLFloaterEditWater::getCurrentPresetName() const -{ - std::string name; - LLEnvKey::EScope scope; - getSelectedPreset(name, scope); - return name; -} - -LLEnvKey::EScope LLFloaterEditWater::getCurrentScope() const -{ - std::string name; - LLEnvKey::EScope scope; - getSelectedPreset(name, scope); - return scope; -} - -void LLFloaterEditWater::getSelectedPreset(std::string& name, LLEnvKey::EScope& scope) const -{ - if (mWaterPresetNameEditor->getVisible()) - { - name = mWaterPresetNameEditor->getText(); - scope = LLEnvKey::SCOPE_LOCAL; - } - else - { - LLSD combo_val = mWaterPresetCombo->getValue(); - - if (!combo_val.isArray()) // manually typed text - { - name = combo_val.asString(); - scope = LLEnvKey::SCOPE_LOCAL; - } - else - { - name = combo_val[0].asString(); - scope = (LLEnvKey::EScope) combo_val[1].asInteger(); - } - } -} - -void LLFloaterEditWater::onWaterPresetNameEdited() -{ - // Disable saving a water preset having empty name. - mSaveButton->setEnabled(!getCurrentPresetName().empty()); -} - -void LLFloaterEditWater::onWaterPresetSelected() -{ - LLWaterParamSet water_params; - std::string name; - LLEnvKey::EScope scope; - - getSelectedPreset(name, scope); - - // Display selected preset. - if (scope == LLEnvKey::SCOPE_REGION) - { - water_params.setAll(LLEnvManagerNew::instance().getRegionSettings().getWaterParams()); - } - else // local preset selected - { - if (!LLWaterParamManager::instance().getParamSet(name, water_params)) - { - // Manually entered string? - LL_WARNS("Windlight") << "No water preset named " << name << LL_ENDL; - return; - } - } - - LLEnvManagerNew::instance().useWaterParams(water_params.getAll()); - - bool can_edit = (scope == LLEnvKey::SCOPE_LOCAL || LLEnvManagerNew::canEditRegionSettings()); - enableEditing(can_edit); - - mMakeDefaultCheckBox->setEnabled(scope == LLEnvKey::SCOPE_LOCAL); -} - -bool LLFloaterEditWater::onSaveAnswer(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - - // If they choose save, do it. Otherwise, don't do anything - if (option == 0) - { - onSaveConfirmed(); - } - - return false; -} - -void LLFloaterEditWater::onSaveConfirmed() -{ - // Save currently displayed water params to the selected preset. - std::string name = getCurrentPresetName(); - - LL_DEBUGS("Windlight") << "Saving sky preset " << name << LL_ENDL; - LLWaterParamManager& water_mgr = LLWaterParamManager::instance(); - if (water_mgr.hasParamSet(name)) - { - water_mgr.setParamSet(name, water_mgr.mCurParams); - } - else - { - water_mgr.addParamSet(name, water_mgr.mCurParams); - } - - water_mgr.savePreset(name); - - // Change preference if requested. - if (mMakeDefaultCheckBox->getEnabled() && mMakeDefaultCheckBox->getValue()) - { - LL_DEBUGS("Windlight") << name << " is now the new preferred water preset" << LL_ENDL; - LLEnvManagerNew::instance().setUseWaterPreset(name); - } - - closeFloater(); -} - -void LLFloaterEditWater::onBtnSave() -{ - LLEnvKey::EScope scope; - std::string name; - getSelectedPreset(name, scope); - - if (scope == LLEnvKey::SCOPE_REGION) - { - saveRegionWater(); - closeFloater(); - return; - } - - if (name.empty()) - { - // *TODO: show an alert - LL_WARNS() << "Empty water preset name" << LL_ENDL; - return; - } - - // Don't allow overwriting system presets. - LLWaterParamManager& water_mgr = LLWaterParamManager::instance(); - if (water_mgr.isSystemPreset(name)) - { - LLNotificationsUtil::add("WLNoEditDefault"); - return; - } - - // Save, ask for confirmation for overwriting an existing preset. - if (water_mgr.hasParamSet(name)) - { - LLNotificationsUtil::add("WLSavePresetAlert", LLSD(), LLSD(), boost::bind(&LLFloaterEditWater::onSaveAnswer, this, _1, _2)); - } - else - { - // new preset, hence no confirmation needed - onSaveConfirmed(); - } -} - -void LLFloaterEditWater::onBtnCancel() -{ - closeFloater(); -} - -void LLFloaterEditWater::onWaterPresetListChange() -{ - std::string name; - LLEnvKey::EScope scope; - getSelectedPreset(name, scope); // preset being edited - - if (scope == LLEnvKey::SCOPE_LOCAL && !LLWaterParamManager::instance().hasParamSet(name)) - { - // Preset we've been editing doesn't exist anymore. Close the floater. - closeFloater(false); - } - else - { - // A new preset has been added. - // Refresh the presets list, though it may not make sense as the floater is about to be closed. - refreshWaterPresetsList(); - } -} - -void LLFloaterEditWater::onRegionSettingsChange() -{ - // If creating a new preset, don't bother. - if (isNewPreset()) - { - return; - } - - if (getCurrentScope() == LLEnvKey::SCOPE_REGION) // if editing region water - { - // reset the floater to its initial state - reset(); - - // *TODO: Notify user? - } - else // editing a local preset - { - refreshWaterPresetsList(); - } -} - -void LLFloaterEditWater::onRegionInfoUpdate() -{ - bool can_edit = true; - - // If we've selected the region water for editing. - if (getCurrentScope() == LLEnvKey::SCOPE_REGION) - { - // check whether we have the access - can_edit = LLEnvManagerNew::canEditRegionSettings(); - } - - enableEditing(can_edit); -} diff --git a/indra/newview/llfloatereditwater.h b/indra/newview/llfloatereditwater.h deleted file mode 100644 index 2211bca59f..0000000000 --- a/indra/newview/llfloatereditwater.h +++ /dev/null @@ -1,115 +0,0 @@ -/** - * @file llfloatereditwater.h - * @brief Floater to create or edit a water preset - * - * $LicenseInfo:firstyear=2011&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2011, 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_LLFLOATEREDITWATER_H -#define LL_LLFLOATEREDITWATER_H - -#include "llfloater.h" -#include "llenvmanager.h" // for LLEnvKey - -class LLButton; -class LLCheckBoxCtrl; -class LLComboBox; -class LLLineEditor; - -struct WaterVector2Control; -struct WaterVector3Control; -struct WaterColorControl; -struct WaterFloatControl; -struct WaterExpFloatControl; - -class LLFloaterEditWater : public LLFloater -{ - LOG_CLASS(LLFloaterEditWater); - -public: - LLFloaterEditWater(const LLSD &key); - - /*virtual*/ BOOL postBuild(); - /*virtual*/ void onOpen(const LLSD& key); - /*virtual*/ void onClose(bool app_quitting); - /*virtual*/ void draw(); - -private: - void initCallbacks(void); - - //-- WL stuff begins ------------------------------------------------------ - - void syncControls(); /// sync up sliders with parameters - - // general purpose callbacks for dealing with color controllers - void onColorControlRMoved(LLUICtrl* ctrl, WaterColorControl* color_ctrl); - void onColorControlGMoved(LLUICtrl* ctrl, WaterColorControl* color_ctrl); - void onColorControlBMoved(LLUICtrl* ctrl, WaterColorControl* color_ctrl); - void onColorControlAMoved(LLUICtrl* ctrl, WaterColorControl* color_ctrl); - void onColorControlIMoved(LLUICtrl* ctrl, WaterColorControl* color_ctrl); - - void onVector3ControlXMoved(LLUICtrl* ctrl, WaterVector3Control* vector_ctrl); - void onVector3ControlYMoved(LLUICtrl* ctrl, WaterVector3Control* vector_ctrl); - void onVector3ControlZMoved(LLUICtrl* ctrl, WaterVector3Control* vector_ctrl); - - void onVector2ControlXMoved(LLUICtrl* ctrl, WaterVector2Control* vector_ctrl); - void onVector2ControlYMoved(LLUICtrl* ctrl, WaterVector2Control* vector_ctrl); - - void onFloatControlMoved(LLUICtrl* ctrl, WaterFloatControl* floatControl); - - void onExpFloatControlMoved(LLUICtrl* ctrl, WaterExpFloatControl* expFloatControl); - - void onWaterFogColorMoved(LLUICtrl* ctrl, WaterColorControl* color_ctrl); - - void onNormalMapPicked(LLUICtrl* ctrl); /// handle if they choose a new normal map - - //-- WL stuff ends -------------------------------------------------------- - - void reset(); - bool isNewPreset() const; - void refreshWaterPresetsList(); - void enableEditing(bool enable); - void saveRegionWater(); - - std::string getCurrentPresetName() const; - LLEnvKey::EScope getCurrentScope() const; - void getSelectedPreset(std::string& name, LLEnvKey::EScope& scope) const; - - void onWaterPresetNameEdited(); - void onWaterPresetSelected(); - bool onSaveAnswer(const LLSD& notification, const LLSD& response); - void onSaveConfirmed(); - - void onBtnSave(); - void onBtnCancel(); - - void onWaterPresetListChange(); - void onRegionSettingsChange(); - void onRegionInfoUpdate(); - - LLLineEditor* mWaterPresetNameEditor; - LLComboBox* mWaterPresetCombo; - LLCheckBoxCtrl* mMakeDefaultCheckBox; - LLButton* mSaveButton; -}; - -#endif // LL_LLFLOATEREDITWATER_H diff --git a/indra/newview/llfloaterenvironmentsettings.cpp b/indra/newview/llfloaterenvironmentsettings.cpp index 4dbc8cdee0..b7bf6918fe 100644 --- a/indra/newview/llfloaterenvironmentsettings.cpp +++ b/indra/newview/llfloaterenvironmentsettings.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llfloaterenvironmentsettings.cpp * @brief LLFloaterEnvironmentSettings class definition * * $LicenseInfo:firstyear=2011&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2011, 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$ */ @@ -31,11 +31,8 @@ #include "llcombobox.h" #include "llradiogroup.h" -#include "lldaycyclemanager.h" -#include "llenvmanager.h" -#include "llwaterparammanager.h" -#include "llwlparamset.h" -#include "llwlparammanager.h" +#include "llenvironment.h" + LLFloaterEnvironmentSettings::LLFloaterEnvironmentSettings(const LLSD &key) : LLFloater(key) @@ -66,16 +63,13 @@ BOOL LLFloaterEnvironmentSettings::postBuild() mDayCyclePresetCombo->setCommitCallback(boost::bind(&LLFloaterEnvironmentSettings::onSelectDayCyclePreset, this)); childSetCommitCallback("ok_btn", boost::bind(&LLFloaterEnvironmentSettings::onBtnOK, this), NULL); - getChild<LLUICtrl>("ok_btn")->setRightMouseDownCallback(boost::bind(&LLEnvManagerNew::dumpUserPrefs, LLEnvManagerNew::getInstance())); childSetCommitCallback("cancel_btn", boost::bind(&LLFloaterEnvironmentSettings::onBtnCancel, this), NULL); - getChild<LLUICtrl>("cancel_btn")->setRightMouseDownCallback(boost::bind(&LLEnvManagerNew::dumpPresets, LLEnvManagerNew::getInstance())); setCloseCallback(boost::bind(&LLFloaterEnvironmentSettings::cancel, this)); - LLEnvManagerNew::instance().setPreferencesChangeCallback(boost::bind(&LLFloaterEnvironmentSettings::refresh, this)); - LLDayCycleManager::instance().setModifyCallback(boost::bind(&LLFloaterEnvironmentSettings::populateDayCyclePresetsList, this)); - LLWLParamManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterEnvironmentSettings::populateSkyPresetsList, this)); - LLWaterParamManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterEnvironmentSettings::populateWaterPresetsList, this)); + LLEnvironment::instance().setSkyListChange(boost::bind(&LLFloaterEnvironmentSettings::populateSkyPresetsList, this)); + LLEnvironment::instance().setWaterListChange(boost::bind(&LLFloaterEnvironmentSettings::populateWaterPresetsList, this)); + LLEnvironment::instance().setDayCycleListChange(boost::bind(&LLFloaterEnvironmentSettings::populateDayCyclePresetsList, this)); return TRUE; } @@ -86,6 +80,14 @@ void LLFloaterEnvironmentSettings::onOpen(const LLSD& key) refresh(); } +//virtual +void LLFloaterEnvironmentSettings::onClose(bool app_quitting) +{ + if (!app_quitting) + LLEnvironment::instance().updateEnvironment(); +} + + void LLFloaterEnvironmentSettings::onSwitchRegionSettings() { getChild<LLView>("user_environment_settings")->setEnabled(mRegionSettingsRadioGroup->getSelectedIndex() != 0); @@ -120,6 +122,42 @@ void LLFloaterEnvironmentSettings::onSelectDayCyclePreset() void LLFloaterEnvironmentSettings::onBtnOK() { + bool use_region_settings = mRegionSettingsRadioGroup->getSelectedIndex() == 0; + + LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_EDIT); + if (use_region_settings) + { + LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_LOCAL); + LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_PARCEL); + } + else + { + bool use_fixed_sky = mDayCycleSettingsRadioGroup->getSelectedIndex() == 0; + + if (!use_fixed_sky) + { + + std::string day_cycle = mDayCyclePresetCombo->getValue().asString(); + LLSettingsDay::ptr_t day = LLEnvironment::instance().findDayCycleByName(day_cycle); + if (day) + { + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, day, LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET); + } + } + else + { + std::string water_preset = mWaterPresetCombo->getValue().asString(); + std::string sky_preset = mSkyPresetCombo->getValue().asString(); + + LLSettingsSky::ptr_t sky = LLEnvironment::instance().findSkyByName(sky_preset); + LLSettingsWater::ptr_t water = LLEnvironment::instance().findWaterByName(water_preset); + + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::fixedEnvironment_t(sky, water)); + } + LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); + } + +#if 0 // Save and apply new user preferences. bool use_region_settings = mRegionSettingsRadioGroup->getSelectedIndex() == 0; bool use_fixed_sky = mDayCycleSettingsRadioGroup->getSelectedIndex() == 0; @@ -135,7 +173,8 @@ void LLFloaterEnvironmentSettings::onBtnOK() use_region_settings); // *TODO: This triggers applying user preferences again, which is suboptimal. - closeFloater(); +#endif + closeFloater(); } void LLFloaterEnvironmentSettings::onBtnCancel() @@ -145,10 +184,14 @@ void LLFloaterEnvironmentSettings::onBtnCancel() void LLFloaterEnvironmentSettings::refresh() { - LLEnvManagerNew& env_mgr = LLEnvManagerNew::instance(); + LLEnvironment::fixedEnvironment_t fixed = LLEnvironment::instance().getEnvironmentFixed(LLEnvironment::ENV_EDIT); - bool use_region_settings = env_mgr.getUseRegionSettings(); - bool use_fixed_sky = env_mgr.getUseFixedSky(); + LLSettingsDay::ptr_t day = LLEnvironment::instance().getEnvironmentDay(LLEnvironment::ENV_EDIT); + LLSettingsSky::ptr_t sky = fixed.first; + LLSettingsWater::ptr_t water = fixed.second; + + bool use_region_settings = true; + bool use_fixed_sky = !day; // Set up radio buttons according to user preferences. mRegionSettingsRadioGroup->setSelectedIndex(use_region_settings ? 0 : 1); @@ -165,9 +208,18 @@ void LLFloaterEnvironmentSettings::refresh() mDayCyclePresetCombo->setEnabled(!use_fixed_sky); // Select the current presets in combo boxes. - mWaterPresetCombo->selectByValue(env_mgr.getWaterPresetName()); - mSkyPresetCombo->selectByValue(env_mgr.getSkyPresetName()); - mDayCyclePresetCombo->selectByValue(env_mgr.getDayCycleName()); + if (water) + mWaterPresetCombo->selectByValue(water->getName()); + else + mWaterPresetCombo->selectByValue(LLSD()); + if (sky) + mSkyPresetCombo->selectByValue(sky->getName()); + else + mSkyPresetCombo->selectByValue(LLSD()); + if (day) + mDayCyclePresetCombo->selectByValue(day->getName()); + else + mDayCyclePresetCombo->selectByValue(LLSD()); } void LLFloaterEnvironmentSettings::apply() @@ -175,108 +227,73 @@ void LLFloaterEnvironmentSettings::apply() // Update environment with the user choice. bool use_region_settings = mRegionSettingsRadioGroup->getSelectedIndex() == 0; bool use_fixed_sky = mDayCycleSettingsRadioGroup->getSelectedIndex() == 0; - std::string water_preset = mWaterPresetCombo->getValue().asString(); - std::string sky_preset = mSkyPresetCombo->getValue().asString(); + std::string water_preset = mWaterPresetCombo->getValue().asString(); + std::string sky_preset = mSkyPresetCombo->getValue().asString(); std::string day_cycle = mDayCyclePresetCombo->getValue().asString(); - LLEnvManagerNew& env_mgr = LLEnvManagerNew::instance(); if (use_region_settings) { - env_mgr.useRegionSettings(); + //env_mgr.useRegionSettings(); } else { if (use_fixed_sky) { - env_mgr.useSkyPreset(sky_preset); - } + LLSettingsSky::ptr_t psky = LLEnvironment::instance().findSkyByName(sky_preset); + if (psky) + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, psky); + } else { - env_mgr.useDayCycle(day_cycle, LLEnvKey::SCOPE_LOCAL); - } - - env_mgr.useWaterPreset(water_preset); + LLSettingsDay::ptr_t pday = LLEnvironment::instance().findDayCycleByName(day_cycle); + if (pday) + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, pday, LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET); + } + + LLSettingsWater::ptr_t pwater = LLEnvironment::instance().findWaterByName(water_preset); + if (pwater) + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, pwater); } } void LLFloaterEnvironmentSettings::cancel() { // Revert environment to user preferences. - LLEnvManagerNew::instance().usePrefs(); +// LLEnvManagerNew::instance().usePrefs(); } void LLFloaterEnvironmentSettings::populateWaterPresetsList() { - mWaterPresetCombo->removeall(); - - std::list<std::string> user_presets, system_presets; - LLWaterParamManager::instance().getPresetNames(user_presets, system_presets); + mWaterPresetCombo->removeall(); - // Add user presets first. - for (std::list<std::string>::const_iterator it = user_presets.begin(); it != user_presets.end(); ++it) - { - mWaterPresetCombo->add(*it); - } - - if (user_presets.size() > 0) - { - mWaterPresetCombo->addSeparator(); - } + LLEnvironment::list_name_id_t list = LLEnvironment::instance().getWaterList(); - // Add system presets. - for (std::list<std::string>::const_iterator it = system_presets.begin(); it != system_presets.end(); ++it) - { - mWaterPresetCombo->add(*it); - } + for (LLEnvironment::list_name_id_t::iterator it = list.begin(); it != list.end(); ++it) + { + mWaterPresetCombo->add((*it).first, LLSD::String((*it).first)); // + } } void LLFloaterEnvironmentSettings::populateSkyPresetsList() { mSkyPresetCombo->removeall(); - LLWLParamManager::preset_name_list_t region_presets; // unused as we don't list region presets here - LLWLParamManager::preset_name_list_t user_presets, sys_presets; - LLWLParamManager::instance().getPresetNames(region_presets, user_presets, sys_presets); - - // Add user presets. - for (LLWLParamManager::preset_name_list_t::const_iterator it = user_presets.begin(); it != user_presets.end(); ++it) - { - mSkyPresetCombo->add(*it); - } - - if (!user_presets.empty()) - { - mSkyPresetCombo->addSeparator(); - } + LLEnvironment::list_name_id_t list = LLEnvironment::instance().getSkyList(); - // Add system presets. - for (LLWLParamManager::preset_name_list_t::const_iterator it = sys_presets.begin(); it != sys_presets.end(); ++it) - { - mSkyPresetCombo->add(*it); - } + for (LLEnvironment::list_name_id_t::iterator it = list.begin(); it != list.end(); ++it) + { + mSkyPresetCombo->add((*it).first, LLSD::String((*it).first)); + } } void LLFloaterEnvironmentSettings::populateDayCyclePresetsList() { mDayCyclePresetCombo->removeall(); - LLDayCycleManager::preset_name_list_t user_days, sys_days; - LLDayCycleManager::instance().getPresetNames(user_days, sys_days); + LLEnvironment::list_name_id_t list = LLEnvironment::instance().getDayCycleList(); - // Add user days. - for (LLDayCycleManager::preset_name_list_t::const_iterator it = user_days.begin(); it != user_days.end(); ++it) - { - mDayCyclePresetCombo->add(*it); - } - - if (user_days.size() > 0) - { - mDayCyclePresetCombo->addSeparator(); - } - - // Add system days. - for (LLDayCycleManager::preset_name_list_t::const_iterator it = sys_days.begin(); it != sys_days.end(); ++it) - { - mDayCyclePresetCombo->add(*it); - } + for (LLEnvironment::list_name_id_t::iterator it = list.begin(); it != list.end(); ++it) + { + mDayCyclePresetCombo->add((*it).first, LLSD::String((*it).first)); + } } diff --git a/indra/newview/llfloaterenvironmentsettings.h b/indra/newview/llfloaterenvironmentsettings.h index 0ab458a0f6..2236d57ff4 100644 --- a/indra/newview/llfloaterenvironmentsettings.h +++ b/indra/newview/llfloaterenvironmentsettings.h @@ -40,6 +40,7 @@ public: LLFloaterEnvironmentSettings(const LLSD &key); /*virtual*/ BOOL postBuild(); /*virtual*/ void onOpen(const LLSD& key); + /*virtual*/ void onClose(bool app_quitting); private: void onSwitchRegionSettings(); diff --git a/indra/newview/llfloaterfixedenvironment.cpp b/indra/newview/llfloaterfixedenvironment.cpp new file mode 100644 index 0000000000..d5fc34a04b --- /dev/null +++ b/indra/newview/llfloaterfixedenvironment.cpp @@ -0,0 +1,489 @@ +/** + * @file llfloaterfixedenvironment.cpp + * @brief Floaters to create and edit fixed settings for sky and water. + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, 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 "llfloaterfixedenvironment.h" + +#include <boost/make_shared.hpp> + +// libs +#include "llbutton.h" +#include "llnotifications.h" +#include "llnotificationsutil.h" +#include "llsliderctrl.h" +#include "lltabcontainer.h" +#include "llfilepicker.h" + +#include "llviewerparcelmgr.h" + +// newview +#include "llpaneleditwater.h" +#include "llpaneleditsky.h" + +#include "llsettingssky.h" +#include "llsettingswater.h" + +#include "llenvironment.h" +#include "llagent.h" +#include "llparcel.h" + +#include "llsettingsvo.h" +#include "llinventorymodel.h" + +namespace +{ + const std::string FIELD_SETTINGS_NAME("settings_name"); + + const std::string CONTROL_TAB_AREA("tab_settings"); + + const std::string BUTTON_NAME_IMPORT("btn_import"); + const std::string BUTTON_NAME_COMMIT("btn_commit"); + const std::string BUTTON_NAME_CANCEL("btn_cancel"); + const std::string BUTTON_NAME_FLYOUT("btn_flyout"); + + const std::string ACTION_SAVE("save_settings"); + const std::string ACTION_SAVEAS("save_as_new_settings"); + const std::string ACTION_APPLY_LOCAL("apply_local"); + const std::string ACTION_APPLY_PARCEL("apply_parcel"); + const std::string ACTION_APPLY_REGION("apply_region"); + + const std::string XML_FLYOUTMENU_FILE("menu_save_settings.xml"); +} + +//========================================================================= +const std::string LLFloaterFixedEnvironment::KEY_INVENTORY_ID("inventory_id"); + + +//========================================================================= +LLFloaterFixedEnvironment::LLFloaterFixedEnvironment(const LLSD &key) : + LLFloater(key), + mFlyoutControl(nullptr), + mInventoryId(), + mInventoryItem(nullptr) +{ +} + +LLFloaterFixedEnvironment::~LLFloaterFixedEnvironment() +{ + delete mFlyoutControl; +} + +BOOL LLFloaterFixedEnvironment::postBuild() +{ + mTab = getChild<LLTabContainer>(CONTROL_TAB_AREA); + mTxtName = getChild<LLLineEditor>(FIELD_SETTINGS_NAME); + + mTxtName->setCommitOnFocusLost(TRUE); + mTxtName->setCommitCallback([this](LLUICtrl *, const LLSD &) { onNameChanged(mTxtName->getValue().asString()); }); + + getChild<LLButton>(BUTTON_NAME_IMPORT)->setClickedCallback([this](LLUICtrl *, const LLSD &) { onButtonImport(); }); + getChild<LLButton>(BUTTON_NAME_CANCEL)->setClickedCallback([this](LLUICtrl *, const LLSD &) { onButtonCancel(); }); + + mFlyoutControl = new LLFlyoutComboBtnCtrl(this, BUTTON_NAME_COMMIT, BUTTON_NAME_FLYOUT, XML_FLYOUTMENU_FILE); + mFlyoutControl->setAction([this](LLUICtrl *ctrl, const LLSD &data) { onButtonApply(ctrl, data); }); + + return TRUE; +} + +void LLFloaterFixedEnvironment::onOpen(const LLSD& key) +{ + LLUUID invid; + + if (key.has(KEY_INVENTORY_ID)) + { + invid = key[KEY_INVENTORY_ID].asUUID(); + } + + loadInventoryItem(invid); + LL_INFOS("SETTINGS") << "Setting edit inventory item to " << mInventoryId << "." << LL_ENDL; + + updateEditEnvironment(); + syncronizeTabs(); + refresh(); + LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_FAST); + +} + +void LLFloaterFixedEnvironment::onClose(bool app_quitting) +{ + mSettings.reset(); + syncronizeTabs(); +} + +void LLFloaterFixedEnvironment::onFocusReceived() +{ + updateEditEnvironment(); + LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_FAST); +} + +void LLFloaterFixedEnvironment::onFocusLost() +{ + // *TODO*: If the window receiving focus is from a select color or select image control... + // We have technically not changed out of what we are doing so don't change back to displaying + // the local environment. (unfortunately the focus manager has + LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); +} + +void LLFloaterFixedEnvironment::refresh() +{ + if (!mSettings) + { + // disable everything. + return; + } + + bool is_inventory_avail = canUseInventory(); + + mFlyoutControl->setMenuItemEnabled(ACTION_SAVE, is_inventory_avail); + mFlyoutControl->setMenuItemEnabled(ACTION_SAVEAS, is_inventory_avail); + + mTxtName->setValue(mSettings->getName()); + + S32 count = mTab->getTabCount(); + + for (S32 idx = 0; idx < count; ++idx) + { + LLSettingsEditPanel *panel = static_cast<LLSettingsEditPanel *>(mTab->getPanelByIndex(idx)); + if (panel) + panel->refresh(); + } +} + +void LLFloaterFixedEnvironment::syncronizeTabs() +{ + S32 count = mTab->getTabCount(); + + for (S32 idx = 0; idx < count; ++idx) + { + LLSettingsEditPanel *panel = static_cast<LLSettingsEditPanel *>(mTab->getPanelByIndex(idx)); + if (panel) + panel->setSettings(mSettings); + } +} + +void LLFloaterFixedEnvironment::loadInventoryItem(const LLUUID &inventoryId) +{ + if (inventoryId.isNull()) + { + mInventoryItem = nullptr; + mInventoryId.setNull(); + return; + } + + mInventoryId = inventoryId; + LL_INFOS("SETTINGS") << "Setting edit inventory item to " << mInventoryId << "." << LL_ENDL; + mInventoryItem = gInventory.getItem(mInventoryId); + + if (!mInventoryItem) + { + LL_WARNS("SETTINGS") << "Could not find inventory item with Id = " << mInventoryId << LL_ENDL; + mInventoryId.setNull(); + mInventoryItem = nullptr; + return; + } + + LLSettingsVOBase::getSettingsAsset(mInventoryItem->getAssetUUID(), + [this](LLUUID asset_id, LLSettingsBase::ptr_t settins, S32 status, LLExtStat) { onAssetLoaded(asset_id, settins, status); }); +} + +void LLFloaterFixedEnvironment::onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status) +{ + mSettings = settings; + updateEditEnvironment(); + syncronizeTabs(); + refresh(); +} + +void LLFloaterFixedEnvironment::onNameChanged(const std::string &name) +{ + mSettings->setName(name); +} + +void LLFloaterFixedEnvironment::onButtonImport() +{ + doImportFromDisk(); +} + +void LLFloaterFixedEnvironment::onButtonApply(LLUICtrl *ctrl, const LLSD &data) +{ + std::string ctrl_action = ctrl->getName(); + + if (ctrl_action == ACTION_SAVE) + { + doApplyUpdateInventory(); + } + else if (ctrl_action == ACTION_SAVEAS) + { + doApplyCreateNewInventory(); + } + else if ((ctrl_action == ACTION_APPLY_LOCAL) || + (ctrl_action == ACTION_APPLY_PARCEL) || + (ctrl_action == ACTION_APPLY_REGION)) + { + doApplyEnvironment(ctrl_action); + } + else + { + LL_WARNS("ENVIRONMENT") << "Unknown settings action '" << ctrl_action << "'" << LL_ENDL; + } +} + +void LLFloaterFixedEnvironment::onButtonCancel() +{ + // *TODO*: If changed issue a warning? + this->closeFloater(); +} + +void LLFloaterFixedEnvironment::doApplyCreateNewInventory() +{ + // This method knows what sort of settings object to create. + LLSettingsVOBase::createInventoryItem(mSettings, [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); +} + +void LLFloaterFixedEnvironment::doApplyUpdateInventory() +{ + if (mInventoryId.isNull()) + LLSettingsVOBase::createInventoryItem(mSettings, [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); + else + LLSettingsVOBase::updateInventoryItem(mSettings, mInventoryId, [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryUpdated(asset_id, inventory_id, results); }); +} + +void LLFloaterFixedEnvironment::doApplyEnvironment(const std::string &where) +{ + LLEnvironment::EnvSelection_t env(LLEnvironment::ENV_DEFAULT); + bool updateSimulator( where != ACTION_APPLY_LOCAL ); + + if (where == ACTION_APPLY_LOCAL) + env = LLEnvironment::ENV_LOCAL; + else if (where == ACTION_APPLY_PARCEL) + env = LLEnvironment::ENV_PARCEL; + else if (where == ACTION_APPLY_REGION) + env = LLEnvironment::ENV_REGION; + else + { + LL_WARNS("ENVIRONMENT") << "Unknown apply '" << where << "'" << LL_ENDL; + return; + } + + LLEnvironment::instance().setEnvironment(env, mSettings); + if (updateSimulator) + { + LL_WARNS("ENVIRONMENT") << "Attempting apply" << LL_ENDL; + } +} + +void LLFloaterFixedEnvironment::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results) +{ + LL_WARNS("ENVIRONMENT") << "Inventory item " << inventory_id << " has been created with asset " << asset_id << " results are:" << results << LL_ENDL; + + setFocus(TRUE); // Call back the focus... + loadInventoryItem(inventory_id); +} + +void LLFloaterFixedEnvironment::onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results) +{ + LL_WARNS("ENVIRONMENT") << "Inventory item " << inventory_id << " has been updated with asset " << asset_id << " results are:" << results << LL_ENDL; + + if (inventory_id != mInventoryId) + { + loadInventoryItem(inventory_id); + } +} + +//------------------------------------------------------------------------- +bool LLFloaterFixedEnvironment::canUseInventory() const +{ + return LLEnvironment::instance().isInventoryEnabled(); +} + +bool LLFloaterFixedEnvironment::canApplyRegion() const +{ + return gAgent.canManageEstate(); +} + +bool LLFloaterFixedEnvironment::canApplyParcel() const +{ + LLParcelSelectionHandle handle(LLViewerParcelMgr::instance().getParcelSelection()); + LLParcel *parcel(nullptr); + + if (handle) + parcel = handle->getParcel(); + if (!parcel) + parcel = LLViewerParcelMgr::instance().getAgentParcel(); + + if (!parcel) + return false; + + return parcel->allowModifyBy(gAgent.getID(), gAgent.getGroupID()) && + LLEnvironment::instance().isExtendedEnvironmentEnabled(); +} + +//========================================================================= +LLFloaterFixedEnvironmentWater::LLFloaterFixedEnvironmentWater(const LLSD &key): + LLFloaterFixedEnvironment(key) +{} + +BOOL LLFloaterFixedEnvironmentWater::postBuild() +{ + if (!LLFloaterFixedEnvironment::postBuild()) + return FALSE; + + LLPanelSettingsWater * panel; + panel = new LLPanelSettingsWaterMainTab; + panel->buildFromFile("panel_settings_water.xml"); + panel->setWater(std::static_pointer_cast<LLSettingsWater>(mSettings)); + mTab->addTabPanel(LLTabContainer::TabPanelParams().panel(panel).select_tab(true)); + + return TRUE; +} + +void LLFloaterFixedEnvironmentWater::updateEditEnvironment(void) +{ + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, + std::static_pointer_cast<LLSettingsWater>(mSettings)); +} + +void LLFloaterFixedEnvironmentWater::onOpen(const LLSD& key) +{ + if (!mSettings) + { + // Initialize the settings, take a snapshot of the current water. + mSettings = LLEnvironment::instance().getEnvironmentFixedWater(LLEnvironment::ENV_CURRENT)->buildClone(); + mSettings->setName("Snapshot water (new)"); + + // TODO: Should we grab sky and keep it around for reference? + } + + LLFloaterFixedEnvironment::onOpen(key); +} + +void LLFloaterFixedEnvironmentWater::onClose(bool app_quitting) +{ + LLFloaterFixedEnvironment::onClose(app_quitting); +} + +void LLFloaterFixedEnvironmentWater::doImportFromDisk() +{ // Load a a legacy Windlight XML from disk. + + LLFilePicker& picker = LLFilePicker::instance(); + if (picker.getOpenFile(LLFilePicker::FFLOAD_XML)) + { + std::string filename = picker.getFirstFile(); + + LL_WARNS("LAPRAS") << "Selected file: " << filename << LL_ENDL; + LLSettingsWater::ptr_t legacywater = LLEnvironment::createWaterFromLegacyPreset(filename); + + if (!legacywater) + { // *TODO* Put up error dialog here. Could not create water from filename + return; + } + + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, legacywater); + this->setEditSettings(legacywater); + LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_FAST, true); + } +} + +//========================================================================= +LLFloaterFixedEnvironmentSky::LLFloaterFixedEnvironmentSky(const LLSD &key) : + LLFloaterFixedEnvironment(key) +{} + +BOOL LLFloaterFixedEnvironmentSky::postBuild() +{ + if (!LLFloaterFixedEnvironment::postBuild()) + return FALSE; + + LLPanelSettingsSky * panel; + panel = new LLPanelSettingsSkyAtmosTab; + panel->buildFromFile("panel_settings_sky_atmos.xml"); + panel->setSky(std::static_pointer_cast<LLSettingsSky>(mSettings)); + mTab->addTabPanel(LLTabContainer::TabPanelParams().panel(panel).select_tab(true)); + + panel = new LLPanelSettingsSkyCloudTab; + panel->buildFromFile("panel_settings_sky_clouds.xml"); + panel->setSky(std::static_pointer_cast<LLSettingsSky>(mSettings)); + mTab->addTabPanel(LLTabContainer::TabPanelParams().panel(panel).select_tab(false)); + + panel = new LLPanelSettingsSkySunMoonTab; + panel->buildFromFile("panel_settings_sky_sunmoon.xml"); + panel->setSky(std::static_pointer_cast<LLSettingsSky>(mSettings)); + mTab->addTabPanel(LLTabContainer::TabPanelParams().panel(panel).select_tab(false)); + + return TRUE; +} + +void LLFloaterFixedEnvironmentSky::updateEditEnvironment(void) +{ + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, + std::static_pointer_cast<LLSettingsSky>(mSettings)); +} + +void LLFloaterFixedEnvironmentSky::onOpen(const LLSD& key) +{ + if (!mSettings) + { + // Initialize the settings, take a snapshot of the current water. + mSettings = LLEnvironment::instance().getEnvironmentFixedSky(LLEnvironment::ENV_CURRENT)->buildClone(); + mSettings->setName("Snapshot sky (new)"); + + // TODO: Should we grab water and keep it around for reference? + } + + LLFloaterFixedEnvironment::onOpen(key); + +} + +void LLFloaterFixedEnvironmentSky::onClose(bool app_quitting) +{ + LLFloaterFixedEnvironment::onClose(app_quitting); +} + +void LLFloaterFixedEnvironmentSky::doImportFromDisk() +{ // Load a a legacy Windlight XML from disk. + + LLFilePicker& picker = LLFilePicker::instance(); + if (picker.getOpenFile(LLFilePicker::FFLOAD_XML)) + { + std::string filename = picker.getFirstFile(); + + LL_WARNS("LAPRAS") << "Selected file: " << filename << LL_ENDL; + LLSettingsSky::ptr_t legacysky = LLEnvironment::createSkyFromLegacyPreset(filename); + + if (!legacysky) + { // *TODO* Put up error dialog here. Could not create water from filename + return; + } + + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, legacysky); + this->setEditSettings(legacysky); + LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_FAST, true); + } +} + +//========================================================================= + diff --git a/indra/newview/llfloaterfixedenvironment.h b/indra/newview/llfloaterfixedenvironment.h new file mode 100644 index 0000000000..ef47941555 --- /dev/null +++ b/indra/newview/llfloaterfixedenvironment.h @@ -0,0 +1,155 @@ +/** + * @file llfloaterfixedenvironment.h + * @brief Floaters to create and edit fixed settings for sky and water. + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, 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_FLOATERFIXEDENVIRONMENT_H +#define LL_FLOATERFIXEDENVIRONMENT_H + +#include "llfloater.h" +#include "llsettingsbase.h" +#include "llflyoutcombobtn.h" +#include "llinventory.h" + +class LLTabContainer; +class LLButton; +class LLLineEditor; + +/** + * Floater container for creating and editing fixed environment settings. + */ +class LLFloaterFixedEnvironment : public LLFloater +{ + LOG_CLASS(LLFloaterFixedEnvironment); + +public: + static const std::string KEY_INVENTORY_ID; + + LLFloaterFixedEnvironment(const LLSD &key); + ~LLFloaterFixedEnvironment(); + + virtual BOOL postBuild() override; + virtual void onOpen(const LLSD& key) override; + virtual void onClose(bool app_quitting) override; + + virtual void onFocusReceived() override; + virtual void onFocusLost() override; + + void setEditSettings(const LLSettingsBase::ptr_t &settings) { mSettings = settings; syncronizeTabs(); refresh(); } + LLSettingsBase::ptr_t getEditSettings() const { return mSettings; } + +protected: + virtual void updateEditEnvironment() = 0; + virtual void refresh() override; + virtual void syncronizeTabs(); + + void loadInventoryItem(const LLUUID &inventoryId); + + LLTabContainer * mTab; + LLLineEditor * mTxtName; + + LLSettingsBase::ptr_t mSettings; + + virtual void doImportFromDisk() = 0; + virtual void doApplyCreateNewInventory(); + virtual void doApplyUpdateInventory(); + virtual void doApplyEnvironment(const std::string &where); + + bool canUseInventory() const; + bool canApplyRegion() const; + bool canApplyParcel() const; + + LLFlyoutComboBtnCtrl * mFlyoutControl; + + LLUUID mInventoryId; + LLInventoryItem * mInventoryItem; + + void onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results); + void onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results); + +private: + void onNameChanged(const std::string &name); + + void onButtonImport(); + void onButtonApply(LLUICtrl *ctrl, const LLSD &data); + void onButtonCancel(); + + void onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settins, S32 status); +}; + +class LLFloaterFixedEnvironmentWater : public LLFloaterFixedEnvironment +{ + LOG_CLASS(LLFloaterFixedEnvironmentWater); + +public: + LLFloaterFixedEnvironmentWater(const LLSD &key); + + BOOL postBuild() override; + + virtual void onOpen(const LLSD& key) override; + virtual void onClose(bool app_quitting) override; + +protected: + virtual void updateEditEnvironment() override; + + virtual void doImportFromDisk() override; + +private: +}; + +class LLFloaterFixedEnvironmentSky : public LLFloaterFixedEnvironment +{ + LOG_CLASS(LLFloaterFixedEnvironmentSky); + +public: + LLFloaterFixedEnvironmentSky(const LLSD &key); + + BOOL postBuild() override; + + virtual void onOpen(const LLSD& key) override; + virtual void onClose(bool app_quitting) override; + +protected: + virtual void updateEditEnvironment() override; + + virtual void doImportFromDisk() override; + +private: +}; + +class LLSettingsEditPanel : public LLPanel +{ +public: + virtual void setSettings(const LLSettingsBase::ptr_t &) = 0; + +// virtual void refresh() override; + +protected: + LLSettingsEditPanel() : + LLPanel() + {} + +}; + +#endif // LL_FLOATERFIXEDENVIRONMENT_H 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/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 88b3fb7b96..39dada1984 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -78,9 +78,11 @@ #include "lltrans.h" #include "llpanelexperiencelisteditor.h" #include "llpanelexperiencepicker.h" +#include "llpanelenvironment.h" #include "llexperiencecache.h" #include "llgroupactions.h" +#include "llenvironment.h" const F64 COVENANT_REFRESH_TIME_SEC = 60.0f; @@ -138,6 +140,26 @@ protected: LLPanelExperienceListEditor* mBlocked; }; + +class LLPanelLandEnvironment + : public LLPanelEnvironmentInfo +{ +public: + LLPanelLandEnvironment(LLSafeHandle<LLParcelSelection>& parcelp); + + virtual BOOL postBuild(); + virtual void refresh(); + +protected: + + virtual void doApply(); + + + LLSafeHandle<LLParcelSelection>& mParcel; + +}; + + // inserts maturity info(icon and text) into target textbox // names_floater - pointer to floater which contains strings with maturity icons filenames // str_to_parse is string in format "txt1[MATURITY]txt2" where maturity icon and text will be inserted instead of [MATURITY] @@ -277,6 +299,7 @@ LLFloaterLand::LLFloaterLand(const LLSD& seed) mFactoryMap["land_media_panel"] = LLCallbackMap(createPanelLandMedia, this); mFactoryMap["land_access_panel"] = LLCallbackMap(createPanelLandAccess, this); mFactoryMap["land_experiences_panel"] = LLCallbackMap(createPanelLandExperiences, this); + mFactoryMap["land_environment_panel"] = LLCallbackMap(createPanelLandEnvironment, this); sObserver = new LLParcelSelectionObserver(); LLViewerParcelMgr::getInstance()->addObserver( sObserver ); @@ -318,6 +341,7 @@ void LLFloaterLand::refresh() mPanelAccess->refresh(); mPanelCovenant->refresh(); mPanelExperiences->refresh(); + mPanelEnvironment->refresh(); } @@ -386,6 +410,14 @@ void* LLFloaterLand::createPanelLandExperiences(void* data) return self->mPanelExperiences; } +//static +void* LLFloaterLand::createPanelLandEnvironment(void* data) +{ + LLFloaterLand* self = (LLFloaterLand*)data; + self->mPanelEnvironment = new LLPanelLandEnvironment(self->mParcel); + return self->mPanelEnvironment; +} + //--------------------------------------------------------------------------- // LLPanelLandGeneral @@ -3211,3 +3243,101 @@ void LLPanelLandExperiences::refresh() refreshPanel(mAllowed, EXPERIENCE_KEY_TYPE_ALLOWED); refreshPanel(mBlocked, EXPERIENCE_KEY_TYPE_BLOCKED); } + +//========================================================================= + +LLPanelLandEnvironment::LLPanelLandEnvironment(LLSafeHandle<LLParcelSelection>& parcelp): + LLPanelEnvironmentInfo(), + mParcel(parcelp) +{ +} + +BOOL LLPanelLandEnvironment::postBuild() +{ + if (!LLPanelEnvironmentInfo::postBuild()) + return FALSE; + + mAllowOverRide->setVisible(FALSE); + return TRUE; +} + +void LLPanelLandEnvironment::refresh() +{ + /*TODO: if legacy don't do any of this.*/ + + LLParcel* parcel = mParcel->getParcel(); + if (!parcel) + { + mRegionSettingsRadioGroup->setEnabled(FALSE); + mDayLengthSlider->setEnabled(FALSE); + mDayOffsetSlider->setEnabled(FALSE); + mAllowOverRide->setEnabled(FALSE); + + return; + } + + //BOOL owner_or_god = gAgent.isGodlike() || (parcel owner or group) + BOOL owner_or_god = true; + //BOOL owner_or_god_or_manager = owner_or_god || (region && region->isEstateManager()); + + F64Hours daylength; + F64Hours dayoffset; + + LLEnvironment::EnvSelection_t env = LLEnvironment::ENV_PARCEL; + + if (!LLEnvironment::instance().hasEnvironment(env)) + env = LLEnvironment::ENV_REGION; + + daylength = LLEnvironment::instance().getEnvironmentDayLength(env); + dayoffset = LLEnvironment::instance().getEnvironmentDayOffset(env); + + LLSettingsDay::ptr_t pday = LLEnvironment::instance().getEnvironmentDay(env); + + mEditingDayCycle = pday->buildClone(); + + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, mEditingDayCycle, daylength, dayoffset); + + if (dayoffset.value() > 12.0) + dayoffset = dayoffset - F32Hours(24.0f); + + mDayLengthSlider->setValue(daylength.value()); + mDayOffsetSlider->setValue(dayoffset.value()); + + //mRegionSettingsRadioGroup->setSelectedIndex(parcel->getUsesDefaultDayCycle() ? 0 : 1); + mRegionSettingsRadioGroup->setSelectedIndex(1); + + setControlsEnabled(owner_or_god); + +} + +void LLPanelLandEnvironment::doApply() +{ + LLParcel* parcel = mParcel->getParcel(); + if (!parcel) + { + LL_WARNS("PARCEL") << "Could not get parcel." << LL_ENDL; + } + S32 parcel_id = parcel->getLocalID(); + + if (mRegionSettingsRadioGroup->getSelectedIndex() == 0) + { + LLEnvironment::instance().resetParcel(parcel_id); + } + else + { + S64Seconds daylength; + F32Hours dayoffset_h; + + daylength = F32Hours(mDayLengthSlider->getValueF32()); + dayoffset_h = F32Hours(mDayOffsetSlider->getValueF32()); + + if (dayoffset_h.value() < 0) + { + dayoffset_h = F32Hours(24.0f) + dayoffset_h; + } + + S64Seconds dayoffset_s = dayoffset_h; + + LLEnvironment::instance().updateParcel(parcel_id, mEditingDayCycle, daylength.value(), dayoffset_s.value()); + } +} diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h index 0540ddb880..0eea46bc5a 100644 --- a/indra/newview/llfloaterland.h +++ b/indra/newview/llfloaterland.h @@ -67,6 +67,7 @@ class LLPanelLandRenters; class LLPanelLandCovenant; class LLParcel; class LLPanelLandExperiences; +class LLPanelLandEnvironment; class LLFloaterLand : public LLFloater @@ -103,7 +104,8 @@ protected: static void* createPanelLandMedia(void* data); static void* createPanelLandAccess(void* data); static void* createPanelLandExperiences(void* data); - static void* createPanelLandBan(void* data); + static void* createPanelLandEnvironment(void* data); + static void* createPanelLandBan(void* data); protected: @@ -119,6 +121,7 @@ protected: LLPanelLandAccess* mPanelAccess; LLPanelLandCovenant* mPanelCovenant; LLPanelLandExperiences* mPanelExperiences; + LLPanelLandEnvironment *mPanelEnvironment; LLSafeHandle<LLParcelSelection> mParcel; 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<LLNewFileResourceUploadInfo>( mFilenameAndPath, getChild<LLUICtrl>("name_form")->getValue().asString(), getChild<LLUICtrl>("description_form")->getValue().asString(), 0, diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index af68a2aae1..272ac8a1bb 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -52,8 +52,6 @@ #include "llbutton.h" #include "llcheckboxctrl.h" #include "llcombobox.h" -#include "lldaycyclemanager.h" -#include "llenvmanager.h" #include "llestateinfomodel.h" #include "llfilepicker.h" #include "llfloatergodtools.h" // for send_sim_wide_deletes() @@ -87,7 +85,6 @@ #include "llviewertexteditor.h" #include "llviewerwindow.h" #include "llvlcomposition.h" -#include "llwaterparammanager.h" #include "lltrans.h" #include "llagentui.h" #include "llmeshrepository.h" @@ -98,6 +95,7 @@ #include "llexperiencecache.h" #include "llpanelexperiences.h" #include "llcorehttputil.h" +#include "llenvironment.h" const S32 TERRAIN_TEXTURE_COUNT = 4; const S32 CORNER_COUNT = 4; @@ -178,6 +176,26 @@ void unpack_request_params( } */ +class LLPanelRegionEnvironment : public LLPanelEnvironmentInfo +{ +public: + LLPanelRegionEnvironment(); + + void refresh(); + + bool refreshFromRegion(LLViewerRegion* region); + + virtual BOOL postBuild(); + +protected: + virtual void doApply(); + + virtual void doEditCommited(LLSettingsDay::ptr_t &newday); + +private: + LLViewerRegion * mLastRegion; +}; + bool estate_dispatch_initialized = false; @@ -192,7 +210,8 @@ LLUUID LLFloaterRegionInfo::sRequestInvoice; LLFloaterRegionInfo::LLFloaterRegionInfo(const LLSD& seed) - : LLFloater(seed) + : LLFloater(seed), + mEnvironmentPanel(NULL) {} BOOL LLFloaterRegionInfo::postBuild() @@ -223,10 +242,9 @@ BOOL LLFloaterRegionInfo::postBuild() panel->buildFromFile("panel_region_terrain.xml"); mTab->addTabPanel(panel); - panel = new LLPanelEnvironmentInfo; - mInfoPanels.push_back(panel); - panel->buildFromFile("panel_region_environment.xml"); - mTab->addTabPanel(panel); + mEnvironmentPanel = new LLPanelRegionEnvironment; + mEnvironmentPanel->buildFromFile("panel_region_environment.xml"); + mTab->addTabPanel(mEnvironmentPanel); panel = new LLPanelRegionDebugInfo; mInfoPanels.push_back(panel); @@ -245,7 +263,7 @@ BOOL LLFloaterRegionInfo::postBuild() panel->buildFromFile("panel_region_experiences.xml"); mTab->addTabPanel(panel); } - + gMessageSystem->setHandlerFunc( "EstateOwnerMessage", &processEstateOwnerRequest); @@ -337,13 +355,13 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg) { return; } - +#if 0 // We need to re-request environment setting here, // otherwise after we apply (send) updated region settings we won't get them back, // so our environment won't be updated. // This is also the way to know about externally changed region environment. LLEnvManagerNew::instance().requestRegionSettings(); - +#endif LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels"); LLViewerRegion* region = gAgent.getRegion(); @@ -543,6 +561,7 @@ void LLFloaterRegionInfo::refreshFromRegion(LLViewerRegion* region) std::mem_fun(&LLPanelRegionInfo::refreshFromRegion), #endif region)); + mEnvironmentPanel->refreshFromRegion(region); } // public @@ -553,6 +572,7 @@ void LLFloaterRegionInfo::refresh() { (*iter)->refresh(); } + mEnvironmentPanel->refresh(); } void LLFloaterRegionInfo::enableTopButtons() @@ -3086,604 +3106,6 @@ bool LLDispatchSetEstateExperience::operator()( } - -LLPanelEnvironmentInfo::LLPanelEnvironmentInfo() -: mEnableEditing(false), - mRegionSettingsRadioGroup(NULL), - mDayCycleSettingsRadioGroup(NULL), - mWaterPresetCombo(NULL), - mSkyPresetCombo(NULL), - mDayCyclePresetCombo(NULL) -{ -} - -// virtual -BOOL LLPanelEnvironmentInfo::postBuild() -{ - mRegionSettingsRadioGroup = getChild<LLRadioGroup>("region_settings_radio_group"); - mRegionSettingsRadioGroup->setCommitCallback(boost::bind(&LLPanelEnvironmentInfo::onSwitchRegionSettings, this)); - - mDayCycleSettingsRadioGroup = getChild<LLRadioGroup>("sky_dayc_settings_radio_group"); - mDayCycleSettingsRadioGroup->setCommitCallback(boost::bind(&LLPanelEnvironmentInfo::onSwitchDayCycle, this)); - - mWaterPresetCombo = getChild<LLComboBox>("water_settings_preset_combo"); - mWaterPresetCombo->setCommitCallback(boost::bind(&LLPanelEnvironmentInfo::onSelectWaterPreset, this)); - - mSkyPresetCombo = getChild<LLComboBox>("sky_settings_preset_combo"); - mSkyPresetCombo->setCommitCallback(boost::bind(&LLPanelEnvironmentInfo::onSelectSkyPreset, this)); - - mDayCyclePresetCombo = getChild<LLComboBox>("dayc_settings_preset_combo"); - mDayCyclePresetCombo->setCommitCallback(boost::bind(&LLPanelEnvironmentInfo::onSelectDayCycle, this)); - - childSetCommitCallback("apply_btn", boost::bind(&LLPanelEnvironmentInfo::onBtnApply, this), NULL); - getChild<LLButton>("apply_btn")->setRightMouseDownCallback(boost::bind(&LLEnvManagerNew::dumpUserPrefs, LLEnvManagerNew::getInstance())); - childSetCommitCallback("cancel_btn", boost::bind(&LLPanelEnvironmentInfo::onBtnCancel, this), NULL); - getChild<LLButton>("cancel_btn")->setRightMouseDownCallback(boost::bind(&LLEnvManagerNew::dumpPresets, LLEnvManagerNew::getInstance())); - - LLEnvManagerNew::instance().setRegionSettingsChangeCallback(boost::bind(&LLPanelEnvironmentInfo::onRegionSettingschange, this)); - LLEnvManagerNew::instance().setRegionSettingsAppliedCallback(boost::bind(&LLPanelEnvironmentInfo::onRegionSettingsApplied, this, _1)); - - LLDayCycleManager::instance().setModifyCallback(boost::bind(&LLPanelEnvironmentInfo::populateDayCyclesList, this)); - LLWLParamManager::instance().setPresetListChangeCallback(boost::bind(&LLPanelEnvironmentInfo::populateSkyPresetsList, this)); - LLWaterParamManager::instance().setPresetListChangeCallback(boost::bind(&LLPanelEnvironmentInfo::populateWaterPresetsList, this)); - - return TRUE; -} - -// virtual -void LLPanelEnvironmentInfo::onOpen(const LLSD& key) -{ - LL_DEBUGS("Windlight") << "Panel opened, refreshing" << LL_ENDL; - refresh(); -} - -// virtual -void LLPanelEnvironmentInfo::onVisibilityChange(BOOL new_visibility) -{ - // If hiding (user switched to another tab or closed the floater), - // display user's preferred environment. - if (!new_visibility) - { - LLEnvManagerNew::instance().usePrefs(); - } -} - -// virtual -bool LLPanelEnvironmentInfo::refreshFromRegion(LLViewerRegion* region) -{ - LL_DEBUGS("Windlight") << "Region updated, enabling/disabling controls" << LL_ENDL; - BOOL owner_or_god = gAgent.isGodlike() || (region && (region->getOwner() == gAgent.getID())); - BOOL owner_or_god_or_manager = owner_or_god || (region && region->isEstateManager()); - - // Don't refresh from region settings to avoid flicker after applying new region settings. - mEnableEditing = owner_or_god_or_manager; - setControlsEnabled(mEnableEditing); - - return LLPanelRegionInfo::refreshFromRegion(region); -} - -void LLPanelEnvironmentInfo::refresh() -{ - if(gDisconnected) - { - return; - } - - populateWaterPresetsList(); - populateSkyPresetsList(); - populateDayCyclesList(); - - // Init radio groups. - const LLEnvironmentSettings& settings = LLEnvManagerNew::instance().getRegionSettings(); - const LLSD& dc = settings.getWLDayCycle(); - LLSD::Real first_frame_time = dc.size() > 0 ? dc[0][0].asReal() : 0.0f; - const bool use_fixed_sky = dc.size() == 1 && first_frame_time < 0; - mRegionSettingsRadioGroup->setSelectedIndex(settings.getSkyMap().size() == 0 ? 0 : 1); - mDayCycleSettingsRadioGroup->setSelectedIndex(use_fixed_sky ? 0 : 1); - - setControlsEnabled(mEnableEditing); - - setDirty(false); -} - -void LLPanelEnvironmentInfo::setControlsEnabled(bool enabled) -{ - mRegionSettingsRadioGroup->setEnabled(enabled); - mDayCycleSettingsRadioGroup->setEnabled(enabled); - - mWaterPresetCombo->setEnabled(enabled); - mSkyPresetCombo->setEnabled(enabled); - mDayCyclePresetCombo->setEnabled(enabled); - - getChildView("apply_btn")->setEnabled(enabled); - getChildView("cancel_btn")->setEnabled(enabled); - - if (enabled) - { - // Enable/disable some controls based on currently selected radio buttons. - bool use_defaults = mRegionSettingsRadioGroup->getSelectedIndex() == 0; - getChild<LLView>("user_environment_settings")->setEnabled(!use_defaults); - - bool is_fixed_sky = mDayCycleSettingsRadioGroup->getSelectedIndex() == 0; - mSkyPresetCombo->setEnabled(is_fixed_sky); - mDayCyclePresetCombo->setEnabled(!is_fixed_sky); - } -} - -void LLPanelEnvironmentInfo::setApplyProgress(bool started) -{ - LLLoadingIndicator* indicator = getChild<LLLoadingIndicator>("progress_indicator"); - - indicator->setVisible(started); - - if (started) - { - indicator->start(); - } - else - { - indicator->stop(); - } -} - -void LLPanelEnvironmentInfo::setDirty(bool dirty) -{ - getChildView("apply_btn")->setEnabled(dirty); - getChildView("cancel_btn")->setEnabled(dirty); -} - -void LLPanelEnvironmentInfo::sendRegionSunUpdate() -{ - LLRegionInfoModel& region_info = LLRegionInfoModel::instance(); - - // If the region is being switched to fixed sky, - // change the region's sun hour according to the (fixed) sun position. - // This is needed for llGetSunDirection() LSL function to work properly (STORM-1330). - const LLSD& sky_map = mNewRegionSettings.getSkyMap(); - bool region_use_fixed_sky = sky_map.size() == 1; - if (region_use_fixed_sky) - { - LLWLParamSet param_set; - llassert(sky_map.isMap()); - param_set.setAll(sky_map.beginMap()->second); - F32 sun_angle = param_set.getSunAngle(); - - LL_DEBUGS("Windlight Sync") << "Old sun hour: " << region_info.mSunHour << LL_ENDL; - // convert value range from 0..2pi to 6..30 - region_info.mSunHour = fmodf((sun_angle / F_TWO_PI) * 24.f, 24.f) + 6.f; - } - - region_info.setUseFixedSun(region_use_fixed_sky); - region_info.mUseEstateSun = !region_use_fixed_sky; - LL_DEBUGS("Windlight Sync") << "Sun hour: " << region_info.mSunHour << LL_ENDL; - - region_info.sendRegionTerrain(LLFloaterRegionInfo::getLastInvoice()); -} - -void LLPanelEnvironmentInfo::fixEstateSun() -{ - // We don't support fixed sun estates anymore and need to fix - // such estates for region day cycle to take effect. - // *NOTE: Assuming that current estate settings have arrived already. - LLEstateInfoModel& estate_info = LLEstateInfoModel::instance(); - if (estate_info.getUseFixedSun()) - { - LL_INFOS() << "Switching estate to global sun" << LL_ENDL; - estate_info.setUseFixedSun(false); - estate_info.sendEstateInfo(); - } -} - -void LLPanelEnvironmentInfo::populateWaterPresetsList() -{ - mWaterPresetCombo->removeall(); - - // If the region already has water params, add them to the list. - const LLEnvironmentSettings& region_settings = LLEnvManagerNew::instance().getRegionSettings(); - if (region_settings.getWaterParams().size() != 0) - { - const std::string& region_name = gAgent.getRegion()->getName(); - mWaterPresetCombo->add(region_name, LLWLParamKey(region_name, LLEnvKey::SCOPE_REGION).toLLSD()); - mWaterPresetCombo->addSeparator(); - } - - std::list<std::string> user_presets, system_presets; - LLWaterParamManager::instance().getPresetNames(user_presets, system_presets); - - // Add local user presets first. - for (std::list<std::string>::const_iterator it = user_presets.begin(); it != user_presets.end(); ++it) - { - mWaterPresetCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toLLSD()); - } - - if (user_presets.size() > 0) - { - mWaterPresetCombo->addSeparator(); - } - - // Add local system presets. - for (std::list<std::string>::const_iterator it = system_presets.begin(); it != system_presets.end(); ++it) - { - mWaterPresetCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toLLSD()); - } - - // There's no way to select current preset because its name is not stored on server. -} - -void LLPanelEnvironmentInfo::populateSkyPresetsList() -{ - mSkyPresetCombo->removeall(); - - LLWLParamManager::preset_name_list_t region_presets; - LLWLParamManager::preset_name_list_t user_presets, sys_presets; - LLWLParamManager::instance().getPresetNames(region_presets, user_presets, sys_presets); - - // Add region presets. - std::string region_name = gAgent.getRegion() ? gAgent.getRegion()->getName() : LLTrans::getString("Unknown"); - for (LLWLParamManager::preset_name_list_t::const_iterator it = region_presets.begin(); it != region_presets.end(); ++it) - { - std::string preset_name = *it; - std::string item_title = preset_name + " (" + region_name + ")"; - mSkyPresetCombo->add(item_title, LLWLParamKey(preset_name, LLEnvKey::SCOPE_REGION).toStringVal()); - } - - if (!region_presets.empty()) - { - mSkyPresetCombo->addSeparator(); - } - - // Add user presets. - for (LLWLParamManager::preset_name_list_t::const_iterator it = user_presets.begin(); it != user_presets.end(); ++it) - { - mSkyPresetCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toStringVal()); - } - - if (!user_presets.empty()) - { - mSkyPresetCombo->addSeparator(); - } - - // Add system presets. - for (LLWLParamManager::preset_name_list_t::const_iterator it = sys_presets.begin(); it != sys_presets.end(); ++it) - { - mSkyPresetCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toStringVal()); - } - - // Select current preset. - LLSD sky_map = LLEnvManagerNew::instance().getRegionSettings().getSkyMap(); - if (sky_map.size() == 1) // if the region is set to fixed sky - { - std::string preset_name = sky_map.beginMap()->first; - mSkyPresetCombo->selectByValue(LLWLParamKey(preset_name, LLEnvKey::SCOPE_REGION).toStringVal()); - } -} - -void LLPanelEnvironmentInfo::populateDayCyclesList() -{ - mDayCyclePresetCombo->removeall(); - - // If the region already has env. settings, add its day cycle to the list. - const LLSD& cur_region_dc = LLEnvManagerNew::instance().getRegionSettings().getWLDayCycle(); - if (cur_region_dc.size() != 0) - { - LLViewerRegion* region = gAgent.getRegion(); - llassert(region != NULL); - - LLWLParamKey key(region->getName(), LLEnvKey::SCOPE_REGION); - mDayCyclePresetCombo->add(region->getName(), key.toStringVal()); - mDayCyclePresetCombo->addSeparator(); - } - - // Add local user day cycles. - LLDayCycleManager::preset_name_list_t user_days, sys_days; - LLDayCycleManager::instance().getPresetNames(user_days, sys_days); - for (LLDayCycleManager::preset_name_list_t::const_iterator it = user_days.begin(); it != user_days.end(); ++it) - { - mDayCyclePresetCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toStringVal()); - } - - if (user_days.size() > 0) - { - mDayCyclePresetCombo->addSeparator(); - } - - // Add local system day cycles. - for (LLDayCycleManager::preset_name_list_t::const_iterator it = sys_days.begin(); it != sys_days.end(); ++it) - { - mDayCyclePresetCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toStringVal()); - } - - // Current day cycle is already selected. -} - -bool LLPanelEnvironmentInfo::getSelectedWaterParams(LLSD& water_params) -{ - LLWLParamKey water_key(mWaterPresetCombo->getSelectedValue()); - - if (water_key.scope == LLEnvKey::SCOPE_REGION) - { - water_params = LLEnvManagerNew::instance().getRegionSettings().getWaterParams(); - } - else - { - LLWaterParamSet param_set; - if (!LLWaterParamManager::instance().getParamSet(water_key.name, param_set)) - { - LL_WARNS() << "Error getting water preset: " << water_key.name << LL_ENDL; - return false; - } - - water_params = param_set.getAll(); - } - - return true; -} - -bool LLPanelEnvironmentInfo::getSelectedSkyParams(LLSD& sky_params, std::string& preset_name) -{ - std::string preset_key(mSkyPresetCombo->getValue().asString()); - LLWLParamKey preset(preset_key); - - // Get the preset sky params. - LLWLParamSet param_set; - if (!LLWLParamManager::instance().getParamSet(preset, param_set)) - { - LL_WARNS() << "Error getting sky params: " << preset.toLLSD() << LL_ENDL; - return false; - } - - sky_params = param_set.getAll(); - preset_name = preset.name; - return true; -} - -bool LLPanelEnvironmentInfo::getSelectedDayCycleParams(LLSD& day_cycle, LLSD& sky_map, short& scope) -{ - std::string preset_key(mDayCyclePresetCombo->getValue().asString()); - LLWLParamKey dc(preset_key); - LL_DEBUGS("Windlight") << "Use day cycle: " << dc.toLLSD() << LL_ENDL; - - if (dc.scope == LLEnvKey::SCOPE_REGION) // current region day cycle - { - const LLEnvironmentSettings& cur_region_settings = LLEnvManagerNew::instance().getRegionSettings(); - day_cycle = cur_region_settings.getWLDayCycle(); - sky_map = cur_region_settings.getSkyMap(); - } - else // a local day cycle - { - if (!LLDayCycleManager::instance().getPreset(dc.name, day_cycle)) - { - LL_WARNS() << "Error getting day cycle " << dc.name << LL_ENDL; - return false; - } - - // Create sky map from the day cycle. - { - LLWLDayCycle tmp_day; - tmp_day.loadDayCycle(day_cycle, dc.scope); - tmp_day.getSkyMap(sky_map); - } - } - - scope = dc.scope; - - return true; -} -void LLPanelEnvironmentInfo::onSwitchRegionSettings() -{ - bool use_defaults = mRegionSettingsRadioGroup->getSelectedIndex() == 0; - getChild<LLView>("user_environment_settings")->setEnabled(!use_defaults); - - if (use_defaults) - { - LLEnvManagerNew::instance().useDefaults(); - } - else - { - onSelectWaterPreset(); - onSwitchDayCycle(); - } - - setDirty(true); -} - -void LLPanelEnvironmentInfo::onSwitchDayCycle() -{ - bool is_fixed_sky = mDayCycleSettingsRadioGroup->getSelectedIndex() == 0; - - mSkyPresetCombo->setEnabled(is_fixed_sky); - mDayCyclePresetCombo->setEnabled(!is_fixed_sky); - - if (is_fixed_sky) - { - onSelectSkyPreset(); - } - else - { - onSelectDayCycle(); - } - - setDirty(true); -} - -void LLPanelEnvironmentInfo::onSelectWaterPreset() -{ - LLSD water_params; - - if (getSelectedWaterParams(water_params)) - { - LLEnvManagerNew::instance().useWaterParams(water_params); - } - - setDirty(true); -} - -void LLPanelEnvironmentInfo::onSelectSkyPreset() -{ - LLSD params; - std::string dummy; - - if (getSelectedSkyParams(params, dummy)) - { - LLEnvManagerNew::instance().useSkyParams(params); - } - - setDirty(true); -} - -void LLPanelEnvironmentInfo::onSelectDayCycle() -{ - LLSD day_cycle; - LLSD sky_map; // unused - short scope; - - if (getSelectedDayCycleParams(day_cycle, sky_map, scope)) - { - LLEnvManagerNew::instance().useDayCycleParams(day_cycle, (LLEnvKey::EScope) scope); - } - - setDirty(true); -} - -void LLPanelEnvironmentInfo::onBtnApply() -{ - const bool use_defaults = mRegionSettingsRadioGroup->getSelectedIndex() == 0; - const bool use_fixed_sky = mDayCycleSettingsRadioGroup->getSelectedIndex() == 0; - - LLSD day_cycle; - LLSD sky_map; - LLSD water_params; - - if (use_defaults) - { - // settings will be empty - LL_DEBUGS("Windlight") << "Defaults" << LL_ENDL; - } - else // use custom region settings - { - if (use_fixed_sky) - { - LL_DEBUGS("Windlight") << "Use fixed sky" << LL_ENDL; - - // Get selected sky params. - LLSD params; - std::string preset_name; - if (!getSelectedSkyParams(params, preset_name)) - { - return; - } - - // Create a day cycle consisting of a single sky preset. - LLSD key(LLSD::emptyArray()); - key.append(-1.0f); // indicate that user preference is actually fixed sky, not a day cycle - key.append(preset_name); - day_cycle.append(key); - - // Create a sky map consisting of only the sky preset. - std::map<LLWLParamKey, LLWLParamSet> refs; - LLWLParamSet param_set; - param_set.setAll(params); - refs[LLWLParamKey(preset_name, LLEnvKey::SCOPE_LOCAL)] = param_set; // scope doesn't matter here - sky_map = LLWLParamManager::createSkyMap(refs); - } - else // use day cycle - { - LL_DEBUGS("Windlight") << "Use day cycle" << LL_ENDL; - - short scope; // unused - if (!getSelectedDayCycleParams(day_cycle, sky_map, scope)) - { - return; - } - - // If it's a special single-preset day cycle meaning using a fixed sky, - // reset the frame time to a non-negative value, - // so that the region setting is displayed in the floater as - // a day cycle, not a preset. (STORM-1289) - if (day_cycle.size() == 1 && day_cycle[0][0].asReal() < 0.0f) - { - LL_DEBUGS("Windlight") << "Fixing negative time" << LL_ENDL; - day_cycle[0][0] = 0.0f; - } - } - - // Get water params. - if (!getSelectedWaterParams(water_params)) - { - // *TODO: show a notification? - return; - } - } - - // Send settings apply request. - LLEnvironmentSettings new_region_settings; - new_region_settings.saveParams(day_cycle, sky_map, water_params, 0.0f); - if (!LLEnvManagerNew::instance().sendRegionSettings(new_region_settings)) - { - LL_WARNS() << "Error applying region environment settings" << LL_ENDL; - return; - } - - // When the settings get applied, we'll also send the region sun position update. - // To determine the sun angle we're going to need the new settings. - mNewRegionSettings = new_region_settings; - - // Start spinning the progress indicator. - setApplyProgress(true); -} - -void LLPanelEnvironmentInfo::onBtnCancel() -{ - // Reload last saved region settings. - refresh(); - - // Apply them. - LLEnvManagerNew& env_mgr = LLEnvManagerNew::instance(); - const LLEnvironmentSettings& cur_settings = env_mgr.getRegionSettings(); - const LLSD& region_day_cycle = cur_settings.getWLDayCycle(); - const LLSD& region_water = cur_settings.getWaterParams(); - env_mgr.useWaterParams(region_water); - env_mgr.useDayCycleParams(region_day_cycle, LLEnvKey::SCOPE_REGION); -} - -void LLPanelEnvironmentInfo::onRegionSettingschange() -{ - LL_DEBUGS("Windlight") << "Region settings changed, refreshing" << LL_ENDL; - refresh(); - - // Stop applying progress indicator (it may be running if it's us who initiated settings update). - setApplyProgress(false); -} - -void LLPanelEnvironmentInfo::onRegionSettingsApplied(bool ok) -{ - // If applying new settings has failed, stop the indicator right away. - // Otherwise it will be stopped when we receive the updated settings from server. - if (ok) - { - // Set the region sun phase/flags according to the chosen new preferences. - // - // If we do this earlier we may get jerky transition from fixed sky to a day cycle (STORM-1481). - // That is caused by the simulator re-sending the region info, which in turn makes us - // re-request and display old region environment settings while the new ones haven't been applied yet. - sendRegionSunUpdate(); - - // Switch estate to not using fixed sun for the region day cycle to work properly (STORM-1506). - fixEstateSun(); - } - else - { - setApplyProgress(false); - - // We need to re-request environment setting here, - // otherwise our subsequent attempts to change region settings will fail with the following error: - // "Unable to update environment settings because the last update your viewer saw was not the same - // as the last update sent from the simulator. Try sending your update again, and if this - // does not work, try leaving and returning to the region." - LLEnvManagerNew::instance().requestRegionSettings(); - } -} - BOOL LLPanelRegionExperiences::postBuild() { mAllowed = setupList("panel_allowed", ESTATE_EXPERIENCE_ALLOWED_ADD, ESTATE_EXPERIENCE_ALLOWED_REMOVE); @@ -3942,3 +3364,86 @@ void LLPanelRegionExperiences::itemChanged( U32 event_type, const LLUUID& id ) onChangeAnything(); } + +//========================================================================= +LLPanelRegionEnvironment::LLPanelRegionEnvironment(): + LLPanelEnvironmentInfo(), + mLastRegion(NULL) +{ +} + + +BOOL LLPanelRegionEnvironment::postBuild() +{ + if (!LLPanelEnvironmentInfo::postBuild()) + return FALSE; + + return TRUE; +} + + +void LLPanelRegionEnvironment::refresh() +{ + refreshFromRegion(mLastRegion); +} + +bool LLPanelRegionEnvironment::refreshFromRegion(LLViewerRegion* region) +{ + BOOL owner_or_god = gAgent.isGodlike() || (region && (region->getOwner() == gAgent.getID())); + BOOL owner_or_god_or_manager = owner_or_god || (region && region->isEstateManager()); + + F64Hours daylength; + F64Hours dayoffset; + + daylength = LLEnvironment::instance().getEnvironmentDayLength(LLEnvironment::ENV_REGION); + dayoffset = LLEnvironment::instance().getEnvironmentDayOffset(LLEnvironment::ENV_REGION); + + if (dayoffset.value() > 12.0) + dayoffset = dayoffset - F64Hours(24.0f); + + mDayLengthSlider->setValue(daylength.value()); + mDayOffsetSlider->setValue(dayoffset.value()); + + //mRegionSettingsRadioGroup->setSelectedIndex(region->getIsDefaultDayCycle() ? 0 : 1); + mRegionSettingsRadioGroup->setSelectedIndex(1); + + setControlsEnabled(owner_or_god_or_manager); + mLastRegion = region; + + LLSettingsDay::ptr_t pday = LLEnvironment::instance().getEnvironmentDay(LLEnvironment::ENV_REGION); + + if (pday) + mEditingDayCycle = pday->buildClone(); + + return true; +} + +void LLPanelRegionEnvironment::doApply() +{ + if (mRegionSettingsRadioGroup->getSelectedIndex() == 0) + { + LLEnvironment::instance().resetRegion(); + } + else + { + S64Seconds daylength; + F32Hours dayoffset_h; + + daylength = F32Hours(mDayLengthSlider->getValueF32()); + dayoffset_h = F32Hours(mDayOffsetSlider->getValueF32()); + + if (dayoffset_h.value() < 0) + { + dayoffset_h = F32Hours(24.0f) + dayoffset_h; + } + + S64Seconds dayoffset_s = dayoffset_h; + + LLEnvironment::instance().updateRegion(mEditingDayCycle, daylength.value(), dayoffset_s.value()); + } +} + +void LLPanelRegionEnvironment::doEditCommited(LLSettingsDay::ptr_t &newday) +{ + mEditingDayCycle = newday; +} diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index c9d0e51640..6d64ae1d60 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -34,8 +34,8 @@ #include "llhost.h" #include "llpanel.h" #include "llextendedstatus.h" +#include "llpanelenvironment.h" -#include "llenvmanager.h" // for LLEnvironmentSettings #include "lleventcoro.h" class LLAvatarName; @@ -64,13 +64,9 @@ class LLPanelEstateCovenant; class LLPanelExperienceListEditor; class LLPanelExperiences; class LLPanelRegionExperiences; +class LLPanelRegionEnvironment; class LLEventTimer; -class LLEnvironmentSettings; -class LLWLParamManager; -class LLWaterParamManager; -class LLWLParamSet; -class LLWaterParamSet; class LLFloaterRegionInfo : public LLFloater { @@ -121,6 +117,7 @@ protected: LLTabContainer* mTab; typedef std::vector<LLPanelRegionInfo*> info_panels_t; info_panels_t mInfoPanels; + LLPanelRegionEnvironment *mEnvironmentPanel; //static S32 sRequestSerial; // serial # of last EstateOwnerRequest static LLUUID sRequestInvoice; }; @@ -415,69 +412,10 @@ protected: ///////////////////////////////////////////////////////////////////////////// -class LLPanelEnvironmentInfo : public LLPanelRegionInfo -{ - LOG_CLASS(LLPanelEnvironmentInfo); - -public: - LLPanelEnvironmentInfo(); - - // LLPanel - /*virtual*/ BOOL postBuild(); - /*virtual*/ void onOpen(const LLSD& key); - - // LLView - /*virtual*/ void onVisibilityChange(BOOL new_visibility); - - // LLPanelRegionInfo - /*virtual*/ bool refreshFromRegion(LLViewerRegion* region); - -private: - void refresh(); - void setControlsEnabled(bool enabled); - void setApplyProgress(bool started); - void setDirty(bool dirty); - - void sendRegionSunUpdate(); - void fixEstateSun(); - - void populateWaterPresetsList(); - void populateSkyPresetsList(); - void populateDayCyclesList(); - - bool getSelectedWaterParams(LLSD& water_params); - bool getSelectedSkyParams(LLSD& sky_params, std::string& preset_name); - bool getSelectedDayCycleParams(LLSD& day_cycle, LLSD& sky_map, short& scope); - - void onSwitchRegionSettings(); - void onSwitchDayCycle(); - - void onSelectWaterPreset(); - void onSelectSkyPreset(); - void onSelectDayCycle(); - - void onBtnApply(); - void onBtnCancel(); - - void onRegionSettingschange(); - void onRegionSettingsApplied(bool ok); - - /// New environment settings that are being applied to the region. - LLEnvironmentSettings mNewRegionSettings; - - bool mEnableEditing; - - LLRadioGroup* mRegionSettingsRadioGroup; - LLRadioGroup* mDayCycleSettingsRadioGroup; - - LLComboBox* mWaterPresetCombo; - LLComboBox* mSkyPresetCombo; - LLComboBox* mDayCyclePresetCombo; -}; class LLPanelRegionExperiences : public LLPanelRegionInfo { - LOG_CLASS(LLPanelEnvironmentInfo); + LOG_CLASS(LLPanelRegionExperiences); public: LLPanelRegionExperiences(){} diff --git a/indra/newview/llflyoutcombobtn.cpp b/indra/newview/llflyoutcombobtn.cpp new file mode 100644 index 0000000000..a736fcafa3 --- /dev/null +++ b/indra/newview/llflyoutcombobtn.cpp @@ -0,0 +1,127 @@ +/** + * @file llflyoutcombobtn.cpp + * @brief Represents outfit save/save as combo button. + * + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, 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 "llflyoutcombobtn.h" +#include "llviewermenu.h" + +LLFlyoutComboBtnCtrl::LLFlyoutComboBtnCtrl(LLPanel* parent, const std::string &action_button, const std::string &flyout_button, const std::string &menu_file) : + mParent(parent), + mActionButton(action_button), + mFlyoutButton(flyout_button) +{ + // register action mapping before creating menu + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar save_registar; + save_registar.add("FlyoutCombo.Button.Action", [this](LLUICtrl *ctrl, const LLSD &data) { onFlyoutItemSelected(ctrl, data); }); + + mParent->childSetAction(flyout_button, [this](LLUICtrl *ctrl, const LLSD &data) { onFlyoutButton(ctrl, data); }); + mParent->childSetAction(action_button, [this](LLUICtrl *ctrl, const LLSD &data) { onFlyoutAction(ctrl, data); }); + + mFlyoutMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu> (menu_file, gMenuHolder, + LLViewerMenuHolderGL::child_registry_t::instance()); + + // select the first item in the list. + setSelectedItem(0); +} + +void LLFlyoutComboBtnCtrl::setAction(LLUICtrl::commit_callback_t cb) +{ + mActionSignal.connect(cb); +} + + +U32 LLFlyoutComboBtnCtrl::getItemCount() +{ + return mFlyoutMenu->getItemCount(); +} + +void LLFlyoutComboBtnCtrl::setSelectedItem(S32 itemno) +{ + LLMenuItemGL *pitem = mFlyoutMenu->getItem(itemno); + setSelectedItem(pitem); +} + +void LLFlyoutComboBtnCtrl::setSelectedItem(const std::string &item) +{ + LLMenuItemGL *pitem = mFlyoutMenu->getChild<LLMenuItemGL>(item, false); + setSelectedItem(pitem); +} + +void LLFlyoutComboBtnCtrl::setSelectedItem(LLMenuItemGL *pitem) +{ + if (!pitem) + { + LL_WARNS("INTERFACE") << "NULL item selected" << LL_ENDL; + return; + } + + mSelectedName = pitem->getName(); + + LLButton *action_button = mParent->getChild<LLButton>(mActionButton); + action_button->setEnabled(pitem->getEnabled()); + action_button->setLabel(pitem->getLabel()); +} + +void LLFlyoutComboBtnCtrl::setMenuItemEnabled(const std::string& item, bool enabled) +{ + mFlyoutMenu->setItemEnabled(item, enabled); + if (item == mSelectedName) + { + mParent->getChildView(mActionButton)->setEnabled(enabled); + } +} + +void LLFlyoutComboBtnCtrl::setShownBtnEnabled(bool enabled) +{ + mParent->getChildView(mActionButton)->setEnabled(enabled); +} + +void LLFlyoutComboBtnCtrl::onFlyoutButton(LLUICtrl *ctrl, const LLSD &data) +{ + S32 x, y; + LLUI::getMousePositionLocal(mParent, &x, &y); + + mFlyoutMenu->updateParent(LLMenuGL::sMenuContainer); + LLMenuGL::showPopup(mParent, mFlyoutMenu, x, y); +} + +void LLFlyoutComboBtnCtrl::onFlyoutItemSelected(LLUICtrl *ctrl, const LLSD &data) +{ + LLMenuItemGL *pmenuitem = static_cast<LLMenuItemGL*>(ctrl); + setSelectedItem(pmenuitem); + + onFlyoutAction(pmenuitem, data); +} + +void LLFlyoutComboBtnCtrl::onFlyoutAction(LLUICtrl *ctrl, const LLSD &data) +{ + LLMenuItemGL *pmenuitem = mFlyoutMenu->getChild<LLMenuItemGL>(mSelectedName); + + if (!mActionSignal.empty()) + mActionSignal(pmenuitem, data); +} + diff --git a/indra/newview/llflyoutcombobtn.h b/indra/newview/llflyoutcombobtn.h new file mode 100644 index 0000000000..517752d8db --- /dev/null +++ b/indra/newview/llflyoutcombobtn.h @@ -0,0 +1,68 @@ +/** + * @file llsaveoutfitcombobtn.h + * @brief Represents outfit save/save as combo button. + * + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, 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_LLFLYOUTCOMBOBTN_H +#define LL_LLFLYOUTCOMBOBTN_H + +/*TODO: Make this button generic */ + +class LLButton; + +#include "lltoggleablemenu.h" + +class LLFlyoutComboBtnCtrl +{ + LOG_CLASS(LLFlyoutComboBtnCtrl); +public: + LLFlyoutComboBtnCtrl(LLPanel* parent, const std::string &action_button, const std::string &flyout_button, const std::string &menu_file); + + void setMenuItemEnabled(const std::string &item, bool enabled); + void setShownBtnEnabled(bool enabled); + + U32 getItemCount(); + void setSelectedItem(S32 itemno); + void setSelectedItem(const std::string &item); + + void setAction(LLUICtrl::commit_callback_t cb); + +protected: + void onFlyoutButton(LLUICtrl *, const LLSD &); + void onFlyoutItemSelected(LLUICtrl *, const LLSD &); + void onFlyoutAction(LLUICtrl *, const LLSD &); + + void setSelectedItem(LLMenuItemGL *pitem); + +private: + LLPanel * mParent; + LLToggleableMenu * mFlyoutMenu; + std::string mActionButton; + std::string mFlyoutButton; + + std::string mSelectedName; + + LLUICtrl::commit_signal_t mActionSignal; +}; +#endif // LL_LLFLYOUTCOMBOBTN_H 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/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 67b51f11b3..2b74116f8b 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -82,6 +82,8 @@ #include "lllandmarkactions.h" #include "llpanellandmarks.h" +#include "llenvironment.h" + #include <boost/shared_ptr.hpp> void copy_slurl_to_clipboard_callback_inv(const std::string& slurl); @@ -1411,6 +1413,14 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type, //LL_WARNS() << LLAssetType::lookup(asset_type) << " asset type is unhandled for uuid " << uuid << LL_ENDL; break; + case LLAssetType::AT_SETTINGS: + if (inv_type != LLInventoryType::IT_SETTINGS) + { + LL_WARNS() << LLAssetType::lookup(asset_type) << " asset has inventory type " << LLInventoryType::lookupHumanReadable(inv_type) << " on uuid " << uuid << LL_ENDL; + } + new_listener = new LLSettingsBridge(inventory, root, uuid, LLSettingsType::fromInventoryFlags(flags)); + break; + default: LL_INFOS() << "Unhandled asset type (llassetstorage.h): " << (S32)asset_type << " (" << LLAssetType::lookup(asset_type) << ")" << LL_ENDL; @@ -4021,10 +4031,18 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items items.push_back(std::string("New Gesture")); items.push_back(std::string("New Clothes")); items.push_back(std::string("New Body Parts")); + items.push_back(std::string("New Settings")); items.push_back(std::string("upload_def")); + + if (!LLEnvironment::instance().isInventoryEnabled()) + { + disabled_items.push_back("New Settings"); + } + } } getClipboardEntries(false, items, disabled_items, flags); + } else { @@ -6865,6 +6883,52 @@ void LLMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags) hide_context_entries(menu, items, disabled_items); } +// +=================================================+ +// | LLSettingsBridge | +// +=================================================+ + +LLSettingsBridge::LLSettingsBridge(LLInventoryPanel* inventory, + LLFolderView* root, + const LLUUID& uuid, + LLSettingsType::type_e settings_type): + LLItemBridge(inventory, root, uuid), + mSettingsType(settings_type) +{ +} + +LLUIImagePtr LLSettingsBridge::getIcon() const +{ + return LLInventoryIcon::getIcon(LLAssetType::AT_SETTINGS, LLInventoryType::IT_SETTINGS, mSettingsType, FALSE); +} + +void LLSettingsBridge::performAction(LLInventoryModel* model, std::string action) +{ + LLItemBridge::performAction(model, action); +} + +void LLSettingsBridge::openItem() +{ + LLViewerInventoryItem* item = getItem(); + if (item) + { + LLInvFVBridgeAction::doAction(item->getType(), mUUID, getInventoryModel()); + } +} + +void LLSettingsBridge::buildContextMenu(LLMenuGL& menu, U32 flags) +{ + LLItemBridge::buildContextMenu(menu, flags); +} + +std::string LLSettingsBridge::getLabelSuffix() const +{ + return LLItemBridge::getLabelSuffix(); +} + +BOOL LLSettingsBridge::renameItem(const std::string& new_name) +{ + return LLItemBridge::renameItem(new_name); +} // +=================================================+ // | LLLinkBridge | @@ -7209,6 +7273,40 @@ void LLWearableBridgeAction::wearOnAvatar() } } +class LLSettingsBridgeAction + : public LLInvFVBridgeAction +{ + friend class LLInvFVBridgeAction; +public: + virtual void doIt() + { + LLViewerInventoryItem* item = getItem(); + if (item) + { + LLSettingsType::type_e type = item->getSettingsType(); + switch (type) + { + case LLSettingsType::ST_SKY: + LLFloaterReg::showInstance("env_fixed_environmentent_sky", LLSDMap("inventory_id", item->getUUID()), TAKE_FOCUS_YES); + break; + case LLSettingsType::ST_WATER: + LLFloaterReg::showInstance("env_fixed_environmentent_water", LLSDMap("inventory_id", item->getUUID()), TAKE_FOCUS_YES); + break; + case LLSettingsType::ST_DAYCYCLE: + LLFloaterReg::showInstance("env_edit_extdaycycle", LLSDMap("inventory_id", item->getUUID()), TAKE_FOCUS_YES); + break; + default: + break; + } + } + LLInvFVBridgeAction::doIt(); + } + virtual ~LLSettingsBridgeAction(){} +protected: + LLSettingsBridgeAction(const LLUUID& id, LLInventoryModel* model) : LLInvFVBridgeAction(id, model) {} +}; + + LLInvFVBridgeAction* LLInvFVBridgeAction::createAction(LLAssetType::EType asset_type, const LLUUID& uuid, LLInventoryModel* model) @@ -7247,6 +7345,9 @@ LLInvFVBridgeAction* LLInvFVBridgeAction::createAction(LLAssetType::EType asset_ case LLAssetType::AT_BODYPART: action = new LLWearableBridgeAction(uuid,model); break; + case LLAssetType::AT_SETTINGS: + action = new LLSettingsBridgeAction(uuid, model); + break; default: break; } diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index fd5c0433b1..e7df5e4e93 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -38,6 +38,7 @@ #include "lltooldraganddrop.h" #include "lllandmarklist.h" #include "llfolderviewitem.h" +#include "llsettingsbase.h" class LLInventoryFilter; class LLInventoryPanel; @@ -136,6 +137,7 @@ public: std::string& tooltip_msg) { return FALSE; } virtual LLInventoryType::EType getInventoryType() const { return mInvType; } virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_NONE; } + virtual LLSettingsType::type_e getSettingsType() const { return LLSettingsType::ST_NONE; } EInventorySortGroup getSortGroup() const { return SG_ITEM; } virtual LLInventoryObject* getInventoryObject() const; @@ -609,6 +611,26 @@ protected: }; +class LLSettingsBridge : public LLItemBridge +{ +public: + LLSettingsBridge(LLInventoryPanel* inventory, + LLFolderView* root, + const LLUUID& uuid, + LLSettingsType::type_e settings_type); + virtual LLUIImagePtr getIcon() const; + virtual void performAction(LLInventoryModel* model, std::string action); + virtual void openItem(); + virtual void buildContextMenu(LLMenuGL& menu, U32 flags); + virtual std::string getLabelSuffix() const; + virtual BOOL renameItem(const std::string& new_name); + virtual LLSettingsType::type_e getSettingsType() const { return mSettingsType; } + + +protected: + LLSettingsType::type_e mSettingsType; +}; + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLInvFVBridgeAction // diff --git a/indra/newview/llinventoryicon.cpp b/indra/newview/llinventoryicon.cpp index 495180f087..106e5fd415 100644 --- a/indra/newview/llinventoryicon.cpp +++ b/indra/newview/llinventoryicon.cpp @@ -34,6 +34,7 @@ #include "llui.h" #include "lluiimage.h" #include "llwearabletype.h" +#include "llinventorysettings.h" struct IconEntry : public LLDictionaryEntry { @@ -92,6 +93,11 @@ LLIconDictionary::LLIconDictionary() addEntry(LLInventoryType::ICONNAME_LINKFOLDER, new IconEntry("Inv_LinkFolder")); addEntry(LLInventoryType::ICONNAME_MESH, new IconEntry("Inv_Mesh")); + addEntry(LLInventoryType::ICONNAME_SETTINGS_SKY, new IconEntry("Inv_SettingsSky")); + addEntry(LLInventoryType::ICONNAME_SETTINGS_WATER, new IconEntry("Inv_SettingsWater")); + addEntry(LLInventoryType::ICONNAME_SETTINGS_DAY, new IconEntry("Inv_SettingsDay")); + addEntry(LLInventoryType::ICONNAME_SETTINGS, new IconEntry("Inv_Settings")); + addEntry(LLInventoryType::ICONNAME_INVALID, new IconEntry("Inv_Invalid")); addEntry(LLInventoryType::ICONNAME_NONE, new IconEntry("NONE")); @@ -166,6 +172,11 @@ const std::string& LLInventoryIcon::getIconName(LLAssetType::EType asset_type, break; case LLAssetType::AT_MESH: idx = LLInventoryType::ICONNAME_MESH; + break; + case LLAssetType::AT_SETTINGS: + // TODO: distinguish between Sky and Water settings. + idx = assignSettingsIcon(misc_flag); + break; default: break; } @@ -185,3 +196,9 @@ LLInventoryType::EIconName LLInventoryIcon::assignWearableIcon(U32 misc_flag) const LLWearableType::EType wearable_type = LLWearableType::inventoryFlagsToWearableType(misc_flag); return LLWearableType::getIconName(wearable_type); } + +LLInventoryType::EIconName LLInventoryIcon::assignSettingsIcon(U32 misc_flag) +{ + LLSettingsType::type_e settings_type = LLSettingsType::fromInventoryFlags(misc_flag); + return LLSettingsType::getIconName(settings_type); +} diff --git a/indra/newview/llinventoryicon.h b/indra/newview/llinventoryicon.h index bc09e32087..b8637c4e33 100644 --- a/indra/newview/llinventoryicon.h +++ b/indra/newview/llinventoryicon.h @@ -48,6 +48,7 @@ public: protected: static LLInventoryType::EIconName assignWearableIcon(U32 misc_flag); + static LLInventoryType::EIconName assignSettingsIcon(U32 misc_flag); }; #endif // LL_LLINVENTORYICON_H diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 556af93963..678fdbef35 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -1811,7 +1811,7 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item) // For example, there is a known backwards compatibility issue in some viewer prototypes prior to when // the AT_LINK enum changed from 23 to 24. if ((item->getType() == LLAssetType::AT_NONE) - || LLAssetType::lookup(item->getType()) == LLAssetType::badLookup()) + || LLAssetType::lookup(item->getType()) == LLAssetType::BADLOOKUP) { LL_WARNS(LOG_INV) << "Got bad asset type for item [ name: " << item->getName() << " type: " << item->getType() diff --git a/indra/newview/lljoystickbutton.cpp b/indra/newview/lljoystickbutton.cpp index 59e14e6cc0..7fcd6f4361 100644 --- a/indra/newview/lljoystickbutton.cpp +++ b/indra/newview/lljoystickbutton.cpp @@ -48,7 +48,7 @@ static LLDefaultChildRegistry::Register<LLJoystickAgentSlide> r1("joystick_slide static LLDefaultChildRegistry::Register<LLJoystickAgentTurn> r2("joystick_turn"); static LLDefaultChildRegistry::Register<LLJoystickCameraRotate> r3("joystick_rotate"); static LLDefaultChildRegistry::Register<LLJoystickCameraTrack> r5("joystick_track"); - +static LLDefaultChildRegistry::Register<LLJoystickQuaternion> r6("joystick_quat"); const F32 NUDGE_TIME = 0.25f; // in seconds @@ -646,3 +646,238 @@ void LLJoystickCameraTrack::onHeldDown() gAgentCamera.setPanDownKey(getOrbitRate()); } } + +//------------------------------------------------------------------------------- +// LLJoystickQuaternion +//------------------------------------------------------------------------------- + +LLJoystickQuaternion::Params::Params() +{ +} + +LLJoystickQuaternion::LLJoystickQuaternion(const LLJoystickQuaternion::Params &p): + LLJoystick(p), + mInLeft(false), + mInTop(false), + mInRight(false), + mInBottom(false), + mVectorZero(0.0f, 0.0f, 1.0f), + mRotation(), + mUpDnAxis(1.0f, 0.0f, 0.0f), + mLfRtAxis(0.0f, 0.0f, 1.0f), + mXAxisIndex(2), // left & right across the control + mYAxisIndex(0), // up & down across the control + mZAxisIndex(1) // tested for above and below +{ + for (int i = 0; i < 3; ++i) + { + mLfRtAxis.mV[i] = (mXAxisIndex == i) ? 1.0 : 0.0; + mUpDnAxis.mV[i] = (mYAxisIndex == i) ? 1.0 : 0.0; + } +} + +void LLJoystickQuaternion::setToggleState(BOOL left, BOOL top, BOOL right, BOOL bottom) +{ + mInLeft = left; + mInTop = top; + mInRight = right; + mInBottom = bottom; +} + +BOOL LLJoystickQuaternion::handleMouseDown(S32 x, S32 y, MASK mask) +{ + updateSlop(); + + // Set initial offset based on initial click location + S32 horiz_center = getRect().getWidth() / 2; + S32 vert_center = getRect().getHeight() / 2; + + S32 dx = x - horiz_center; + S32 dy = y - vert_center; + + if (dy > dx && dy > -dx) + { + // top + mInitialOffset.mX = 0; + mInitialOffset.mY = (mVertSlopNear + mVertSlopFar) / 2; + mInitialQuadrant = JQ_UP; + } + else if (dy > dx && dy <= -dx) + { + // left + mInitialOffset.mX = -(mHorizSlopNear + mHorizSlopFar) / 2; + mInitialOffset.mY = 0; + mInitialQuadrant = JQ_LEFT; + } + else if (dy <= dx && dy <= -dx) + { + // bottom + mInitialOffset.mX = 0; + mInitialOffset.mY = -(mVertSlopNear + mVertSlopFar) / 2; + mInitialQuadrant = JQ_DOWN; + } + else + { + // right + mInitialOffset.mX = (mHorizSlopNear + mHorizSlopFar) / 2; + mInitialOffset.mY = 0; + mInitialQuadrant = JQ_RIGHT; + } + + return LLJoystick::handleMouseDown(x, y, mask); +} + +BOOL LLJoystickQuaternion::handleMouseUp(S32 x, S32 y, MASK mask) +{ + return LLJoystick::handleMouseUp(x, y, mask); +} + +void LLJoystickQuaternion::onHeldDown() +{ + LLVector3 axis; + updateSlop(); + + S32 dx = mLastMouse.mX - mFirstMouse.mX + mInitialOffset.mX; + S32 dy = mLastMouse.mY - mFirstMouse.mY + mInitialOffset.mY; + + // left-right rotation + if (dx > mHorizSlopNear) + { + axis += mUpDnAxis; + } + else if (dx < -mHorizSlopNear) + { + axis -= mUpDnAxis; + } + + // over/under rotation + if (dy > mVertSlopNear) + { + axis += mLfRtAxis; + } + else if (dy < -mVertSlopNear) + { + axis -= mLfRtAxis; + } + + if (axis.isNull()) + return; + + axis.normalize(); + + LLQuaternion delta; + delta.setAngleAxis(0.0523599f, axis); // about 3deg + + mRotation *= delta; + setValue(mRotation.getValue()); + onCommit(); +} + +void LLJoystickQuaternion::draw() +{ + LLGLSUIDefault gls_ui; + + getImageUnselected()->draw(0, 0); + LLPointer<LLUIImage> image = getImageSelected(); + + if (mInTop) + { + drawRotatedImage(getImageSelected(), 0); + } + + if (mInRight) + { + drawRotatedImage(getImageSelected(), 1); + } + + if (mInBottom) + { + drawRotatedImage(getImageSelected(), 2); + } + + if (mInLeft) + { + drawRotatedImage(getImageSelected(), 3); + } + + LLVector3 draw_point = mVectorZero * mRotation; + S32 halfwidth = getRect().getWidth() / 2; + S32 halfheight = getRect().getHeight() / 2; + draw_point.mV[mXAxisIndex] = (draw_point.mV[mXAxisIndex] + 1.0) * halfwidth; + draw_point.mV[mYAxisIndex] = (draw_point.mV[mYAxisIndex] + 1.0) * halfheight; + + gl_circle_2d(draw_point.mV[mXAxisIndex], draw_point.mV[mYAxisIndex], 4, 8, + draw_point.mV[mZAxisIndex] >= 0.f); + +} + +F32 LLJoystickQuaternion::getOrbitRate() +{ + return 1; +} + +void LLJoystickQuaternion::updateSlop() +{ + // small fixed slop region + mVertSlopNear = 16; + mVertSlopFar = 32; + + mHorizSlopNear = 16; + mHorizSlopFar = 32; +} + +void LLJoystickQuaternion::drawRotatedImage(LLPointer<LLUIImage> image, S32 rotations) +{ + S32 width = image->getWidth(); + S32 height = image->getHeight(); + LLTexture* texture = image->getImage(); + + /* + * Scale texture coordinate system + * to handle the different between image size and size of texture. + */ + F32 uv[][2] = + { + { (F32)width / texture->getWidth(), (F32)height / texture->getHeight() }, + { 0.f, (F32)height / texture->getHeight() }, + { 0.f, 0.f }, + { (F32)width / texture->getWidth(), 0.f } + }; + + gGL.getTexUnit(0)->bind(texture); + + gGL.color4fv(UI_VERTEX_COLOR.mV); + + gGL.begin(LLRender::QUADS); + { + gGL.texCoord2fv(uv[(rotations + 0) % 4]); + gGL.vertex2i(width, height); + + gGL.texCoord2fv(uv[(rotations + 1) % 4]); + gGL.vertex2i(0, height); + + gGL.texCoord2fv(uv[(rotations + 2) % 4]); + gGL.vertex2i(0, 0); + + gGL.texCoord2fv(uv[(rotations + 3) % 4]); + gGL.vertex2i(width, 0); + } + gGL.end(); +} + +void LLJoystickQuaternion::setRotation(const LLQuaternion &value) +{ + if (value != mRotation) + { + mRotation = value; + mRotation.normalize(); + LLJoystick::setValue(mRotation.getValue()); + } +} + +LLQuaternion LLJoystickQuaternion::getRotation() const +{ + return mRotation; +} + + diff --git a/indra/newview/lljoystickbutton.h b/indra/newview/lljoystickbutton.h index 4e6c774cad..ee66088b56 100644 --- a/indra/newview/lljoystickbutton.h +++ b/indra/newview/lljoystickbutton.h @@ -30,6 +30,7 @@ #include "llbutton.h" #include "llcoord.h" #include "llviewertexture.h" +#include "llquaternion.h" typedef enum e_joystick_quadrant { @@ -178,4 +179,47 @@ public: virtual void onHeldDown(); }; +// +class LLJoystickQuaternion : + public LLJoystick +{ +public: + struct Params : + public LLInitParam::Block<Params, LLJoystick::Params> + { + Params(); + }; + + LLJoystickQuaternion(const LLJoystickQuaternion::Params &); + + virtual void setToggleState(BOOL left, BOOL top, BOOL right, BOOL bottom); + + virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); + virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); + virtual void onHeldDown(); + virtual void draw(); + + void setRotation(const LLQuaternion &value); + LLQuaternion getRotation() const; + +protected: + F32 getOrbitRate(); + virtual void updateSlop(); + void drawRotatedImage(LLPointer<LLUIImage> image, S32 rotations); + + BOOL mInLeft; + BOOL mInTop; + BOOL mInRight; + BOOL mInBottom; + + S32 mXAxisIndex; + S32 mYAxisIndex; + S32 mZAxisIndex; + + LLVector3 mVectorZero; + LLQuaternion mRotation; + LLVector3 mUpDnAxis; + LLVector3 mLfRtAxis; +}; + #endif // LL_LLJOYSTICKBUTTON_H 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/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp index 11bc1425f9..c01a2fbf8a 100644 --- a/indra/newview/lllocationinputctrl.cpp +++ b/indra/newview/lllocationinputctrl.cpp @@ -44,7 +44,6 @@ // newview includes #include "llagent.h" -#include "llenvmanager.h" #include "llfloatersidepanelcontainer.h" #include "llinventoryobserver.h" #include "lllandmarkactions.h" diff --git a/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp b/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp index 63d97f6ac2..0663dd41ee 100644 --- a/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp +++ b/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp @@ -34,7 +34,6 @@ #include <boost/signals2.hpp> #include "llagent.h" -#include "llenvmanager.h" #include "llnotificationsutil.h" #include "llpathfindingmanager.h" #include "llpathfindingnavmesh.h" diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 71a161198a..0a49e2647e 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -2552,7 +2552,7 @@ void LLMeshUploadThread::requestWholeModelFee() { ms_sleep(sleep_time); sleep_time = llmin(250U, sleep_time + sleep_time); - mHttpRequest->update(0); + mHttpRequest->update(0); } if (isDiscarded()) { diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp index dc3b153da2..28fb19f8b3 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/llpaneleditsky.cpp b/indra/newview/llpaneleditsky.cpp new file mode 100644 index 0000000000..e5c6116c4f --- /dev/null +++ b/indra/newview/llpaneleditsky.cpp @@ -0,0 +1,392 @@ +/** +* @file llpaneleditsky.cpp +* @brief Floaters to create and edit fixed settings for sky and water. +* +* $LicenseInfo:firstyear=2011&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2011, 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 "llpaneleditsky.h" + +#include "llslider.h" +#include "lltexturectrl.h" +#include "llcolorswatch.h" +#include "lljoystickbutton.h" + +namespace +{ + // Atmosphere Tab + const std::string FIELD_SKY_AMBIENT_LIGHT("ambient_light"); + const std::string FIELD_SKY_BLUE_HORIZON("blue_horizon"); + const std::string FIELD_SKY_BLUE_DENSITY("blue_density"); + const std::string FIELD_SKY_HAZE_HORIZON("haze_horizon"); + const std::string FIELD_SKY_HAZE_DENSITY("haze_density"); + const std::string FIELD_SKY_SCENE_GAMMA("scene_gamma"); + const std::string FIELD_SKY_DENSITY_MULTIP("density_multip"); + const std::string FIELD_SKY_DISTANCE_MULTIP("distance_multip"); + const std::string FIELD_SKY_MAX_ALT("max_alt"); + + const std::string FIELD_SKY_CLOUD_COLOR("cloud_color"); + const std::string FIELD_SKY_CLOUD_COVERAGE("cloud_coverage"); + const std::string FIELD_SKY_CLOUD_SCALE("cloud_scale"); + const std::string FIELD_SKY_CLOUD_SCROLL_X("cloud_scroll_x"); + const std::string FIELD_SKY_CLOUD_SCROLL_Y("cloud_scroll_y"); + const std::string FIELD_SKY_CLOUD_MAP("cloud_map"); + const std::string FIELD_SKY_CLOUD_DENSITY_X("cloud_density_x"); + const std::string FIELD_SKY_CLOUD_DENSITY_Y("cloud_density_y"); + const std::string FIELD_SKY_CLOUD_DENSITY_D("cloud_density_d"); + const std::string FIELD_SKY_CLOUD_DETAIL_X("cloud_detail_x"); + const std::string FIELD_SKY_CLOUD_DETAIL_Y("cloud_detail_y"); + const std::string FIELD_SKY_CLOUD_DETAIL_D("cloud_detail_d"); + + const std::string FIELD_SKY_SUN_MOON_COLOR("sun_moon_color"); + const std::string FIELD_SKY_GLOW_FOCUS("glow_focus"); + const std::string FIELD_SKY_GLOW_SIZE("glow_size"); + const std::string FIELD_SKY_STAR_BRIGHTNESS("star_brightness"); + const std::string FIELD_SKY_SUN_ROTATION("sun_rotation"); + const std::string FIELD_SKY_SUN_IMAGE("sun_image"); + const std::string FIELD_SKY_MOON_ROTATION("moon_rotation"); + const std::string FIELD_SKY_MOON_IMAGE("moon_image"); + + const F32 SLIDER_SCALE_SUN_AMBIENT(3.0f); + const F32 SLIDER_SCALE_BLUE_HORIZON_DENSITY(2.0f); + const F32 SLIDER_SCALE_GLOW_R(20.0f); + const F32 SLIDER_SCALE_GLOW_B(-5.0f); +} + +static LLPanelInjector<LLPanelSettingsSkyAtmosTab> t_settings_atmos("panel_settings_atmos"); +static LLPanelInjector<LLPanelSettingsSkyCloudTab> t_settings_cloud("panel_settings_cloud"); +static LLPanelInjector<LLPanelSettingsSkySunMoonTab> t_settings_sunmoon("panel_settings_sunmoon"); + +//========================================================================== +LLPanelSettingsSky::LLPanelSettingsSky() : + LLSettingsEditPanel(), + mSkySettings() +{ + +} + + +//========================================================================== +LLPanelSettingsSkyAtmosTab::LLPanelSettingsSkyAtmosTab() : + LLPanelSettingsSky() +{ +} + + +BOOL LLPanelSettingsSkyAtmosTab::postBuild() +{ + getChild<LLUICtrl>(FIELD_SKY_AMBIENT_LIGHT)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onAmbientLightChanged(); }); + getChild<LLUICtrl>(FIELD_SKY_BLUE_HORIZON)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onBlueHorizonChanged(); }); + getChild<LLUICtrl>(FIELD_SKY_BLUE_DENSITY)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onBlueDensityChanged(); }); + getChild<LLUICtrl>(FIELD_SKY_HAZE_HORIZON)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onHazeHorizonChanged(); }); + getChild<LLUICtrl>(FIELD_SKY_HAZE_DENSITY)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onHazeDensityChanged(); }); + getChild<LLUICtrl>(FIELD_SKY_SCENE_GAMMA)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSceneGammaChanged(); }); + getChild<LLUICtrl>(FIELD_SKY_DENSITY_MULTIP)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onDensityMultipChanged(); }); + getChild<LLUICtrl>(FIELD_SKY_DISTANCE_MULTIP)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onDistanceMultipChanged(); }); + getChild<LLUICtrl>(FIELD_SKY_MAX_ALT)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMaxAltChanged(); }); + + refresh(); + + return TRUE; +} + +void LLPanelSettingsSkyAtmosTab::refresh() +{ + if (!mSkySettings) + { + setAllChildrenEnabled(FALSE); + setEnabled(FALSE); + return; + } + + setEnabled(TRUE); + setAllChildrenEnabled(TRUE); + + getChild<LLColorSwatchCtrl>(FIELD_SKY_AMBIENT_LIGHT)->set(mSkySettings->getAmbientColor() / SLIDER_SCALE_SUN_AMBIENT); + getChild<LLColorSwatchCtrl>(FIELD_SKY_BLUE_HORIZON)->set(mSkySettings->getBlueHorizon() / SLIDER_SCALE_BLUE_HORIZON_DENSITY); + getChild<LLColorSwatchCtrl>(FIELD_SKY_BLUE_DENSITY)->set(mSkySettings->getBlueDensity() / SLIDER_SCALE_BLUE_HORIZON_DENSITY); + + getChild<LLUICtrl>(FIELD_SKY_HAZE_HORIZON)->setValue(mSkySettings->getHazeHorizon()); + getChild<LLUICtrl>(FIELD_SKY_HAZE_DENSITY)->setValue(mSkySettings->getHazeDensity()); + getChild<LLUICtrl>(FIELD_SKY_SCENE_GAMMA)->setValue(mSkySettings->getGamma()); + getChild<LLUICtrl>(FIELD_SKY_DENSITY_MULTIP)->setValue(mSkySettings->getDensityMultiplier()); + getChild<LLUICtrl>(FIELD_SKY_DISTANCE_MULTIP)->setValue(mSkySettings->getDistanceMultiplier()); + getChild<LLUICtrl>(FIELD_SKY_MAX_ALT)->setValue(mSkySettings->getMaxY()); + +} + +//------------------------------------------------------------------------- +void LLPanelSettingsSkyAtmosTab::onAmbientLightChanged() +{ + mSkySettings->setAmbientColor(LLColor3(getChild<LLColorSwatchCtrl>(FIELD_SKY_AMBIENT_LIGHT)->get() * SLIDER_SCALE_SUN_AMBIENT)); +} + +void LLPanelSettingsSkyAtmosTab::onBlueHorizonChanged() +{ + mSkySettings->setBlueHorizon(LLColor3(getChild<LLColorSwatchCtrl>(FIELD_SKY_BLUE_HORIZON)->get() * SLIDER_SCALE_BLUE_HORIZON_DENSITY)); +} + +void LLPanelSettingsSkyAtmosTab::onBlueDensityChanged() +{ + mSkySettings->setBlueDensity(LLColor3(getChild<LLColorSwatchCtrl>(FIELD_SKY_BLUE_DENSITY)->get() * SLIDER_SCALE_BLUE_HORIZON_DENSITY)); +} + +void LLPanelSettingsSkyAtmosTab::onHazeHorizonChanged() +{ + mSkySettings->setHazeHorizon(getChild<LLUICtrl>(FIELD_SKY_HAZE_HORIZON)->getValue().asReal()); +} + +void LLPanelSettingsSkyAtmosTab::onHazeDensityChanged() +{ + mSkySettings->setHazeDensity(getChild<LLUICtrl>(FIELD_SKY_HAZE_DENSITY)->getValue().asReal()); +} + +void LLPanelSettingsSkyAtmosTab::onSceneGammaChanged() +{ + mSkySettings->setGamma(getChild<LLUICtrl>(FIELD_SKY_SCENE_GAMMA)->getValue().asReal()); +} + +void LLPanelSettingsSkyAtmosTab::onDensityMultipChanged() +{ + mSkySettings->setDensityMultiplier(getChild<LLUICtrl>(FIELD_SKY_DENSITY_MULTIP)->getValue().asReal()); +} + +void LLPanelSettingsSkyAtmosTab::onDistanceMultipChanged() +{ + mSkySettings->setDistanceMultiplier(getChild<LLUICtrl>(FIELD_SKY_DISTANCE_MULTIP)->getValue().asReal()); +} + +void LLPanelSettingsSkyAtmosTab::onMaxAltChanged() +{ + mSkySettings->setMaxY(getChild<LLUICtrl>(FIELD_SKY_MAX_ALT)->getValue().asReal()); +} + +//========================================================================== +LLPanelSettingsSkyCloudTab::LLPanelSettingsSkyCloudTab() : + LLPanelSettingsSky() +{ +} + + +BOOL LLPanelSettingsSkyCloudTab::postBuild() +{ + getChild<LLUICtrl>(FIELD_SKY_CLOUD_COLOR)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onCloudColorChanged(); }); + getChild<LLUICtrl>(FIELD_SKY_CLOUD_COVERAGE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onCloudCoverageChanged(); }); + getChild<LLUICtrl>(FIELD_SKY_CLOUD_SCALE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onCloudScaleChanged(); }); + getChild<LLUICtrl>(FIELD_SKY_CLOUD_SCROLL_X)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onCloudScrollChanged(); }); + getChild<LLUICtrl>(FIELD_SKY_CLOUD_SCROLL_Y)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onCloudScrollChanged(); }); + getChild<LLTextureCtrl>(FIELD_SKY_CLOUD_MAP)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onCloudMapChanged(); }); +// getChild<LLTextureCtrl>(FIELD_SKY_CLOUD_MAP)->setDefaultImageAssetID(LLSettingsSky::DEFAULT_CLOUD_TEXTURE_ID); + + getChild<LLUICtrl>(FIELD_SKY_CLOUD_DENSITY_X)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onCloudDensityChanged(); }); + getChild<LLUICtrl>(FIELD_SKY_CLOUD_DENSITY_Y)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onCloudDensityChanged(); }); + getChild<LLUICtrl>(FIELD_SKY_CLOUD_DENSITY_D)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onCloudDensityChanged(); }); + getChild<LLUICtrl>(FIELD_SKY_CLOUD_DETAIL_X)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onCloudDetailChanged(); }); + getChild<LLUICtrl>(FIELD_SKY_CLOUD_DETAIL_Y)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onCloudDetailChanged(); }); + getChild<LLUICtrl>(FIELD_SKY_CLOUD_DETAIL_D)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onCloudDetailChanged(); }); + + refresh(); + + return TRUE; +} + +void LLPanelSettingsSkyCloudTab::refresh() +{ + if (!mSkySettings) + { + setAllChildrenEnabled(FALSE); + setEnabled(FALSE); + return; + } + + setEnabled(TRUE); + setAllChildrenEnabled(TRUE); + + getChild<LLColorSwatchCtrl>(FIELD_SKY_CLOUD_COLOR)->set(mSkySettings->getCloudColor()); + getChild<LLUICtrl>(FIELD_SKY_CLOUD_COVERAGE)->setValue(mSkySettings->getCloudShadow()); + getChild<LLUICtrl>(FIELD_SKY_CLOUD_SCALE)->setValue(mSkySettings->getCloudScale()); + + LLVector2 cloudScroll(mSkySettings->getCloudScrollRate()); + getChild<LLUICtrl>(FIELD_SKY_CLOUD_SCROLL_X)->setValue(cloudScroll[0]); + getChild<LLUICtrl>(FIELD_SKY_CLOUD_SCROLL_Y)->setValue(cloudScroll[1]); + + getChild<LLTextureCtrl>(FIELD_SKY_CLOUD_MAP)->setValue(mSkySettings->getCloudNoiseTextureId()); + + LLVector3 cloudDensity(mSkySettings->getCloudPosDensity1().getValue()); + getChild<LLUICtrl>(FIELD_SKY_CLOUD_DENSITY_X)->setValue(cloudDensity[0]); + getChild<LLUICtrl>(FIELD_SKY_CLOUD_DENSITY_Y)->setValue(cloudDensity[1]); + getChild<LLUICtrl>(FIELD_SKY_CLOUD_DENSITY_D)->setValue(cloudDensity[2]); + + LLVector3 cloudDetail(mSkySettings->getCloudPosDensity1().getValue()); + getChild<LLUICtrl>(FIELD_SKY_CLOUD_DETAIL_X)->setValue(cloudDetail[0]); + getChild<LLUICtrl>(FIELD_SKY_CLOUD_DETAIL_Y)->setValue(cloudDetail[1]); + getChild<LLUICtrl>(FIELD_SKY_CLOUD_DETAIL_D)->setValue(cloudDetail[2]); +} + +//------------------------------------------------------------------------- +void LLPanelSettingsSkyCloudTab::onCloudColorChanged() +{ + mSkySettings->setCloudColor(LLColor3(getChild<LLColorSwatchCtrl>(FIELD_SKY_CLOUD_COLOR)->get())); +} + +void LLPanelSettingsSkyCloudTab::onCloudCoverageChanged() +{ + mSkySettings->setCloudShadow(getChild<LLUICtrl>(FIELD_SKY_CLOUD_COVERAGE)->getValue().asReal()); +} + +void LLPanelSettingsSkyCloudTab::onCloudScaleChanged() +{ + mSkySettings->setCloudScale(getChild<LLUICtrl>(FIELD_SKY_CLOUD_SCALE)->getValue().asReal()); +} + +void LLPanelSettingsSkyCloudTab::onCloudScrollChanged() +{ + LLVector2 scroll(getChild<LLUICtrl>(FIELD_SKY_CLOUD_SCROLL_X)->getValue().asReal(), + getChild<LLUICtrl>(FIELD_SKY_CLOUD_SCROLL_Y)->getValue().asReal()); + + mSkySettings->setCloudScrollRate(scroll); +} + +void LLPanelSettingsSkyCloudTab::onCloudMapChanged() +{ + mSkySettings->setCloudNoiseTextureId(getChild<LLTextureCtrl>(FIELD_SKY_CLOUD_MAP)->getValue().asUUID()); +} + +void LLPanelSettingsSkyCloudTab::onCloudDensityChanged() +{ + LLColor3 density(getChild<LLUICtrl>(FIELD_SKY_CLOUD_DENSITY_X)->getValue().asReal(), + getChild<LLUICtrl>(FIELD_SKY_CLOUD_DENSITY_Y)->getValue().asReal(), + getChild<LLUICtrl>(FIELD_SKY_CLOUD_DENSITY_D)->getValue().asReal()); + + mSkySettings->setCloudPosDensity1(density); +} + +void LLPanelSettingsSkyCloudTab::onCloudDetailChanged() +{ + LLColor3 detail(getChild<LLUICtrl>(FIELD_SKY_CLOUD_DETAIL_X)->getValue().asReal(), + getChild<LLUICtrl>(FIELD_SKY_CLOUD_DETAIL_Y)->getValue().asReal(), + getChild<LLUICtrl>(FIELD_SKY_CLOUD_DETAIL_D)->getValue().asReal()); + + mSkySettings->setCloudPosDensity2(detail); +} + +//========================================================================== +LLPanelSettingsSkySunMoonTab::LLPanelSettingsSkySunMoonTab() : + LLPanelSettingsSky() +{ +} + + +BOOL LLPanelSettingsSkySunMoonTab::postBuild() +{ + getChild<LLUICtrl>(FIELD_SKY_SUN_MOON_COLOR)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunMoonColorChanged(); }); + getChild<LLUICtrl>(FIELD_SKY_GLOW_FOCUS)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onGlowChanged(); }); + getChild<LLUICtrl>(FIELD_SKY_GLOW_SIZE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onGlowChanged(); }); + getChild<LLUICtrl>(FIELD_SKY_STAR_BRIGHTNESS)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onStarBrightnessChanged(); }); + getChild<LLUICtrl>(FIELD_SKY_SUN_ROTATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunRotationChanged(); }); + getChild<LLUICtrl>(FIELD_SKY_SUN_IMAGE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunImageChanged(); }); +// getChild<LLTextureCtrl>(FIELD_SKY_SUN_IMAGE)->setDefaultImageAssetID(LLSettingsSky:: ); + getChild<LLUICtrl>(FIELD_SKY_MOON_ROTATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonRotationChanged(); }); + getChild<LLUICtrl>(FIELD_SKY_MOON_IMAGE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonImageChanged(); }); +// getChild<LLTextureCtrl>(FIELD_SKY_MOON_IMAGE)->setDefaultImageAssetID(LLSettingsSky:: ); + + refresh(); + + return TRUE; +} + +void LLPanelSettingsSkySunMoonTab::refresh() +{ + if (!mSkySettings) + { + setAllChildrenEnabled(FALSE); + setEnabled(FALSE); + return; + } + + setEnabled(TRUE); + setAllChildrenEnabled(TRUE); + + getChild<LLColorSwatchCtrl>(FIELD_SKY_SUN_MOON_COLOR)->set(mSkySettings->getSunlightColor() / SLIDER_SCALE_SUN_AMBIENT); + + LLColor3 glow(mSkySettings->getGlow()); + + glow.mV[0] = 2 - (glow.mV[0] / SLIDER_SCALE_GLOW_R); + glow.mV[2] /= SLIDER_SCALE_GLOW_B; + + getChild<LLUICtrl>(FIELD_SKY_GLOW_FOCUS)->setValue(glow.mV[0]); + getChild<LLUICtrl>(FIELD_SKY_GLOW_SIZE)->setValue(glow.mV[2]); + + getChild<LLUICtrl>(FIELD_SKY_STAR_BRIGHTNESS)->setValue(mSkySettings->getStarBrightness()); + getChild<LLJoystickQuaternion>(FIELD_SKY_SUN_ROTATION)->setRotation(mSkySettings->getSunRotation()); + getChild<LLTextureCtrl>(FIELD_SKY_SUN_IMAGE)->setValue(mSkySettings->getSunTextureId()); + getChild<LLJoystickQuaternion>(FIELD_SKY_MOON_ROTATION)->setRotation(mSkySettings->getMoonRotation()); + getChild<LLTextureCtrl>(FIELD_SKY_MOON_IMAGE)->setValue(mSkySettings->getMoonTextureId()); +} + +//------------------------------------------------------------------------- +void LLPanelSettingsSkySunMoonTab::onSunMoonColorChanged() +{ + LLColor3 color(getChild<LLColorSwatchCtrl>(FIELD_SKY_SUN_MOON_COLOR)->get()); + + color *= SLIDER_SCALE_SUN_AMBIENT; + + mSkySettings->setSunlightColor(color); +} + +void LLPanelSettingsSkySunMoonTab::onGlowChanged() +{ + LLColor3 glow(getChild<LLUICtrl>(FIELD_SKY_GLOW_FOCUS)->getValue().asReal(), 0.0f, + getChild<LLUICtrl>(FIELD_SKY_GLOW_SIZE)->getValue().asReal()); + + glow.mV[0] = (2 - glow.mV[0]) * SLIDER_SCALE_GLOW_R; + glow.mV[2] *= SLIDER_SCALE_GLOW_B; + + mSkySettings->setGlow(glow); +} + +void LLPanelSettingsSkySunMoonTab::onStarBrightnessChanged() +{ + mSkySettings->setStarBrightness(getChild<LLUICtrl>(FIELD_SKY_STAR_BRIGHTNESS)->getValue().asReal()); +} + +void LLPanelSettingsSkySunMoonTab::onSunRotationChanged() +{ + mSkySettings->setSunRotation(getChild<LLJoystickQuaternion>(FIELD_SKY_SUN_ROTATION)->getRotation()); +} + +void LLPanelSettingsSkySunMoonTab::onSunImageChanged() +{ + mSkySettings->setSunTextureId(getChild<LLTextureCtrl>(FIELD_SKY_SUN_IMAGE)->getValue().asUUID()); +} + +void LLPanelSettingsSkySunMoonTab::onMoonRotationChanged() +{ + mSkySettings->setMoonRotation(getChild<LLJoystickQuaternion>(FIELD_SKY_MOON_ROTATION)->getRotation()); +} + +void LLPanelSettingsSkySunMoonTab::onMoonImageChanged() +{ + mSkySettings->setMoonTextureId(getChild<LLTextureCtrl>(FIELD_SKY_MOON_IMAGE)->getValue().asUUID()); +} diff --git a/indra/newview/llpaneleditsky.h b/indra/newview/llpaneleditsky.h new file mode 100644 index 0000000000..56ae9dc7bb --- /dev/null +++ b/indra/newview/llpaneleditsky.h @@ -0,0 +1,124 @@ +/** +* @file llpaneleditsky.h +* @brief Panels for sky settings +* +* $LicenseInfo:firstyear=2011&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2011, 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 LLPANEL_EDIT_SKY_H +#define LLPANEL_EDIT_SKY_H + +#include "llpanel.h" +#include "llsettingssky.h" + +#include "llfloaterfixedenvironment.h" + +//========================================================================= +class LLSlider; +class LLColorSwatchCtrl; +class LLTextureCtrl; + +//========================================================================= +class LLPanelSettingsSky : public LLSettingsEditPanel +{ + LOG_CLASS(LLPanelSettingsSky); + +public: + LLPanelSettingsSky(); + + virtual void setSettings(const LLSettingsBase::ptr_t &settings) override { setSky(std::static_pointer_cast<LLSettingsSky>(settings)); } + + LLSettingsSky::ptr_t getSky() const { return mSkySettings; } + void setSky(const LLSettingsSky::ptr_t &sky) { mSkySettings = sky; refresh(); } + +protected: + LLSettingsSky::ptr_t mSkySettings; +}; + +class LLPanelSettingsSkyAtmosTab : public LLPanelSettingsSky +{ + LOG_CLASS(LLPanelSettingsSkyAtmosTab); + +public: + LLPanelSettingsSkyAtmosTab(); + + virtual BOOL postBuild() override; + +protected: + virtual void refresh() override; + +private: + void onAmbientLightChanged(); + void onBlueHorizonChanged(); + void onBlueDensityChanged(); + void onHazeHorizonChanged(); + void onHazeDensityChanged(); + void onSceneGammaChanged(); + void onDensityMultipChanged(); + void onDistanceMultipChanged(); + void onMaxAltChanged(); +}; + +class LLPanelSettingsSkyCloudTab : public LLPanelSettingsSky +{ + LOG_CLASS(LLPanelSettingsSkyCloudTab); + +public: + LLPanelSettingsSkyCloudTab(); + + virtual BOOL postBuild() override; + +protected: + virtual void refresh() override; + +private: + void onCloudColorChanged(); + void onCloudCoverageChanged(); + void onCloudScaleChanged(); + void onCloudScrollChanged(); + void onCloudMapChanged(); + void onCloudDensityChanged(); + void onCloudDetailChanged(); +}; + +class LLPanelSettingsSkySunMoonTab : public LLPanelSettingsSky +{ + LOG_CLASS(LLPanelSettingsSkySunMoonTab); + +public: + LLPanelSettingsSkySunMoonTab(); + + virtual BOOL postBuild() override; + +protected: + virtual void refresh() override; + +private: + void onSunMoonColorChanged(); + void onGlowChanged(); + void onStarBrightnessChanged(); + void onSunRotationChanged(); + void onSunImageChanged(); + void onMoonRotationChanged(); + void onMoonImageChanged(); +}; +#endif // LLPANEL_EDIT_SKY_H diff --git a/indra/newview/llpaneleditwater.cpp b/indra/newview/llpaneleditwater.cpp new file mode 100644 index 0000000000..5904b5a542 --- /dev/null +++ b/indra/newview/llpaneleditwater.cpp @@ -0,0 +1,215 @@ +/** +* @file llpaneleditwater.cpp +* @brief Floaters to create and edit fixed settings for sky and water. +* +* $LicenseInfo:firstyear=2011&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2011, 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 "llpaneleditwater.h" + +#include "llslider.h" +#include "lltexturectrl.h" +#include "llcolorswatch.h" + +namespace +{ + const std::string FIELD_WATER_FOG_COLOR("water_fog_color"); + const std::string FIELD_WATER_FOG_DENSITY("water_fog_density"); + const std::string FIELD_WATER_UNDERWATER_MOD("water_underwater_mod"); + const std::string FIELD_WATER_NORMAL_MAP("water_normal_map"); + + const std::string FIELD_WATER_WAVE1_X("water_wave1_x"); + const std::string FIELD_WATER_WAVE1_Y("water_wave1_y"); + + const std::string FIELD_WATER_WAVE2_X("water_wave2_x"); + const std::string FIELD_WATER_WAVE2_Y("water_wave2_y"); + + const std::string FIELD_WATER_NORMAL_SCALE_X("water_normal_scale_x"); + const std::string FIELD_WATER_NORMAL_SCALE_Y("water_normal_scale_y"); + const std::string FIELD_WATER_NORMAL_SCALE_Z("water_normal_scale_z"); + + const std::string FIELD_WATER_FRESNEL_SCALE("water_fresnel_scale"); + const std::string FIELD_WATER_FRESNEL_OFFSET("water_fresnel_offset"); + + const std::string FIELD_WATER_SCALE_ABOVE("water_scale_above"); + const std::string FIELD_WATER_SCALE_BELOW("water_scale_below"); + const std::string FIELD_WATER_BLUR_MULTIP("water_blur_multip"); +} + +static LLPanelInjector<LLPanelSettingsWaterMainTab> t_settings_water("panel_settings_water"); + +//========================================================================== +LLPanelSettingsWater::LLPanelSettingsWater() : + LLSettingsEditPanel(), + mWaterSettings() +{ + +} + + +//========================================================================== +LLPanelSettingsWaterMainTab::LLPanelSettingsWaterMainTab(): + LLPanelSettingsWater(), + mClrFogColor(nullptr), + mTxtNormalMap(nullptr) +{ +} + + +BOOL LLPanelSettingsWaterMainTab::postBuild() +{ + mClrFogColor = getChild<LLColorSwatchCtrl>(FIELD_WATER_FOG_COLOR); + mTxtNormalMap = getChild<LLTextureCtrl>(FIELD_WATER_NORMAL_MAP); + + mClrFogColor->setCommitCallback([this](LLUICtrl *, const LLSD &) { onFogColorChanged(); }); + getChild<LLUICtrl>(FIELD_WATER_FOG_DENSITY)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onFogDensityChanged(); }); +// getChild<LLUICtrl>(FIELD_WATER_FOG_DENSITY)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onFogDensityChanged(getChild<LLUICtrl>(FIELD_WATER_FOG_DENSITY)->getValue().asReal()); }); + getChild<LLUICtrl>(FIELD_WATER_UNDERWATER_MOD)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onFogUnderWaterChanged(); }); + + mTxtNormalMap->setDefaultImageAssetID(LLSettingsWater::DEFAULT_WATER_NORMAL_ID); + mTxtNormalMap->setCommitCallback([this](LLUICtrl *, const LLSD &) { onNormalMapChanged(); }); + + getChild<LLUICtrl>(FIELD_WATER_WAVE1_X)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onLargeWaveChanged(); }); + getChild<LLUICtrl>(FIELD_WATER_WAVE1_Y)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onLargeWaveChanged(); }); + + getChild<LLUICtrl>(FIELD_WATER_WAVE2_X)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSmallWaveChanged(); }); + getChild<LLUICtrl>(FIELD_WATER_WAVE2_Y)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSmallWaveChanged(); }); + + getChild<LLUICtrl>(FIELD_WATER_NORMAL_SCALE_X)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onNormalScaleChanged(); }); + getChild<LLUICtrl>(FIELD_WATER_NORMAL_SCALE_Y)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onNormalScaleChanged(); }); + getChild<LLUICtrl>(FIELD_WATER_NORMAL_SCALE_Z)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onNormalScaleChanged(); }); + + getChild<LLUICtrl>(FIELD_WATER_FRESNEL_SCALE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onFresnelScaleChanged(); }); + getChild<LLUICtrl>(FIELD_WATER_FRESNEL_OFFSET)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onFresnelOffsetChanged(); }); + getChild<LLUICtrl>(FIELD_WATER_SCALE_ABOVE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onScaleAboveChanged(); }); + getChild<LLUICtrl>(FIELD_WATER_SCALE_BELOW)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onScaleBelowChanged(); }); + getChild<LLUICtrl>(FIELD_WATER_BLUR_MULTIP)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onBlurMultipChanged(); }); + + refresh(); + + return TRUE; +} + +//========================================================================== +void LLPanelSettingsWaterMainTab::refresh() +{ + if (!mWaterSettings) + { + setAllChildrenEnabled(FALSE); + setEnabled(FALSE); + return; + } + + setEnabled(TRUE); + setAllChildrenEnabled(TRUE); + mClrFogColor->set(mWaterSettings->getFogColor()); + getChild<LLUICtrl>(FIELD_WATER_FOG_DENSITY)->setValue(mWaterSettings->getFogDensity()); + getChild<LLUICtrl>(FIELD_WATER_UNDERWATER_MOD)->setValue(mWaterSettings->getFogMod()); + mTxtNormalMap->setValue(mWaterSettings->getNormalMapID()); + LLVector2 vect2 = mWaterSettings->getWave1Dir(); + getChild<LLUICtrl>(FIELD_WATER_WAVE1_X)->setValue(vect2[0]); + getChild<LLUICtrl>(FIELD_WATER_WAVE1_Y)->setValue(vect2[1]); + vect2 = mWaterSettings->getWave2Dir(); + getChild<LLUICtrl>(FIELD_WATER_WAVE2_X)->setValue(vect2[0]); + getChild<LLUICtrl>(FIELD_WATER_WAVE2_Y)->setValue(vect2[1]); + LLVector3 vect3 = mWaterSettings->getNormalScale(); + getChild<LLUICtrl>(FIELD_WATER_NORMAL_SCALE_X)->setValue(vect3[0]); + getChild<LLUICtrl>(FIELD_WATER_NORMAL_SCALE_Y)->setValue(vect3[1]); + getChild<LLUICtrl>(FIELD_WATER_NORMAL_SCALE_Z)->setValue(vect3[2]); + getChild<LLUICtrl>(FIELD_WATER_FRESNEL_SCALE)->setValue(mWaterSettings->getFresnelOffset()); + getChild<LLUICtrl>(FIELD_WATER_FRESNEL_OFFSET)->setValue(mWaterSettings->getFresnelOffset()); + getChild<LLUICtrl>(FIELD_WATER_SCALE_ABOVE)->setValue(mWaterSettings->getScaleAbove()); + getChild<LLUICtrl>(FIELD_WATER_SCALE_BELOW)->setValue(mWaterSettings->getScaleBelow()); + getChild<LLUICtrl>(FIELD_WATER_BLUR_MULTIP)->setValue(mWaterSettings->getBlurMultiplier()); +} + +//========================================================================== + +void LLPanelSettingsWaterMainTab::onFogColorChanged() +{ + mWaterSettings->setFogColor(LLColor3(mClrFogColor->get())); +} + +void LLPanelSettingsWaterMainTab::onFogDensityChanged() +{ + mWaterSettings->setFogDensity(getChild<LLUICtrl>(FIELD_WATER_FOG_DENSITY)->getValue().asReal()); +} + +void LLPanelSettingsWaterMainTab::onFogUnderWaterChanged() +{ + mWaterSettings->setFogMod(getChild<LLUICtrl>(FIELD_WATER_UNDERWATER_MOD)->getValue().asReal()); +} + +void LLPanelSettingsWaterMainTab::onNormalMapChanged() +{ + mWaterSettings->setNormalMapID(mTxtNormalMap->getImageAssetID()); +} + + +void LLPanelSettingsWaterMainTab::onLargeWaveChanged() +{ + LLVector2 vect(getChild<LLUICtrl>(FIELD_WATER_WAVE1_X)->getValue().asReal(), getChild<LLUICtrl>(FIELD_WATER_WAVE1_Y)->getValue().asReal()); + LL_WARNS("LAPRAS") << "Changing Large Wave from " << mWaterSettings->getWave1Dir() << " -> " << vect << LL_ENDL; + mWaterSettings->setWave1Dir(vect); +} + +void LLPanelSettingsWaterMainTab::onSmallWaveChanged() +{ + LLVector2 vect(getChild<LLUICtrl>(FIELD_WATER_WAVE2_X)->getValue().asReal(), getChild<LLUICtrl>(FIELD_WATER_WAVE2_Y)->getValue().asReal()); + LL_WARNS("LAPRAS") << "Changing Small Wave from " << mWaterSettings->getWave2Dir() << " -> " << vect << LL_ENDL; + mWaterSettings->setWave2Dir(vect); +} + + +void LLPanelSettingsWaterMainTab::onNormalScaleChanged() +{ + LLVector3 vect(getChild<LLUICtrl>(FIELD_WATER_NORMAL_SCALE_X)->getValue().asReal(), getChild<LLUICtrl>(FIELD_WATER_NORMAL_SCALE_Y)->getValue().asReal(), getChild<LLUICtrl>(FIELD_WATER_NORMAL_SCALE_Z)->getValue().asReal()); + LL_WARNS("LAPRAS") << "Changing normal scale from " << mWaterSettings->getNormalScale() << " -> " << vect << LL_ENDL; + mWaterSettings->setNormalScale(vect); +} + +void LLPanelSettingsWaterMainTab::onFresnelScaleChanged() +{ + mWaterSettings->setFresnelScale(getChild<LLUICtrl>(FIELD_WATER_FRESNEL_SCALE)->getValue().asReal()); +} + +void LLPanelSettingsWaterMainTab::onFresnelOffsetChanged() +{ + mWaterSettings->setFresnelOffset(getChild<LLUICtrl>(FIELD_WATER_FRESNEL_OFFSET)->getValue().asReal()); +} + +void LLPanelSettingsWaterMainTab::onScaleAboveChanged() +{ + mWaterSettings->setScaleAbove(getChild<LLUICtrl>(FIELD_WATER_SCALE_ABOVE)->getValue().asReal()); +} + +void LLPanelSettingsWaterMainTab::onScaleBelowChanged() +{ + mWaterSettings->setScaleBelow(getChild<LLUICtrl>(FIELD_WATER_SCALE_BELOW)->getValue().asReal()); +} + +void LLPanelSettingsWaterMainTab::onBlurMultipChanged() +{ + mWaterSettings->setBlurMultiplier(getChild<LLUICtrl>(FIELD_WATER_BLUR_MULTIP)->getValue().asReal()); +} diff --git a/indra/newview/llpaneleditwater.h b/indra/newview/llpaneleditwater.h new file mode 100644 index 0000000000..3b41a1bb24 --- /dev/null +++ b/indra/newview/llpaneleditwater.h @@ -0,0 +1,113 @@ +/** +* @file llpaneleditwater.h +* @brief Panels for water settings +* +* $LicenseInfo:firstyear=2011&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2011, 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 LLPANEL_EDIT_WATER_H +#define LLPANEL_EDIT_WATER_H + +#include "llpanel.h" +#include "llsettingswater.h" + +#include "llfloaterfixedenvironment.h" + +//========================================================================= +class LLSlider; +class LLColorSwatchCtrl; +class LLTextureCtrl; + +//========================================================================= +class LLPanelSettingsWater : public LLSettingsEditPanel +{ + LOG_CLASS(LLPanelSettingsWater); + +public: + LLPanelSettingsWater(); + + virtual void setSettings(const LLSettingsBase::ptr_t &settings) override { setWater(std::static_pointer_cast<LLSettingsWater>(settings)); } + + LLSettingsWater::ptr_t getWater() const { return mWaterSettings; } + void setWater(const LLSettingsWater::ptr_t &water) { mWaterSettings = water; refresh(); } + +protected: + LLSettingsWater::ptr_t mWaterSettings; +}; + +// *RIDER* In this case this split is unecessary since there is only a single +// tab page for water settings at this point. However more may be added in the +// future and I want to reinforce the pattern used for sky/atmosphere tabs. +class LLPanelSettingsWaterMainTab : public LLPanelSettingsWater +{ + LOG_CLASS(LLPanelSettingsWaterMainTab); + +public: + LLPanelSettingsWaterMainTab(); + + virtual BOOL postBuild() override; + +protected: + virtual void refresh() override; + +private: + + LLColorSwatchCtrl * mClrFogColor; +// LLSlider * mSldFogDensity; +// LLSlider * mSldUnderWaterMod; + LLTextureCtrl * mTxtNormalMap; + +// // Temp until XY control +// LLSlider * mSldWave1X; +// LLSlider * mSldWave1Y; +// +// // Temp until XY control +// LLSlider * mSldWave2X; +// LLSlider * mSldWave2Y; +// +// LLSlider * mSldNormalScaleX; +// LLSlider * mSldNormalScaleY; +// LLSlider * mSldNormalScaleZ; +// LLSlider * mSldFresnelScale; +// LLSlider * mSldFresnelOffset; +// LLSlider * mSldScaleAbove; +// LLSlider * mSldScaleBelow; +// LLSlider * mSldBlurMultip; + + void onFogColorChanged(); + void onFogDensityChanged(); + void onFogUnderWaterChanged(); + void onNormalMapChanged(); + + void onLargeWaveChanged(); + void onSmallWaveChanged(); + + void onNormalScaleChanged(); + void onFresnelScaleChanged(); + void onFresnelOffsetChanged(); + void onScaleAboveChanged(); + void onScaleBelowChanged(); + void onBlurMultipChanged(); +}; + + +#endif // LLPANEL_EDIT_WATER_H diff --git a/indra/newview/llpanelenvironment.cpp b/indra/newview/llpanelenvironment.cpp new file mode 100644 index 0000000000..ebe3da79f2 --- /dev/null +++ b/indra/newview/llpanelenvironment.cpp @@ -0,0 +1,421 @@ +/** + * @file llpanelenvironment.cpp + * @brief LLPanelExperiences class implementation + * + * $LicenseInfo:firstyear=2013&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2013, 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 "llpanelprofile.h" +#include "lluictrlfactory.h" +#include "llexperiencecache.h" +#include "llagent.h" + +#include "llviewerregion.h" +#include "llpanelenvironment.h" +#include "llslurl.h" +#include "lllayoutstack.h" + +#include "llfloater.h" +#include "llfloaterreg.h" +#include "llfloatereditextdaycycle.h" + +//static LLPanelInjector<LLPanelEnvironmentInfo> register_environment_panel("environment_panel"); + +LLPanelEnvironmentInfo::LLPanelEnvironmentInfo(): + mEnableEditing(false), + mRegionSettingsRadioGroup(NULL), + mDayLengthSlider(NULL), + mDayOffsetSlider(NULL), + mAllowOverRide(NULL) +{ +} + +// virtual +BOOL LLPanelEnvironmentInfo::postBuild() +{ + mRegionSettingsRadioGroup = getChild<LLRadioGroup>("environment_select_radio_group"); + mRegionSettingsRadioGroup->setCommitCallback(boost::bind(&LLPanelEnvironmentInfo::onSwitchDefaultSelection, this)); + + mDayLengthSlider = getChild<LLSliderCtrl>("day_length_sld"); + mDayOffsetSlider = getChild<LLSliderCtrl>("day_offset_sld"); + mAllowOverRide = getChild<LLCheckBoxCtrl>("allow_override_chk"); + + childSetCommitCallback("edit_btn", boost::bind(&LLPanelEnvironmentInfo::onBtnEdit, this), NULL); + childSetCommitCallback("apply_btn", boost::bind(&LLPanelEnvironmentInfo::onBtnApply, this), NULL); + childSetCommitCallback("cancel_btn", boost::bind(&LLPanelEnvironmentInfo::onBtnCancel, this), NULL); + + return TRUE; +} + +// virtual +void LLPanelEnvironmentInfo::onOpen(const LLSD& key) +{ + LL_DEBUGS("Windlight") << "Panel opened, refreshing" << LL_ENDL; + refresh(); +} + +// virtual +void LLPanelEnvironmentInfo::onVisibilityChange(BOOL new_visibility) +{ + // If hiding (user switched to another tab or closed the floater), + // display user's preferred environment. + // switching back and forth between agent's environment and the one being edited. + // +} + +void LLPanelEnvironmentInfo::refresh() +{ +#if 0 + if (gDisconnected) + { + return; + } + + populateWaterPresetsList(); + populateSkyPresetsList(); + populateDayCyclesList(); + + // Init radio groups. + const LLEnvironmentSettings& settings = LLEnvManagerNew::instance().getRegionSettings(); + const LLSD& dc = settings.getWLDayCycle(); + LLSD::Real first_frame_time = dc.size() > 0 ? dc[0][0].asReal() : 0.0f; + const bool use_fixed_sky = dc.size() == 1 && first_frame_time < 0; + mRegionSettingsRadioGroup->setSelectedIndex(settings.getSkyMap().size() == 0 ? 0 : 1); + mDayCycleSettingsRadioGroup->setSelectedIndex(use_fixed_sky ? 0 : 1); + + setControlsEnabled(mEnableEditing); + + setDirty(false); +#endif +} + +void LLPanelEnvironmentInfo::setControlsEnabled(bool enabled) +{ + mRegionSettingsRadioGroup->setEnabled(enabled); + + mDayLengthSlider->setEnabled(false); + mDayOffsetSlider->setEnabled(false); + mAllowOverRide->setEnabled(enabled); + + getChildView("edit_btn")->setEnabled(false); + + getChildView("apply_btn")->setEnabled(enabled); + getChildView("cancel_btn")->setEnabled(enabled); + + if (enabled) + { + // Enable/disable some controls based on currently selected radio buttons. + bool use_defaults = mRegionSettingsRadioGroup->getSelectedIndex() == 0; + getChild<LLView>("edit_btn")->setEnabled(!use_defaults); + + mDayLengthSlider->setEnabled(!use_defaults); + mDayOffsetSlider->setEnabled(!use_defaults); + + } +} + +void LLPanelEnvironmentInfo::setApplyProgress(bool started) +{ +// LLLoadingIndicator* indicator = getChild<LLLoadingIndicator>("progress_indicator"); +// +// indicator->setVisible(started); +// +// if (started) +// { +// indicator->start(); +// } +// else +// { +// indicator->stop(); +// } +} + +void LLPanelEnvironmentInfo::setDirty(bool dirty) +{ + getChildView("apply_btn")->setEnabled(dirty); + getChildView("cancel_btn")->setEnabled(dirty); +} + +// void LLPanelEnvironmentInfo::sendRegionSunUpdate() +// { +// #if 0 +// LLRegionInfoModel& region_info = LLRegionInfoModel::instance(); +// +// // If the region is being switched to fixed sky, +// // change the region's sun hour according to the (fixed) sun position. +// // This is needed for llGetSunDirection() LSL function to work properly (STORM-1330). +// const LLSD& sky_map = mNewRegionSettings.getSkyMap(); +// bool region_use_fixed_sky = sky_map.size() == 1; +// if (region_use_fixed_sky) +// { +// LLWLParamSet param_set; +// llassert(sky_map.isMap()); +// param_set.setAll(sky_map.beginMap()->second); +// F32 sun_angle = param_set.getSunAngle(); +// +// LL_DEBUGS("Windlight Sync") << "Old sun hour: " << region_info.mSunHour << LL_ENDL; +// // convert value range from 0..2pi to 6..30 +// region_info.mSunHour = fmodf((sun_angle / F_TWO_PI) * 24.f, 24.f) + 6.f; +// } +// +// region_info.setUseFixedSun(region_use_fixed_sky); +// region_info.mUseEstateSun = !region_use_fixed_sky; +// LL_DEBUGS("Windlight Sync") << "Sun hour: " << region_info.mSunHour << LL_ENDL; +// +// region_info.sendRegionTerrain(LLFloaterRegionInfo::getLastInvoice()); +// #endif +// } + +// void LLPanelEnvironmentInfo::fixEstateSun() +// { +// // We don't support fixed sun estates anymore and need to fix +// // such estates for region day cycle to take effect. +// // *NOTE: Assuming that current estate settings have arrived already. +// LLEstateInfoModel& estate_info = LLEstateInfoModel::instance(); +// if (estate_info.getUseFixedSun()) +// { +// LL_INFOS() << "Switching estate to global sun" << LL_ENDL; +// estate_info.setUseFixedSun(false); +// estate_info.sendEstateInfo(); +// } +// } + +// void LLPanelEnvironmentInfo::populateWaterPresetsList() +// { +// #if 0 +// mWaterPresetCombo->removeall(); +// +// // If the region already has water params, add them to the list. +// const LLEnvironmentSettings& region_settings = LLEnvManagerNew::instance().getRegionSettings(); +// if (region_settings.getWaterParams().size() != 0) +// { +// const std::string& region_name = gAgent.getRegion()->getName(); +// mWaterPresetCombo->add(region_name, LLWLParamKey(region_name, LLEnvKey::SCOPE_REGION).toLLSD()); +// mWaterPresetCombo->addSeparator(); +// } +// +// std::list<std::string> user_presets, system_presets; +// LLWaterParamManager::instance().getPresetNames(user_presets, system_presets); +// +// // Add local user presets first. +// for (std::list<std::string>::const_iterator it = user_presets.begin(); it != user_presets.end(); ++it) +// { +// mWaterPresetCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toLLSD()); +// } +// +// if (user_presets.size() > 0) +// { +// mWaterPresetCombo->addSeparator(); +// } +// +// // Add local system presets. +// for (std::list<std::string>::const_iterator it = system_presets.begin(); it != system_presets.end(); ++it) +// { +// mWaterPresetCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toLLSD()); +// } +// +// // There's no way to select current preset because its name is not stored on server. +// #endif +// } +// +// void LLPanelEnvironmentInfo::populateSkyPresetsList() +// { +// #if 0 +// mSkyPresetCombo->removeall(); +// +// LLWLParamManager::preset_name_list_t region_presets; +// LLWLParamManager::preset_name_list_t user_presets, sys_presets; +// LLWLParamManager::instance().getPresetNames(region_presets, user_presets, sys_presets); +// +// // Add region presets. +// std::string region_name = gAgent.getRegion() ? gAgent.getRegion()->getName() : LLTrans::getString("Unknown"); +// for (LLWLParamManager::preset_name_list_t::const_iterator it = region_presets.begin(); it != region_presets.end(); ++it) +// { +// std::string preset_name = *it; +// std::string item_title = preset_name + " (" + region_name + ")"; +// mSkyPresetCombo->add(item_title, LLWLParamKey(preset_name, LLEnvKey::SCOPE_REGION).toStringVal()); +// } +// +// if (!region_presets.empty()) +// { +// mSkyPresetCombo->addSeparator(); +// } +// +// // Add user presets. +// for (LLWLParamManager::preset_name_list_t::const_iterator it = user_presets.begin(); it != user_presets.end(); ++it) +// { +// mSkyPresetCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toStringVal()); +// } +// +// if (!user_presets.empty()) +// { +// mSkyPresetCombo->addSeparator(); +// } +// +// // Add system presets. +// for (LLWLParamManager::preset_name_list_t::const_iterator it = sys_presets.begin(); it != sys_presets.end(); ++it) +// { +// mSkyPresetCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toStringVal()); +// } +// +// // Select current preset. +// LLSD sky_map = LLEnvManagerNew::instance().getRegionSettings().getSkyMap(); +// if (sky_map.size() == 1) // if the region is set to fixed sky +// { +// std::string preset_name = sky_map.beginMap()->first; +// mSkyPresetCombo->selectByValue(LLWLParamKey(preset_name, LLEnvKey::SCOPE_REGION).toStringVal()); +// } +// #endif +// } +// +// void LLPanelEnvironmentInfo::populateDayCyclesList() +// { +// #if 0 +// mDayCyclePresetCombo->removeall(); +// +// // If the region already has env. settings, add its day cycle to the list. +// const LLSD& cur_region_dc = LLEnvManagerNew::instance().getRegionSettings().getWLDayCycle(); +// if (cur_region_dc.size() != 0) +// { +// LLViewerRegion* region = gAgent.getRegion(); +// llassert(region != NULL); +// +// LLWLParamKey key(region->getName(), LLEnvKey::SCOPE_REGION); +// mDayCyclePresetCombo->add(region->getName(), key.toStringVal()); +// mDayCyclePresetCombo->addSeparator(); +// } +// +// // Add local user day cycles. +// LLDayCycleManager::preset_name_list_t user_days, sys_days; +// LLDayCycleManager::instance().getPresetNames(user_days, sys_days); +// for (LLDayCycleManager::preset_name_list_t::const_iterator it = user_days.begin(); it != user_days.end(); ++it) +// { +// mDayCyclePresetCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toStringVal()); +// } +// +// if (user_days.size() > 0) +// { +// mDayCyclePresetCombo->addSeparator(); +// } +// +// // Add local system day cycles. +// for (LLDayCycleManager::preset_name_list_t::const_iterator it = sys_days.begin(); it != sys_days.end(); ++it) +// { +// mDayCyclePresetCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toStringVal()); +// } +// +// // Current day cycle is already selected. +// #endif +// } + +void LLPanelEnvironmentInfo::onSwitchDefaultSelection() +{ + bool use_defaults = mRegionSettingsRadioGroup->getSelectedIndex() == 0; + + getChild<LLView>("edit_btn")->setEnabled(!use_defaults); + + mDayLengthSlider->setEnabled(!use_defaults); + mDayOffsetSlider->setEnabled(!use_defaults); + + setDirty(true); +} + + +void LLPanelEnvironmentInfo::onBtnApply() +{ + doApply(); +} + +void LLPanelEnvironmentInfo::onBtnCancel() +{ + // Reload last saved region settings. + refresh(); +} + +void LLPanelEnvironmentInfo::onBtnEdit() +{ + LLFloaterEditExtDayCycle *dayeditor = (LLFloaterEditExtDayCycle *)LLFloaterReg::getInstance("env_edit_extdaycycle"); + + if (dayeditor) + { //*TODO Determine if region or parcel. + LLSD params(LLSDMap(LLFloaterEditExtDayCycle::KEY_LIVE_ENVIRONMENT, "parcel") + (LLFloaterEditExtDayCycle::KEY_DAY_LENGTH, mDayLengthSlider->getValueF32() * (60.0 * 60.0))); + + LLFloaterReg::showInstance("env_edit_extdaycycle", params, TAKE_FOCUS_YES); + +// dayeditor->openFloater(mEditingDayCycle, F32Hours(mDayLengthSlider->getValue().asReal()), F32Hours(mDayOffsetSlider->getValue().asReal())); + } +} + +void LLPanelEnvironmentInfo::onEditiCommited(LLSettingsDay::ptr_t newday) +{ + doEditCommited(newday); +} + +void LLPanelEnvironmentInfo::doEditCommited(LLSettingsDay::ptr_t &newday) +{ + mEditingDayCycle = newday; + /*TODO pure virtual*/ +} + +// void LLPanelEnvironmentInfo::onRegionSettingschange() +// { +// LL_DEBUGS("Windlight") << "Region settings changed, refreshing" << LL_ENDL; +// refresh(); +// +// // Stop applying progress indicator (it may be running if it's us who initiated settings update). +// setApplyProgress(false); +// } +// +// void LLPanelEnvironmentInfo::onRegionSettingsApplied(bool ok) +// { +// // If applying new settings has failed, stop the indicator right away. +// // Otherwise it will be stopped when we receive the updated settings from server. +// if (ok) +// { +// // Set the region sun phase/flags according to the chosen new preferences. +// // +// // If we do this earlier we may get jerky transition from fixed sky to a day cycle (STORM-1481). +// // That is caused by the simulator re-sending the region info, which in turn makes us +// // re-request and display old region environment settings while the new ones haven't been applied yet. +// sendRegionSunUpdate(); +// +// // Switch estate to not using fixed sun for the region day cycle to work properly (STORM-1506). +// fixEstateSun(); +// } +// else +// { +// setApplyProgress(false); +// +// // We need to re-request environment setting here, +// // otherwise our subsequent attempts to change region settings will fail with the following error: +// // "Unable to update environment settings because the last update your viewer saw was not the same +// // as the last update sent from the simulator. Try sending your update again, and if this +// // does not work, try leaving and returning to the region." +// // LLEnvManagerNew::instance().requestRegionSettings(); +// } +// } + + diff --git a/indra/newview/llpanelenvironment.h b/indra/newview/llpanelenvironment.h new file mode 100644 index 0000000000..7cc7ddae6f --- /dev/null +++ b/indra/newview/llpanelenvironment.h @@ -0,0 +1,83 @@ +/** + * @file llpanelenvironment.h + * @brief LLPanelExperiences class definition + * + * $LicenseInfo:firstyear=2013&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2013, 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_LLPANELENVIRONMENT_H +#define LL_LLPANELENVIRONMENT_H + +#include "llaccordionctrltab.h" +#include "llradiogroup.h" +#include "llcheckboxctrl.h" +#include "llsliderctrl.h" +#include "llsettingsdaycycle.h" + +class LLViewerRegion; + +class LLPanelEnvironmentInfo : public LLPanel +{ +public: + LLPanelEnvironmentInfo(); + + // LLPanel + /*virtual*/ BOOL postBuild(); + /*virtual*/ void onOpen(const LLSD& key); + + // LLView + /*virtual*/ void onVisibilityChange(BOOL new_visibility); + + + virtual void refresh(); + +protected: + LOG_CLASS(LLPanelEnvironmentInfo); + + void setControlsEnabled(bool enabled); + void setApplyProgress(bool started); + void setDirty(bool dirty); + + void onSwitchDefaultSelection(); + + void onBtnApply(); + void onBtnCancel(); + void onBtnEdit(); + + void onEditiCommited(LLSettingsDay::ptr_t newday); + + virtual void doApply() = 0; + virtual void doEditCommited(LLSettingsDay::ptr_t &newday); + + /// New environment settings that are being applied to the region. + // LLEnvironmentSettings mNewRegionSettings; + + bool mEnableEditing; + + LLRadioGroup* mRegionSettingsRadioGroup; + LLSliderCtrl* mDayLengthSlider; + LLSliderCtrl* mDayOffsetSlider; + LLCheckBoxCtrl* mAllowOverRide; + + LLSettingsDay::ptr_t mEditingDayCycle; +}; +#endif // LL_LLPANELEXPERIENCES_H 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<LLPostcardUploadInfo>( getChild<LLUICtrl>("name_form")->getValue().asString(), getChild<LLUICtrl>("to_form")->getValue().asString(), getChild<LLUICtrl>("subject_form")->getValue().asString(), getChild<LLUICtrl>("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<LLBufferedAssetUploadInfo>(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<LLBufferedAssetUploadInfo>(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<LLBufferedAssetUploadInfo>(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<LLBufferedAssetUploadInfo>(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 945f3c370c..54a47f6e6e 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -33,7 +33,6 @@ #include "llcheckboxctrl.h" #include "llcombobox.h" #include "lldir.h" -#include "llenvmanager.h" #include "llexternaleditor.h" #include "llfilepicker.h" #include "llfloaterreg.h" @@ -1708,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<LLScriptAssetUpload>(mItemUUID, buffer, + [](LLUUID itemId, LLUUID, LLUUID, LLSD response) { + LLPreviewLSL::finishedLSLUpload(itemId, response); + })); LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo); } @@ -2250,11 +2251,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<LLScriptAssetUpload>(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 new file mode 100644 index 0000000000..1ac607cd1f --- /dev/null +++ b/indra/newview/llsettingsvo.cpp @@ -0,0 +1,1007 @@ +/** +* @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 <algorithm> +#include <cstdio> +#include <boost/make_shared.hpp> +#include "lltrace.h" +#include "llfasttimer.h" +#include "v3colorutil.h" + +#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" +#include "llassetstorage.h" +#include "llvfile.h" + +#undef VERIFY_LEGACY_CONVERSION + +//========================================================================= +namespace +{ +LLSD ensureArray4(LLSD in, F32 fill) +{ + if (in.size() >= 4) + return in; + + LLSD out(LLSD::emptyArray()); + + for (S32 idx = 0; idx < in.size(); ++idx) + { + out.append(in[idx]); + } + + while (out.size() < 4) + { + out.append(LLSD::Real(fill)); + } + return out; +} + + +//------------------------------------------------------------------------- +class LLSettingsInventoryCB : public LLInventoryCallback +{ +public: + typedef std::function<void(const LLUUID &)> callback_t; + + LLSettingsInventoryCB(callback_t cbfn) : + mCbfn(cbfn) + { } + + void fire(const LLUUID& inv_item) override { if (mCbfn) mCbfn(inv_item); } + +private: + callback_t mCbfn; +}; + +} + + +//========================================================================= +void LLSettingsVOBase::createInventoryItem(const LLSettingsBase::ptr_t &settings, inventory_result_fn callback) +{ + LLTransactionID tid; + LLUUID parentFolder; //= gInventory.findCategoryUUIDForType(LLFolderType::FT_OBJECT); + U32 nextOwnerPerm = LLPermissions::DEFAULT.getMaskNextOwner(); + + tid.generate(); + + LLPointer<LLInventoryCallback> cb = new LLSettingsInventoryCB([settings, callback](const LLUUID &inventoryId) { + LLSettingsVOBase::onInventoryItemCreated(inventoryId, settings, callback); + }); + + 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, inventory_result_fn callback) +{ + // We need to update some inventory stuff here.... maybe. + updateInventoryItem(settings, inventoryId, callback); +} + +void LLSettingsVOBase::updateInventoryItem(const LLSettingsBase::ptr_t &settings, LLUUID inv_item_id, inventory_result_fn callback) +{ + 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 (!LLEnvironment::instance().isInventoryEnabled()) + { + 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<LLBufferedAssetUploadInfo>(inv_item_id, LLAssetType::AT_SETTINGS, buffer.str(), + [settings, callback](LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD response) { + LLSettingsVOBase::onAgentAssetUploadComplete(itemId, newAssetId, newItemId, response, settings, callback); + }); + + LLViewerAssetUpload::EnqueueInventoryUpload(agent_url, uploadInfo); +} + +void LLSettingsVOBase::updateInventoryItem(const LLSettingsBase::ptr_t &settings, LLUUID object_id, LLUUID inv_item_id, inventory_result_fn callback) +{ + 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 (!LLEnvironment::instance().isInventoryEnabled()) + { + LL_WARNS("SETTINGS") << "Region does not support settings inventory objects." << LL_ENDL; + return; + } + + std::stringstream buffer; + LLSD settingdata(settings->getSettings()); + + LL_WARNS("LAPRAS") << "Sending '" << settingdata << "' for asset." << LL_ENDL; + + LLSDSerialize::serialize(settingdata, buffer, LLSDSerialize::LLSD_NOTATION); + + LLResourceUploadInfo::ptr_t uploadInfo = std::make_shared<LLBufferedAssetUploadInfo>(object_id, inv_item_id, LLAssetType::AT_SETTINGS, buffer.str(), + [settings, callback](LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response) { + LLSettingsVOBase::onTaskAssetUploadComplete(itemId, taskId, newAssetId, response, settings, callback); + }); + + LLViewerAssetUpload::EnqueueInventoryUpload(agent_url, uploadInfo); +} + +void LLSettingsVOBase::onAgentAssetUploadComplete(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD response, LLSettingsBase::ptr_t psettings, inventory_result_fn callback) +{ + LL_WARNS("SETTINGS") << "itemId:" << itemId << " newAssetId:" << newAssetId << " newItemId:" << newItemId << " response:" << response << LL_ENDL; + if (callback) + callback( newAssetId, itemId, LLUUID::null, response ); +} + +void LLSettingsVOBase::onTaskAssetUploadComplete(LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response, LLSettingsBase::ptr_t psettings, inventory_result_fn callback) +{ + LL_WARNS("SETTINGS") << "Upload to task complete!" << LL_ENDL; + if (callback) + callback(newAssetId, itemId, taskId, response); +} + + +void LLSettingsVOBase::getSettingsAsset(const LLUUID &assetId, LLSettingsVOBase::asset_download_fn callback) +{ + gAssetStorage->getAssetData(assetId, LLAssetType::AT_SETTINGS, + [callback](LLVFS *vfs, const LLUUID &asset_id, LLAssetType::EType, void *, S32 status, LLExtStat ext_status) + { onAssetDownloadComplete(vfs, asset_id, status, ext_status, callback); }, + nullptr, true); + +} + +void LLSettingsVOBase::onAssetDownloadComplete(LLVFS *vfs, const LLUUID &asset_id, S32 status, LLExtStat ext_status, LLSettingsVOBase::asset_download_fn callback) +{ + LLSettingsBase::ptr_t settings; + if (!status) + { + LLVFile file(vfs, asset_id, LLAssetType::AT_SETTINGS, LLVFile::READ); + S32 size = file.getSize(); + + std::string buffer(size + 1, '\0'); + file.read((U8 *)buffer.data(), size); + + std::stringstream llsdstream(buffer); + LLSD llsdsettings; + + if (LLSDSerialize::deserialize(llsdsettings, llsdstream, -1)) + { + settings = createFromLLSD(llsdsettings); + } + + if (!settings) + { + status = 1; + LL_WARNS("SETTINGS") << "Unable to creat settings object." << LL_ENDL; + } + + } + else + { + LL_WARNS("SETTINGS") << "Error retrieving asset asset_id. Status code=" << status << "(" << LLAssetStorage::getErrorString(status) << ") ext_status=" << ext_status << LL_ENDL; + } + callback(asset_id, settings, status, ext_status); +} + + +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 LLSettingsBase::ptr_t(); + } + + return createFromLLSD(settings); +} + +LLSettingsBase::ptr_t LLSettingsVOBase::createFromLLSD(const LLSD &settings) +{ + if (!settings.has(SETTING_TYPE)) + { + LL_WARNS("SETTINGS") << "No settings type in LLSD" << LL_ENDL; + return LLSettingsBase::ptr_t(); + } + + std::string settingtype = settings[SETTING_TYPE].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 '" << settingtype << "'." << LL_ENDL; + return LLSettingsBase::ptr_t(); + +} + +//========================================================================= +LLSettingsVOSky::LLSettingsVOSky(const LLSD &data, bool isAdvanced) +: LLSettingsSky(data) +, m_isAdvanced(isAdvanced) +{ +} + +LLSettingsVOSky::LLSettingsVOSky() +: LLSettingsSky() +, m_isAdvanced(false) +{ +} + +//------------------------------------------------------------------------- +LLSettingsSky::ptr_t LLSettingsVOSky::buildSky(LLSD settings) +{ + LLSettingsSky::validation_list_t validations = LLSettingsSky::validationList(); + + LLSD results = LLSettingsBase::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<LLSettingsVOSky>(settings, true); +} + + +LLSettingsSky::ptr_t LLSettingsVOSky::buildFromLegacyPreset(const std::string &name, const LLSD &legacy) +{ + + LLSD newsettings = LLSettingsSky::translateLegacySettings(legacy); + + newsettings[SETTING_NAME] = name; + + LLSettingsSky::validation_list_t validations = LLSettingsSky::validationList(); + LLSD results = LLSettingsBase::settingValidation(newsettings, validations); + if (!results["success"].asBoolean()) + { + LL_WARNS("SETTINGS") << "Sky setting validation failed!\n" << results << LL_ENDL; + LLSettingsSky::ptr_t(); + } + + LLSettingsSky::ptr_t skyp = std::make_shared<LLSettingsVOSky>(newsettings); + +#ifdef VERIFY_LEGACY_CONVERSION + LLSD oldsettings = LLSettingsVOSky::convertToLegacy(skyp, isAdvanced()); + + if (!llsd_equals(legacy, oldsettings)) + { + LL_WARNS("SKY") << "Conversion to/from legacy does not match!\n" + << "Old: " << legacy + << "new: " << oldsettings << LL_ENDL; + } + +#endif + + return skyp; +} + +LLSettingsSky::ptr_t LLSettingsVOSky::buildDefaultSky() +{ + LLSD settings = LLSettingsSky::defaults(); + settings[SETTING_NAME] = std::string("_default_"); + + LLSettingsSky::validation_list_t validations = LLSettingsSky::validationList(); + LLSD results = LLSettingsBase::settingValidation(settings, validations); + if (!results["success"].asBoolean()) + { + LL_WARNS("SETTINGS") << "Sky setting validation failed!\n" << results << LL_ENDL; + LLSettingsSky::ptr_t(); + } + + LLSettingsSky::ptr_t skyp = std::make_shared<LLSettingsVOSky>(settings); + return skyp; +} + +LLSettingsSky::ptr_t LLSettingsVOSky::buildClone() +{ + LLSD settings = cloneSettings(); + + LLSettingsSky::validation_list_t validations = LLSettingsSky::validationList(); + LLSD results = LLSettingsBase::settingValidation(settings, validations); + if (!results["success"].asBoolean()) + { + LL_WARNS("SETTINGS") << "Sky setting validation failed!\n" << results << LL_ENDL; + LLSettingsSky::ptr_t(); + } + + LLSettingsSky::ptr_t skyp = std::make_shared<LLSettingsVOSky>(settings); + return skyp; +} + +void LLSettingsVOSky::convertAtmosphericsToLegacy(LLSD& legacy, LLSD& settings) +{ +// LEGACY_ATMOSPHERICS + // These will need to be inferred from new settings' density profiles + legacy[SETTING_AMBIENT] = ensureArray4(settings[SETTING_AMBIENT], 1.0f); + legacy[SETTING_BLUE_DENSITY] = ensureArray4(settings[SETTING_BLUE_DENSITY], 1.0); + legacy[SETTING_BLUE_HORIZON] = ensureArray4(settings[SETTING_BLUE_HORIZON], 1.0); + legacy[SETTING_DENSITY_MULTIPLIER] = LLSDArray(settings[SETTING_DENSITY_MULTIPLIER].asReal())(0.0f)(0.0f)(1.0f); + legacy[SETTING_DISTANCE_MULTIPLIER] = LLSDArray(settings[SETTING_DISTANCE_MULTIPLIER].asReal())(0.0f)(0.0f)(1.0f); + legacy[SETTING_HAZE_DENSITY] = LLSDArray(settings[SETTING_HAZE_DENSITY])(0.0f)(0.0f)(1.0f); + legacy[SETTING_HAZE_HORIZON] = LLSDArray(settings[SETTING_HAZE_HORIZON])(0.0f)(0.0f)(1.0f); + + //legacy[SETTING_AMBIENT] = LLColor4::black.getValue(); + //legacy[SETTING_BLUE_DENSITY] = LLColor4(0.2447, 0.4487, 0.7599, 0.0).getValue(); + //legacy[SETTING_BLUE_HORIZON] = LLColor4(0.4954, 0.4954, 0.6399, 0.0).getValue(); + //legacy[SETTING_HAZE_DENSITY] = LLSDArray(0.6999f)(0.0f)(0.0f)(1.0f); + //legacy[SETTING_HAZE_HORIZON] = LLSDArray(0.1899f)(0.0f)(0.0f)(1.0f); + //legacy[SETTING_DENSITY_MULTIPLIER] = LLSDArray(0.0001f)(0.0f)(0.0f)(1.0f);LLSD::Real(0.0001); + //legacy[SETTING_DISTANCE_MULTIPLIER] = LLSDArray(0.8f)(0.0f)(0.0f)(1.0f); +} + +LLSD LLSettingsVOSky::convertToLegacy(const LLSettingsSky::ptr_t &psky, bool isAdvanced) +{ + LLSD legacy(LLSD::emptyMap()); + LLSD settings = psky->getSettings(); + + convertAtmosphericsToLegacy(legacy, settings); + + legacy[SETTING_CLOUD_COLOR] = ensureArray4(settings[SETTING_CLOUD_COLOR], 1.0); + legacy[SETTING_CLOUD_POS_DENSITY1] = ensureArray4(settings[SETTING_CLOUD_POS_DENSITY1], 1.0); + legacy[SETTING_CLOUD_POS_DENSITY2] = ensureArray4(settings[SETTING_CLOUD_POS_DENSITY2], 1.0); + legacy[SETTING_CLOUD_SCALE] = LLSDArray(settings[SETTING_CLOUD_SCALE])(LLSD::Real(0.0))(LLSD::Real(0.0))(LLSD::Real(1.0)); + legacy[SETTING_CLOUD_SCROLL_RATE] = settings[SETTING_CLOUD_SCROLL_RATE]; + legacy[SETTING_LEGACY_ENABLE_CLOUD_SCROLL] = LLSDArray(LLSD::Boolean(!is_approx_zero(settings[SETTING_CLOUD_SCROLL_RATE][0].asReal()))) + (LLSD::Boolean(!is_approx_zero(settings[SETTING_CLOUD_SCROLL_RATE][1].asReal()))); + legacy[SETTING_CLOUD_SHADOW] = LLSDArray(settings[SETTING_CLOUD_SHADOW].asReal())(0.0f)(0.0f)(1.0f); + legacy[SETTING_GAMMA] = LLSDArray(settings[SETTING_GAMMA])(0.0f)(0.0f)(1.0f); + legacy[SETTING_GLOW] = ensureArray4(settings[SETTING_GLOW], 1.0); + legacy[SETTING_LIGHT_NORMAL] = ensureArray4(psky->getLightDirection().getValue(), 0.0f); + legacy[SETTING_MAX_Y] = LLSDArray(settings[SETTING_MAX_Y])(0.0f)(0.0f)(1.0f); + legacy[SETTING_STAR_BRIGHTNESS] = settings[SETTING_STAR_BRIGHTNESS]; + legacy[SETTING_SUNLIGHT_COLOR] = ensureArray4(settings[SETTING_SUNLIGHT_COLOR], 1.0f); + + LLSettingsSky::azimalt_t azialt = psky->getSunRotationAzAl(); + + legacy[SETTING_LEGACY_EAST_ANGLE] = azialt.first; + legacy[SETTING_LEGACY_SUN_ANGLE] = azialt.second; + + return legacy; +} + +//------------------------------------------------------------------------- +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()) + { +// LEGACY_ATMOSPHERICS + 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_HAZE_DENSITY] = LLShaderMgr::HAZE_DENSITY; + param_map[SETTING_HAZE_HORIZON] = LLShaderMgr::HAZE_HORIZON; + param_map[SETTING_DENSITY_MULTIPLIER] = LLShaderMgr::DENSITY_MULTIPLIER; + param_map[SETTING_DISTANCE_MULTIPLIER] = LLShaderMgr::DISTANCE_MULTIPLIER; + + 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_GLOW] = LLShaderMgr::GLOW; + param_map[SETTING_MAX_Y] = LLShaderMgr::MAX_Y; + param_map[SETTING_SUNLIGHT_COLOR] = LLShaderMgr::SUNLIGHT_COLOR; + +// AdvancedAtmospherics TODO +// Provide mappings for new shader params here + } + + 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::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<LLSettingsVOWater>(settings); +} + +//------------------------------------------------------------------------- +LLSettingsWater::ptr_t LLSettingsVOWater::buildFromLegacyPreset(const std::string &name, const LLSD &legacy) +{ + LLSD newsettings(LLSettingsWater::translateLegacySettings(legacy)); + + newsettings[SETTING_NAME] = name; + LLSettingsWater::validation_list_t validations = LLSettingsWater::validationList(); + LLSD results = LLSettingsWater::settingValidation(newsettings, validations); + if (!results["success"].asBoolean()) + { + LL_WARNS("SETTINGS") << "Water setting validation failed!: " << results << LL_ENDL; + return LLSettingsWater::ptr_t(); + } + + LLSettingsWater::ptr_t waterp = std::make_shared<LLSettingsVOWater>(newsettings); + +#ifdef VERIFY_LEGACY_CONVERSION + LLSD oldsettings = LLSettingsVOWater::convertToLegacy(waterp); + + if (!llsd_equals(legacy, oldsettings)) + { + LL_WARNS("WATER") << "Conversion to/from legacy does not match!\n" + << "Old: " << legacy + << "new: " << oldsettings << LL_ENDL; + } + +#endif + return waterp; +} + +LLSettingsWater::ptr_t LLSettingsVOWater::buildDefaultWater() +{ + LLSD settings = LLSettingsWater::defaults(); + settings[SETTING_NAME] = std::string("_default_"); + + LLSettingsWater::validation_list_t validations = LLSettingsWater::validationList(); + LLSD results = LLSettingsWater::settingValidation(settings, validations); + if (!results["success"].asBoolean()) + { + LL_WARNS("SETTINGS") << "Water setting validation failed!: " << results << LL_ENDL; + return LLSettingsWater::ptr_t(); + } + + LLSettingsWater::ptr_t waterp = std::make_shared<LLSettingsVOWater>(settings); + + return waterp; +} + +LLSettingsWater::ptr_t LLSettingsVOWater::buildClone() +{ + LLSD settings = cloneSettings(); + LLSettingsWater::validation_list_t validations = LLSettingsWater::validationList(); + LLSD results = LLSettingsWater::settingValidation(settings, validations); + if (!results["success"].asBoolean()) + { + LL_WARNS("SETTINGS") << "Water setting validation failed!: " << results << LL_ENDL; + return LLSettingsWater::ptr_t(); + } + + LLSettingsWater::ptr_t waterp = std::make_shared<LLSettingsVOWater>(settings); + + return waterp; +} + +LLSD LLSettingsVOWater::convertToLegacy(const LLSettingsWater::ptr_t &pwater) +{ + LLSD legacy(LLSD::emptyMap()); + LLSD settings = pwater->getSettings(); + + legacy[SETTING_LEGACY_BLUR_MULTIPILER] = settings[SETTING_BLUR_MULTIPILER]; + legacy[SETTING_LEGACY_FOG_COLOR] = ensureArray4(settings[SETTING_FOG_COLOR], 1.0f); + legacy[SETTING_LEGACY_FOG_DENSITY] = settings[SETTING_FOG_DENSITY]; + legacy[SETTING_LEGACY_FOG_MOD] = settings[SETTING_FOG_MOD]; + legacy[SETTING_LEGACY_FRESNEL_OFFSET] = settings[SETTING_FRESNEL_OFFSET]; + legacy[SETTING_LEGACY_FRESNEL_SCALE] = settings[SETTING_FRESNEL_SCALE]; + legacy[SETTING_LEGACY_NORMAL_MAP] = settings[SETTING_NORMAL_MAP]; + legacy[SETTING_LEGACY_NORMAL_SCALE] = settings[SETTING_NORMAL_SCALE]; + legacy[SETTING_LEGACY_SCALE_ABOVE] = settings[SETTING_SCALE_ABOVE]; + legacy[SETTING_LEGACY_SCALE_BELOW] = settings[SETTING_SCALE_BELOW]; + legacy[SETTING_LEGACY_WAVE1_DIR] = settings[SETTING_WAVE1_DIR]; + legacy[SETTING_LEGACY_WAVE2_DIR] = settings[SETTING_WAVE2_DIR]; + + //_WARNS("LAPRAS") << "Legacy water: " << legacy << LL_ENDL; + return legacy; +} +//------------------------------------------------------------------------- +//------------------------------------------------------------------------- +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::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<LLSettingsVODay>(settings); + if (pday) + pday->initialize(); + + return pday; +} + +//------------------------------------------------------------------------- +LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyPreset(const std::string &name, const LLSD &oldsettings) +{ + LLSD newsettings(defaults()); + std::set<std::string> framenames; + + newsettings[SETTING_NAME] = name; + + LLSD watertrack = LLSDArray( + LLSDMap(SETTING_KEYKFRAME, LLSD::Real(0.0f)) + (SETTING_KEYNAME, "water:Default")); + + LLSD skytrack = LLSD::emptyArray(); + + for (LLSD::array_const_iterator it = oldsettings.beginArray(); it != oldsettings.endArray(); ++it) + { + std::string framename = (*it)[1].asString(); + LLSD entry = LLSDMap(SETTING_KEYKFRAME, (*it)[0].asReal()) + (SETTING_KEYNAME, "sky:" + framename); + framenames.insert(framename); + skytrack.append(entry); + } + + newsettings[SETTING_TRACKS] = LLSDArray(watertrack)(skytrack); + + LLSD frames(LLSD::emptyMap()); + + { + LLSettingsWater::ptr_t pwater = LLEnvironment::instance().findWaterByName("Default"); + frames["water:Default"] = pwater->getSettings(); + } + + for (std::set<std::string>::iterator itn = framenames.begin(); itn != framenames.end(); ++itn) + { + LLSettingsSky::ptr_t psky = LLEnvironment::instance().findSkyByName(*itn); + frames["sky:" + (*itn)] = psky->getSettings(); + } + + newsettings[SETTING_FRAMES] = frames; + + LLSettingsDay::validation_list_t validations = LLSettingsDay::validationList(); + LLSD results = LLSettingsDay::settingValidation(newsettings, validations); + if (!results["success"].asBoolean()) + { + LL_WARNS("SETTINGS") << "Day setting validation failed!: " << results << LL_ENDL; + return LLSettingsDay::ptr_t(); + } + + LLSettingsDay::ptr_t dayp = std::make_shared<LLSettingsVODay>(newsettings); + +#ifdef VERIFY_LEGACY_CONVERSION + LLSD testsettings = LLSettingsVODay::convertToLegacy(dayp); + + if (!llsd_equals(oldsettings, testsettings)) + { + LL_WARNS("DAYCYCLE") << "Conversion to/from legacy does not match!\n" + << "Old: " << oldsettings + << "new: " << testsettings << LL_ENDL; + } + +#endif + + dayp->initialize(); + + return dayp; +} + +LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyMessage(const LLUUID ®ionId, LLSD daycycle, LLSD skydefs, LLSD waterdef) +{ + LLSD frames(LLSD::emptyMap()); + + for (LLSD::map_iterator itm = skydefs.beginMap(); itm != skydefs.endMap(); ++itm) + { + LLSD newsettings = LLSettingsSky::translateLegacySettings((*itm).second); + std::string newname = "sky:" + (*itm).first; + + newsettings[SETTING_NAME] = newname; + frames[newname] = newsettings; + + LL_WARNS("SETTINGS") << "created region sky '" << newname << "'" << LL_ENDL; + } + + LLSD watersettings = LLSettingsWater::translateLegacySettings(waterdef); + std::string watername = "water:"+ watersettings[SETTING_NAME].asString(); + watersettings[SETTING_NAME] = watername; + frames[watername] = watersettings; + + LLSD watertrack = LLSDArray( + LLSDMap(SETTING_KEYKFRAME, LLSD::Real(0.0f)) + (SETTING_KEYNAME, watername)); + + LLSD skytrack(LLSD::emptyArray()); + for (LLSD::array_const_iterator it = daycycle.beginArray(); it != daycycle.endArray(); ++it) + { + LLSD entry = LLSDMap(SETTING_KEYKFRAME, (*it)[0].asReal()) + (SETTING_KEYNAME, "sky:" + (*it)[1].asString()); + skytrack.append(entry); + } + + LLSD newsettings = LLSDMap + ( SETTING_NAME, "Region (legacy)" ) + ( SETTING_TRACKS, LLSDArray(watertrack)(skytrack)) + ( SETTING_FRAMES, frames ) + ( SETTING_TYPE, "daycycle" ); + + LL_WARNS("LAPRAS") << "newsettings=" << newsettings << LL_ENDL; + + LLSettingsSky::validation_list_t validations = LLSettingsDay::validationList(); + LLSD results = LLSettingsDay::settingValidation(newsettings, validations); + if (!results["success"].asBoolean()) + { + LL_WARNS("SETTINGS") << "Day setting validation failed!:" << results << LL_ENDL; + return LLSettingsDay::ptr_t(); + } + + LLSettingsDay::ptr_t dayp = std::make_shared<LLSettingsVODay>(newsettings); + + if (dayp) + { + dayp->initialize(); + } + return dayp; +} + +LLSettingsDay::ptr_t LLSettingsVODay::buildDefaultDayCycle() +{ + LLSD settings = LLSettingsDay::defaults(); + settings[SETTING_NAME] = std::string("_default_"); + + 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 dayp = std::make_shared<LLSettingsVODay>(settings); + + dayp->initialize(); + return dayp; +} + +LLSettingsDay::ptr_t LLSettingsVODay::buildFromEnvironmentMessage(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 dayp = std::make_shared<LLSettingsVODay>(settings); + + dayp->initialize(); + return dayp; +} + + +LLSettingsDay::ptr_t LLSettingsVODay::buildClone() +{ + LLSD settings = cloneSettings(); + + 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 dayp = std::make_shared<LLSettingsVODay>(settings); + + dayp->initialize(); + return dayp; +} + +LLSD LLSettingsVODay::convertToLegacy(const LLSettingsVODay::ptr_t &pday) +{ + CycleTrack_t &trackwater = pday->getCycleTrack(TRACK_WATER); + + LLSettingsWater::ptr_t pwater; + if (!trackwater.empty()) + { + pwater = std::static_pointer_cast<LLSettingsWater>((*trackwater.begin()).second); + } + + if (!pwater) + pwater = LLSettingsVOWater::buildDefaultWater(); + + LLSD llsdwater = LLSettingsVOWater::convertToLegacy(pwater); + + CycleTrack_t &tracksky = pday->getCycleTrack(1); // first sky track + std::map<std::string, LLSettingsSky::ptr_t> skys; + + LLSD llsdcycle(LLSD::emptyArray()); + + for(CycleTrack_t::iterator it = tracksky.begin(); it != tracksky.end(); ++it) + { + size_t hash = (*it).second->getHash(); + std::stringstream name; + + name << hash; + + skys[name.str()] = std::static_pointer_cast<LLSettingsSky>((*it).second); + + F32 frame = ((tracksky.size() == 1) && (it == tracksky.begin())) ? -1.0f : (*it).first; + llsdcycle.append( LLSDArray(LLSD::Real(frame))(name.str()) ); + } + //_WARNS("LAPRAS") << "Cycle created with " << llsdcycle.size() << "entries: " << llsdcycle << LL_ENDL; + + LLSD llsdskylist(LLSD::emptyMap()); + + for (std::map<std::string, LLSettingsSky::ptr_t>::iterator its = skys.begin(); its != skys.end(); ++its) + { + LLSD llsdsky = LLSettingsVOSky::convertToLegacy((*its).second, false); + llsdsky[SETTING_NAME] = (*its).first; + + llsdskylist[(*its).first] = llsdsky; + } + + //_WARNS("LAPRAS") << "Sky map with " << llsdskylist.size() << " entries created: " << llsdskylist << LL_ENDL; + + return LLSDArray(LLSD::emptyMap())(llsdcycle)(llsdskylist)(llsdwater); +} + +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 = std::make_shared<LLSettingsVOSky>(settings); + + if (skyp->validate()) + return skyp; + + return LLSettingsSky::ptr_t(); +} + +LLSettingsWaterPtr_t LLSettingsVODay::buildWater(LLSD settings) const +{ + LLSettingsWater::ptr_t waterp = std::make_shared<LLSettingsVOWater>(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..3339aaf037 --- /dev/null +++ b/indra/newview/llsettingsvo.h @@ -0,0 +1,167 @@ +/** +* @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" + +#include "llsdserialize.h" + +#include "llextendedstatus.h" +#include <boost/signals2.hpp> + +class LLVFS; + +//========================================================================= +class LLSettingsVOBase : public LLSettingsBase +{ +public: + typedef std::function<void(LLUUID asset_id, LLSettingsBase::ptr_t settins, S32 status, LLExtStat extstat)> asset_download_fn; + typedef std::function<void(LLUUID asset_id, LLUUID inventory_id, LLUUID object_id, LLSD results)> inventory_result_fn; + + static void createInventoryItem(const LLSettingsBase::ptr_t &settings, inventory_result_fn callback = inventory_result_fn()); + + static void updateInventoryItem(const LLSettingsBase::ptr_t &settings, LLUUID inv_item_id, inventory_result_fn callback = inventory_result_fn()); + static void updateInventoryItem(const LLSettingsBase::ptr_t &settings, LLUUID object_id, LLUUID inv_item_id, inventory_result_fn callback = inventory_result_fn()); + + static void getSettingsAsset(const LLUUID &assetId, asset_download_fn callback); + + 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); + static LLSettingsBase::ptr_t createFromLLSD(const LLSD &settings); + +private: + struct SettingsSaveData + { + typedef std::shared_ptr<SettingsSaveData> 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, inventory_result_fn callback); + + static void onAgentAssetUploadComplete(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD response, LLSettingsBase::ptr_t psettings, inventory_result_fn callback); + static void onTaskAssetUploadComplete(LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response, LLSettingsBase::ptr_t psettings, inventory_result_fn callback); + + static void onAssetDownloadComplete(LLVFS *vfs, const LLUUID &asset_id, S32 status, LLExtStat ext_status, asset_download_fn callback); +}; + +//========================================================================= +class LLSettingsVOSky : public LLSettingsSky +{ +public: + LLSettingsVOSky(const LLSD &data, bool advanced = false); + + 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() override; + + static LLSD convertToLegacy(const ptr_t &, bool isAdvanced); + + bool isAdvanced() const { return m_isAdvanced; } + +protected: + LLSettingsVOSky(); + + // Interpret new settings in terms of old atmospherics params + static void convertAtmosphericsToLegacy(LLSD& legacy, LLSD& settings); + + virtual void updateSettings() override; + + virtual void applySpecial(void *) override; + + virtual parammapping_t getParameterMap() const override; + + bool m_isAdvanced = false; +}; + +//========================================================================= +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() override; + + static LLSD convertToLegacy(const ptr_t &); +protected: + LLSettingsVOWater(); + + virtual void updateSettings() override; + virtual void applySpecial(void *) override; + + virtual parammapping_t getParameterMap() const override; + + +private: + static const F32 WATER_FOG_LIGHT_CLAMP; + +}; + +//========================================================================= +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(); + static ptr_t buildFromEnvironmentMessage(LLSD settings); + virtual ptr_t buildClone() override; + + static LLSD convertToLegacy(const ptr_t &); + + virtual LLSettingsSkyPtr_t getDefaultSky() const override; + virtual LLSettingsWaterPtr_t getDefaultWater() const override; + virtual LLSettingsSkyPtr_t buildSky(LLSD) const override; + virtual LLSettingsWaterPtr_t buildWater(LLSD) const override; + virtual LLSettingsSkyPtr_t getNamedSky(const std::string &) const override; + virtual LLSettingsWaterPtr_t getNamedWater(const std::string &) const override; + +protected: + LLSettingsVODay(); +}; + + +#endif diff --git a/indra/newview/llsky.cpp b/indra/newview/llsky.cpp index 3ef89ba920..fb3123fd81 100644 --- a/indra/newview/llsky.cpp +++ b/indra/newview/llsky.cpp @@ -51,7 +51,6 @@ #include "llvosky.h" #include "llcubemap.h" #include "llviewercontrol.h" -#include "llenvmanager.h" #include "llvowlsky.h" @@ -77,7 +76,6 @@ LLSky::LLSky() mLightingGeneration = 0; mUpdatedThisFrame = TRUE; - mOverrideSimSunPosition = FALSE; mSunPhase = 0.f; } @@ -134,33 +132,13 @@ void LLSky::resetVertexBuffers() } } -void LLSky::setOverrideSun(BOOL override) -{ - if (!mOverrideSimSunPosition && override) - { - mLastSunDirection = getSunDirection(); - } - else if (mOverrideSimSunPosition && !override) - { - setSunDirection(mLastSunDirection, LLVector3::zero); - } - mOverrideSimSunPosition = override; -} - -void LLSky::setSunDirection(const LLVector3 &sun_direction, const LLVector3 &sun_ang_velocity) +void LLSky::setSunDirection(const LLVector3 &sun_direction, const LLVector3 &moon_direction) { if(mVOSkyp.notNull()) { - mVOSkyp->setSunDirection(sun_direction, sun_ang_velocity); + mVOSkyp->setSunDirection(sun_direction, moon_direction); } } - -void LLSky::setSunTargetDirection(const LLVector3 &sun_direction, const LLVector3 &sun_ang_velocity) -{ - mSunTargDir = sun_direction; -} - - LLVector3 LLSky::getSunDirection() const { if (mVOSkyp) @@ -328,13 +306,13 @@ void LLSky::init(const LLVector3 &sun_direction) LLGLState::checkStates(); LLGLState::checkTextureChannels(); - if (gSavedSettings.getBOOL("SkyOverrideSimSunPosition") || mOverrideSimSunPosition) + if (gSavedSettings.getBOOL("SkyOverrideSimSunPosition")) { - setSunDirection(mSunDefaultPosition, LLVector3(0.f, 0.f, 0.f)); + setSunDirection(mSunDefaultPosition, -mSunDefaultPosition); } else { - setSunDirection(sun_direction, LLVector3(0.f, 0.f, 0.f)); + setSunDirection(sun_direction, -sun_direction); } LLGLState::checkStates(); @@ -364,24 +342,24 @@ void LLSky::setWind(const LLVector3& average_wind) void LLSky::propagateHeavenlyBodies(F32 dt) { - if (!mOverrideSimSunPosition) - { - LLVector3 curr_dir = getSunDirection(); - LLVector3 diff = mSunTargDir - curr_dir; - const F32 dist = diff.normVec(); - if (dist > 0) - { - const F32 step = llmin (dist, 0.00005f); - //const F32 step = min (dist, 0.0001); - diff *= step; - curr_dir += diff; - curr_dir.normVec(); - if (mVOSkyp) - { - mVOSkyp->setSunDirection(curr_dir, LLVector3()); - } - } - } +// if (!mOverrideSimSunPosition) +// { +// LLVector3 curr_dir = getSunDirection(); +// LLVector3 diff = mSunTargDir - curr_dir; +// const F32 dist = diff.normVec(); +// if (dist > 0) +// { +// const F32 step = llmin (dist, 0.00005f); +// //const F32 step = min (dist, 0.0001); +// diff *= step; +// curr_dir += diff; +// curr_dir.normVec(); +// if (mVOSkyp) +// { +// mVOSkyp->setSunDirection(curr_dir); +// } +// } +// } } F32 LLSky::getSunPhase() const diff --git a/indra/newview/llsky.h b/indra/newview/llsky.h index 7b98c97840..79549948f6 100644 --- a/indra/newview/llsky.h +++ b/indra/newview/llsky.h @@ -52,10 +52,7 @@ public: void cleanup(); - void setOverrideSun(BOOL override); - BOOL getOverrideSun() { return mOverrideSimSunPosition; } - void setSunDirection(const LLVector3 &sun_direction, const LLVector3 &sun_ang_velocity); - void setSunTargetDirection(const LLVector3 &sun_direction, const LLVector3 &sun_ang_velocity); + void setSunDirection(const LLVector3 &sun_direction, const LLVector3 &moon_direction); LLColor4 getFogColor() const; @@ -97,8 +94,6 @@ public: LLPointer<LLVOWLSky> mVOWLSkyp; - LLVector3 mSunTargDir; - // Legacy stuff LLVector3 mSunDefaultPosition; @@ -106,12 +101,9 @@ public: static const F32 NIGHTTIME_ELEVATION_COS; protected: - BOOL mOverrideSimSunPosition; - F32 mSunPhase; LLColor4 mFogColor; // Color to use for fog and haze - LLVector3 mLastSunDirection; }; extern LLSky gSky; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 62560a2fc8..deebd91198 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -180,8 +180,6 @@ #include "llnamebox.h" #include "llnameeditor.h" #include "llpostprocess.h" -#include "llwlparammanager.h" -#include "llwaterparammanager.h" #include "llagentlanguage.h" #include "llwearable.h" #include "llinventorybridge.h" @@ -197,6 +195,8 @@ #include "llexperiencelog.h" #include "llcleanup.h" +#include "llenvironment.h" + #include "llstacktrace.h" #if LL_WINDOWS @@ -1466,7 +1466,7 @@ bool idle_startup() LLGLState::checkStates(); LLGLState::checkTextureChannels(); - LLEnvManagerNew::getInstance()->usePrefs(); // Load all presets and settings + LLEnvironment::instance().loadPreferences(); gSky.init(initial_sun_direction); LLGLState::checkStates(); diff --git a/indra/newview/lltoolgun.cpp b/indra/newview/lltoolgun.cpp index 6c9155be85..6903e69d46 100644 --- a/indra/newview/lltoolgun.cpp +++ b/indra/newview/lltoolgun.cpp @@ -107,8 +107,8 @@ BOOL LLToolGun::handleHover(S32 x, S32 y, MASK mask) if (gSavedSettings.getBOOL("MouseSun")) { - gSky.setSunDirection(LLViewerCamera::getInstance()->getAtAxis(), LLVector3(0.f, 0.f, 0.f)); - gSky.setOverrideSun(TRUE); + LLVector3 sunpos = LLViewerCamera::getInstance()->getAtAxis(); + gSky.setSunDirection(sunpos, -sunpos); gSavedSettings.setVector3("SkySunDefaultPosition", LLViewerCamera::getInstance()->getAtAxis()); } 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 346b2c0d1b..a91bf04bfa 100644 --- a/indra/newview/llviewerassetupload.cpp +++ b/indra/newview/llviewerassetupload.cpp @@ -483,7 +483,7 @@ LLBufferedAssetUploadInfo::LLBufferedAssetUploadInfo(LLUUID itemId, LLAssetType: mTaskId(LLUUID::null), mContents(buffer), mInvnFinishFn(finish), - mTaskFinishFn(NULL), + mTaskFinishFn(nullptr), mStoredToVFS(false) { setItemId(itemId); @@ -497,7 +497,7 @@ LLBufferedAssetUploadInfo::LLBufferedAssetUploadInfo(LLUUID itemId, LLPointer<LL mTaskId(LLUUID::null), mContents(), mInvnFinishFn(finish), - mTaskFinishFn(NULL), + mTaskFinishFn(nullptr), mStoredToVFS(false) { setItemId(itemId); @@ -530,7 +530,7 @@ LLBufferedAssetUploadInfo::LLBufferedAssetUploadInfo(LLUUID taskId, LLUUID itemI mTaskUpload(true), mTaskId(taskId), mContents(buffer), - mInvnFinishFn(NULL), + mInvnFinishFn(nullptr), mTaskFinishFn(finish), mStoredToVFS(false) { diff --git a/indra/newview/llviewerassetupload.h b/indra/newview/llviewerassetupload.h index 43e23a0d42..e18b75489a 100644 --- a/indra/newview/llviewerassetupload.h +++ b/indra/newview/llviewerassetupload.h @@ -40,7 +40,7 @@ class LLResourceUploadInfo { public: - typedef boost::shared_ptr<LLResourceUploadInfo> ptr_t; + typedef std::shared_ptr<LLResourceUploadInfo> ptr_t; LLResourceUploadInfo( LLTransactionID transactId, @@ -165,8 +165,8 @@ private: class LLBufferedAssetUploadInfo : public LLResourceUploadInfo { public: - typedef boost::function<void(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD response)> invnUploadFinish_f; - typedef boost::function<void(LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response)> taskUploadFinish_f; + typedef std::function<void(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD response)> invnUploadFinish_f; + typedef std::function<void(LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response)> taskUploadFinish_f; LLBufferedAssetUploadInfo(LLUUID itemId, LLAssetType::EType assetType, std::string buffer, invnUploadFinish_f finish); LLBufferedAssetUploadInfo(LLUUID itemId, LLPointer<LLImageFormatted> image, invnUploadFinish_f finish); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 96ef160c72..46a8d75595 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -74,11 +74,11 @@ #include "llviewerregion.h" #include "lldrawpoolwater.h" #include "lldrawpoolbump.h" -#include "llwlparammanager.h" -#include "llwaterparammanager.h" #include "llpostprocess.h" #include "llscenemonitor.h" +#include "llenvironment.h" + extern LLPointer<LLViewerTexture> gStartTexture; extern bool gShiftFrame; @@ -200,8 +200,7 @@ void display_update_camera() gViewerWindow->setup3DRender(); // update all the sky/atmospheric/water settings - LLWLParamManager::getInstance()->update(LLViewerCamera::getInstance()); - LLWaterParamManager::getInstance()->update(LLViewerCamera::getInstance()); + LLEnvironment::instance().update(LLViewerCamera::getInstance()); // Update land visibility too LLWorld::getInstance()->setLandFarClip(final_far); @@ -921,7 +920,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) gPipeline.mScreen.bindTarget(); if (LLPipeline::sUnderWaterRender && !gPipeline.canUseWindLightShaders()) { - const LLColor4 &col = LLDrawPoolWater::sWaterFogColor; + const LLColor4 &col = LLEnvironment::instance().getCurrentWater()->getFogColor(); glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f); } gPipeline.mScreen.clear(); diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 0ebacddd9b..528987f3bf 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -55,18 +55,17 @@ #include "llfloaterchatvoicevolume.h" #include "llfloaterconversationlog.h" #include "llfloaterconversationpreview.h" -#include "llfloaterdeleteenvpreset.h" #include "llfloaterdeleteprefpreset.h" #include "llfloaterdestinations.h" #include "llfloatereditdaycycle.h" -#include "llfloatereditsky.h" -#include "llfloatereditwater.h" +#include "llfloatereditextdaycycle.h" #include "llfloaterenvironmentsettings.h" #include "llfloaterexperienceprofile.h" #include "llfloaterexperiences.h" #include "llfloaterexperiencepicker.h" #include "llfloaterevent.h" #include "llfloaterfacebook.h" +#include "llfloaterfixedenvironment.h" #include "llfloaterflickr.h" #include "llfloaterfonttest.h" #include "llfloatergesture.h" @@ -222,11 +221,15 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("env_post_process", "floater_post_process.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPostProcess>); LLFloaterReg::add("env_settings", "floater_environment_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEnvironmentSettings>); - LLFloaterReg::add("env_delete_preset", "floater_delete_env_preset.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDeleteEnvPreset>); - LLFloaterReg::add("env_edit_sky", "floater_edit_sky_preset.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEditSky>); - LLFloaterReg::add("env_edit_water", "floater_edit_water_preset.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEditWater>); LLFloaterReg::add("env_edit_day_cycle", "floater_edit_day_cycle.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEditDayCycle>); + LLFloaterReg::add("env_fixed_environmentent_water", "floater_fixedenvironment.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFixedEnvironmentWater>); + LLFloaterReg::add("env_fixed_environmentent_sky", "floater_fixedenvironment.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFixedEnvironmentSky>); + //LLFloaterReg::add("env_fixed_environmentent", "floater_fixedenvironment.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFixedEnvironment>); + + LLFloaterReg::add("env_edit_extdaycycle", "floater_edit_ext_day_cycle.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEditExtDayCycle>); + + LLFloaterReg::add("event", "floater_event.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEvent>); LLFloaterReg::add("experiences", "floater_experiences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterExperiences>); LLFloaterReg::add("experience_profile", "floater_experienceprofile.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterExperienceProfile>); diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 1ab7ec0156..ec457c1b5d 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -70,6 +70,7 @@ #include "llfloaterperms.h" #include "llclipboard.h" #include "llhttpretrypolicy.h" +#include "llsettingsvo.h" // do-nothing ops for use in callbacks. void no_op_inventory_func(const LLUUID&) {} @@ -1097,7 +1098,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<LLInventoryCallback> cb) { @@ -1132,7 +1133,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 +1147,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<LLInventoryCallback> cb) +{ + create_inventory_item(agent_id, session_id, parent, transaction_id, + name, desc, asset_type, LLInventoryType::IT_WEARABLE, static_cast<U8>(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::type_e settype, + U32 next_owner_perm, + LLPointer<LLInventoryCallback> cb) +{ + create_inventory_item(agent_id, session_id, parent, transaction_id, + name, desc, LLAssetType::AT_SETTINGS, LLInventoryType::IT_SETTINGS, + static_cast<U8>(settype), next_owner_perm, cb); +} + + void copy_inventory_item( const LLUUID& agent_id, const LLUUID& current_owner, @@ -1700,7 +1728,7 @@ void create_new_item(const std::string& name, desc, asset_type, inv_type, - NOT_WEARABLE, + NO_INV_SUBTYPE, next_owner_perm, cb); } @@ -1793,6 +1821,40 @@ void menu_create_inventory_item(LLInventoryPanel* panel, LLFolderBridge *bridge, LLInventoryType::IT_GESTURE, PERM_ALL); // overridden in create_new_item } + else if (("sky" == type_name) || ("water" == type_name) || ("daycycle" == type_name)) + { + LL_WARNS("LAPRAS") << "Creating settings object of type: '" << type_name << "'" << LL_ENDL; + + LLSettingsBase::ptr_t settings; + std::string name; + + if ("sky" == type_name) + { + settings = LLSettingsVOSky::buildDefaultSky(); + name = LLTrans::getString("New Sky"); + } + else if ("water" == type_name) + { + settings = LLSettingsVOWater::buildDefaultWater(); + name = LLTrans::getString("New Water"); + } + else if ("daycycle" == type_name) + { + settings = LLSettingsVODay::buildDefaultDayCycle(); + name = LLTrans::getString("New Daycycle"); + } + else + LL_ERRS(LOG_INV) << "Unknown settings type: '" << type_name << "'" << LL_ENDL; + + if (!settings) + { + LL_WARNS(LOG_INV) << "Unable to create a default setting object of type '" << type_name << "'" << LL_ENDL; + return; + } + + settings->setName(name); + LLSettingsVOBase::createInventoryItem(settings); + } else { // Use for all clothing and body parts. Adding new wearable types requires updating LLWearableDictionary. @@ -1973,6 +2035,19 @@ LLWearableType::EType LLViewerInventoryItem::getWearableType() const return LLWearableType::inventoryFlagsToWearableType(getFlags()); } +bool LLViewerInventoryItem::isSettingsType() const +{ + return (getInventoryType() == LLInventoryType::IT_SETTINGS); +} + +LLSettingsType::type_e LLViewerInventoryItem::getSettingsType() const +{ + if (!isSettingsType()) + { + return LLSettingsType::ST_NONE; + } + return LLSettingsType::fromInventoryFlags(getFlags()); +} time_t LLViewerInventoryItem::getCreationDate() const { diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h index b3053e365b..d537b28682 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.hpp> // boost::signals2::trackable @@ -74,6 +75,9 @@ public: virtual LLInventoryType::EType getInventoryType() const; virtual bool isWearableType() const; virtual LLWearableType::EType getWearableType() const; + virtual bool isSettingsType() const; + virtual LLSettingsType::type_e getSettingsType() const; + virtual U32 getFlags() const; virtual time_t getCreationDate() const; virtual U32 getCRC32() const; // really more of a checksum. @@ -295,7 +299,7 @@ public: // virtual void fire(const LLUUID& item_id) -{ + { mFireFunc(item_id); } @@ -336,17 +340,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<LLInventoryCallback> 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<LLInventoryCallback> 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::type_e settype, + U32 next_owner_perm, LLPointer<LLInventoryCallback> cb); + + void create_inventory_callingcard(const LLUUID& avatar_id, const LLUUID& parent = LLUUID::null, LLPointer<LLInventoryCallback> cb=NULL); /** diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index e973363e0f..ce1e740425 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -51,9 +51,8 @@ #include "llagentpilot.h" #include "llcompilequeue.h" #include "llconsole.h" -#include "lldaycyclemanager.h" #include "lldebugview.h" -#include "llenvmanager.h" +#include "llenvironment.h" #include "llfacebookconnect.h" #include "llfilepicker.h" #include "llfirstuse.h" @@ -121,9 +120,6 @@ #include "llworldmap.h" #include "pipeline.h" #include "llviewerjoystick.h" -#include "llwaterparammanager.h" -#include "llwlanimator.h" -#include "llwlparammanager.h" #include "llfloatercamera.h" #include "lluilistener.h" #include "llappearancemgr.h" @@ -135,6 +131,7 @@ #include "llstartup.h" #include "boost/unordered_map.hpp" #include "llcleanup.h" +#include "llviewershadermgr.h" using namespace LLAvatarAppearanceDefines; @@ -8394,32 +8391,35 @@ class LLWorldEnvSettings : public view_listener_t if (tod == "sunrise") { - LLEnvManagerNew::instance().setUseSkyPreset("Sunrise"); + LLSettingsSky::ptr_t psky = LLEnvironment::instance().findSkyByName("Sunrise"); + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, psky); + LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); } else if (tod == "noon") { - LLEnvManagerNew::instance().setUseSkyPreset("Midday"); - } + LLSettingsSky::ptr_t psky = LLEnvironment::instance().findSkyByName("Midday"); + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, psky); + LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); + } else if (tod == "sunset") { - LLEnvManagerNew::instance().setUseSkyPreset("Sunset"); - } + LLSettingsSky::ptr_t psky = LLEnvironment::instance().findSkyByName("Sunset"); + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, psky); + LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); + } else if (tod == "midnight") { - LLEnvManagerNew::instance().setUseSkyPreset("Midnight"); - } + LLSettingsSky::ptr_t psky = LLEnvironment::instance().findSkyByName("Midnight"); + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, psky); + LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); + } else { - LLEnvManagerNew &envmgr = LLEnvManagerNew::instance(); - // reset all environmental settings to track the region defaults, make this reset 'sticky' like the other sun settings. - bool use_fixed_sky = false; - bool use_region_settings = true; - envmgr.setUserPrefs(envmgr.getWaterPresetName(), - envmgr.getSkyPresetName(), - envmgr.getDayCycleName(), - use_fixed_sky, use_region_settings); - } - + LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_LOCAL); + LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); + } + + LLEnvironment::instance().updateEnvironment(); return true; } }; @@ -8431,37 +8431,38 @@ class LLWorldEnableEnvSettings : public view_listener_t bool result = false; std::string tod = userdata.asString(); - if (LLEnvManagerNew::instance().getUseRegionSettings()) + LLSettingsSky::ptr_t sky = LLEnvironment::instance().getEnvironmentFixedSky(LLEnvironment::ENV_LOCAL); + + if (!sky) { return (tod == "region"); } - if (LLEnvManagerNew::instance().getUseFixedSky()) + std::string skyname = (sky) ? sky->getName() : ""; + + if (tod == "sunrise") { - if (tod == "sunrise") - { - result = (LLEnvManagerNew::instance().getSkyPresetName() == "Sunrise"); - } - else if (tod == "noon") - { - result = (LLEnvManagerNew::instance().getSkyPresetName() == "Midday"); - } - else if (tod == "sunset") - { - result = (LLEnvManagerNew::instance().getSkyPresetName() == "Sunset"); - } - else if (tod == "midnight") - { - result = (LLEnvManagerNew::instance().getSkyPresetName() == "Midnight"); - } - else if (tod == "region") - { - return false; - } - else - { - LL_WARNS() << "Unknown time-of-day item: " << tod << LL_ENDL; - } + result = (skyname == "Sunrise"); + } + else if (tod == "noon") + { + result = (skyname == "Midday"); + } + else if (tod == "sunset") + { + result = (skyname == "Sunset"); + } + else if (tod == "midnight") + { + result = (skyname == "Midnight"); + } + else if (tod == "region") + { + return false; + } + else + { + LL_WARNS() << "Unknown time-of-day item: " << tod << LL_ENDL; } return result; } @@ -8473,41 +8474,30 @@ class LLWorldEnvPreset : public view_listener_t { std::string item = userdata.asString(); +// *LAPRAS* These go away! Keep for the moment. if (item == "new_water") { - LLFloaterReg::showInstance("env_edit_water", "new"); + LLFloaterReg::showInstance("env_fixed_environmentent_water", "new"); } else if (item == "edit_water") { - LLFloaterReg::showInstance("env_edit_water", "edit"); - } - else if (item == "delete_water") - { - LLFloaterReg::showInstance("env_delete_preset", "water"); - } + LLFloaterReg::showInstance("env_fixed_environmentent_water", "edit"); + } else if (item == "new_sky") { - LLFloaterReg::showInstance("env_edit_sky", "new"); - } + LLFloaterReg::showInstance("env_fixed_environmentent_sky", "new"); + } else if (item == "edit_sky") { - LLFloaterReg::showInstance("env_edit_sky", "edit"); - } - else if (item == "delete_sky") - { - LLFloaterReg::showInstance("env_delete_preset", "sky"); - } + LLFloaterReg::showInstance("env_fixed_environmentent_sky", "edit"); + } else if (item == "new_day_cycle") { - LLFloaterReg::showInstance("env_edit_day_cycle", "new"); + LLFloaterReg::showInstance("env_edit_extdaycycle", "new"); } else if (item == "edit_day_cycle") { - LLFloaterReg::showInstance("env_edit_day_cycle", "edit"); - } - else if (item == "delete_day_cycle") - { - LLFloaterReg::showInstance("env_delete_preset", "day_cycle"); + LLFloaterReg::showInstance("env_edit_extdaycycle", "edit"); } else { @@ -8522,30 +8512,6 @@ class LLWorldEnableEnvPreset : public view_listener_t { bool handleEvent(const LLSD& userdata) { - std::string item = userdata.asString(); - - if (item == "delete_water") - { - LLWaterParamManager::preset_name_list_t user_waters; - LLWaterParamManager::instance().getUserPresetNames(user_waters); - return !user_waters.empty(); - } - else if (item == "delete_sky") - { - LLWLParamManager::preset_name_list_t user_skies; - LLWLParamManager::instance().getUserPresetNames(user_skies); - return !user_skies.empty(); - } - else if (item == "delete_day_cycle") - { - LLDayCycleManager::preset_name_list_t user_days; - LLDayCycleManager::instance().getUserPresetNames(user_days); - return !user_days.empty(); - } - else - { - LL_WARNS() << "Unknown item" << LL_ENDL; - } return false; } 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<LLNewFileResourceUploadInfo>( 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<LLNewFileResourceUploadInfo>( 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<LLInventoryCallback>(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/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 0f326efe09..e4c71c1648 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -3417,10 +3417,9 @@ void process_time_synch(LLMessageSystem *mesgsys, void **user_data) LL_DEBUGS("Windlight Sync") << "Sun phase: " << phase << " rad = " << fmodf(phase / F_TWO_PI + 0.25, 1.f) * 24.f << " h" << LL_ENDL; gSky.setSunPhase(phase); - gSky.setSunTargetDirection(sun_direction, sun_ang_velocity); - if ( !(gSavedSettings.getBOOL("SkyOverrideSimSunPosition") || gSky.getOverrideSun()) ) + if ( !gSavedSettings.getBOOL("SkyOverrideSimSunPosition") ) { - gSky.setSunDirection(sun_direction, sun_ang_velocity); + gSky.setSunDirection(sun_direction, -sun_direction); } } diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index eea382aac1..8e8d1ff024 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -78,6 +78,7 @@ #include "llcoros.h" #include "lleventcoro.h" #include "llcorehttputil.h" +#include "llsettingsdaycycle.h" #ifdef LL_WINDOWS #pragma warning(disable:4355) @@ -2830,6 +2831,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("EnvironmentSettings"); capabilityNames.append("EstateChangeInfo"); capabilityNames.append("EventQueueGet"); + capabilityNames.append("ExtEnvironment"); capabilityNames.append("FacebookConnect"); capabilityNames.append("FlickrConnect"); capabilityNames.append("TwitterConnect"); @@ -2903,7 +2905,9 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("UpdateNotecardTaskInventory"); 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/llviewerregion.h b/indra/newview/llviewerregion.h index 302647215f..caf0b0cbf1 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -42,6 +42,8 @@ #include "m4math.h" // LLMatrix4 #include "llframetimer.h" +#include "llsettingsdaycycle.h" + // Surface id's #define LAND 1 #define WATER 2 @@ -71,320 +73,322 @@ class LLViewerRegionImpl; class LLViewerOctreeGroup; class LLVOCachePartition; -class LLViewerRegion: public LLCapabilityProvider // implements this interface +class LLViewerRegion : public LLCapabilityProvider // implements this interface { public: - //MUST MATCH THE ORDER OF DECLARATION IN CONSTRUCTOR - typedef enum - { - PARTITION_HUD=0, - PARTITION_TERRAIN, - PARTITION_VOIDWATER, - PARTITION_WATER, - PARTITION_TREE, - PARTITION_PARTICLE, - PARTITION_GRASS, - PARTITION_VOLUME, - PARTITION_BRIDGE, - PARTITION_HUD_PARTICLE, - PARTITION_VO_CACHE, - PARTITION_NONE, - NUM_PARTITIONS - } eObjectPartitions; - - typedef boost::signals2::signal<void(const LLUUID& region_id)> caps_received_signal_t; - - LLViewerRegion(const U64 &handle, - const LLHost &host, - const U32 surface_grid_width, - const U32 patch_grid_width, - const F32 region_width_meters); - ~LLViewerRegion(); - - // Call this after you have the region name and handle. - void loadObjectCache(); - void saveObjectCache(); - - void sendMessage(); // Send the current message to this region's simulator - void sendReliableMessage(); // Send the current message to this region's simulator - - void setOriginGlobal(const LLVector3d &origin); - //void setAgentOffset(const LLVector3d &offset); - void updateRenderMatrix(); - - void setAllowDamage(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_DAMAGE, b); } - void setAllowLandmark(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_LANDMARK, b); } - void setAllowSetHome(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_SET_HOME, b); } - void setResetHomeOnTeleport(BOOL b) { setRegionFlag(REGION_FLAGS_RESET_HOME_ON_TELEPORT, b); } - void setSunFixed(BOOL b) { setRegionFlag(REGION_FLAGS_SUN_FIXED, b); } - //void setBlockFly(BOOL b) { setRegionFlag(REGION_FLAGS_BLOCK_FLY, b); } Never used - void setAllowDirectTeleport(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_DIRECT_TELEPORT, b); } - - - inline BOOL getAllowDamage() const; - inline BOOL getAllowLandmark() const; - inline BOOL getAllowSetHome() const; - inline BOOL getResetHomeOnTeleport() const; - inline BOOL getSunFixed() const; - inline BOOL getBlockFly() const; - inline BOOL getAllowDirectTeleport() const; - inline BOOL isPrelude() const; - inline BOOL getAllowTerraform() const; - inline BOOL getRestrictPushObject() const; - inline BOOL getReleaseNotesRequested() const; - - bool isAlive(); // can become false if circuit disconnects - - void setWaterHeight(F32 water_level); - F32 getWaterHeight() const; - - BOOL isVoiceEnabled() const; - - void setBillableFactor(F32 billable_factor) { mBillableFactor = billable_factor; } - F32 getBillableFactor() const { return mBillableFactor; } - - // Maximum number of primitives allowed, regardless of object - // bonus factor. - U32 getMaxTasks() const { return mMaxTasks; } - void setMaxTasks(U32 max_tasks) { mMaxTasks = max_tasks; } - - // Draw lines in the dirt showing ownership. Return number of - // vertices drawn. - S32 renderPropertyLines(); - - // Call this whenever you change the height data in the region. - // (Automatically called by LLSurfacePatch's update routine) - void dirtyHeights(); - - LLViewerParcelOverlay *getParcelOverlay() const - { return mParcelOverlay; } - - inline void setRegionFlag(U64 flag, BOOL on); - inline BOOL getRegionFlag(U64 flag) const; - void setRegionFlags(U64 flags); - U64 getRegionFlags() const { return mRegionFlags; } - - inline void setRegionProtocol(U64 protocol, BOOL on); - BOOL getRegionProtocol(U64 protocol) const; - void setRegionProtocols(U64 protocols) { mRegionProtocols = protocols; } - U64 getRegionProtocols() const { return mRegionProtocols; } - - void setTimeDilation(F32 time_dilation); - F32 getTimeDilation() const { return mTimeDilation; } - - // Origin height is at zero. - const LLVector3d &getOriginGlobal() const; - LLVector3 getOriginAgent() const; - - // Center is at the height of the water table. - const LLVector3d &getCenterGlobal() const; - LLVector3 getCenterAgent() const; - - void setRegionNameAndZone(const std::string& name_and_zone); - const std::string& getName() const { return mName; } - const std::string& getZoning() const { return mZoning; } - - void setOwner(const LLUUID& owner_id); - const LLUUID& getOwner() const; - - // Is the current agent on the estate manager list for this region? - void setIsEstateManager(BOOL b) { mIsEstateManager = b; } - BOOL isEstateManager() const { return mIsEstateManager; } - BOOL canManageEstate() const; - - void setSimAccess(U8 sim_access) { mSimAccess = sim_access; } - U8 getSimAccess() const { return mSimAccess; } - const std::string getSimAccessString() const; - - // Homestead-related getters; there are no setters as nobody should be - // setting them other than the individual message handler which is a member - S32 getSimClassID() const { return mClassID; } - S32 getSimCPURatio() const { return mCPURatio; } - const std::string& getSimColoName() const { return mColoName; } - const std::string& getSimProductSKU() const { return mProductSKU; } - std::string getLocalizedSimProductName() const; - - // Returns "Sandbox", "Expensive", etc. - static std::string regionFlagsToString(U64 flags); - - // Returns translated version of "Mature", "PG", "Adult", etc. - static std::string accessToString(U8 sim_access); - - // Returns "M", "PG", "A" etc. - static std::string accessToShortString(U8 sim_access); - static U8 shortStringToAccess(const std::string &sim_access); - - // Return access icon name - static std::string getAccessIcon(U8 sim_access); - - // helper function which just makes sure all interested parties - // can process the message. - static void processRegionInfo(LLMessageSystem* msg, void**); + //MUST MATCH THE ORDER OF DECLARATION IN CONSTRUCTOR + typedef enum + { + PARTITION_HUD = 0, + PARTITION_TERRAIN, + PARTITION_VOIDWATER, + PARTITION_WATER, + PARTITION_TREE, + PARTITION_PARTICLE, + PARTITION_GRASS, + PARTITION_VOLUME, + PARTITION_BRIDGE, + PARTITION_HUD_PARTICLE, + PARTITION_VO_CACHE, + PARTITION_NONE, + NUM_PARTITIONS + } eObjectPartitions; + + typedef boost::signals2::signal<void(const LLUUID& region_id)> caps_received_signal_t; + + LLViewerRegion(const U64 &handle, + const LLHost &host, + const U32 surface_grid_width, + const U32 patch_grid_width, + const F32 region_width_meters); + ~LLViewerRegion(); + + // Call this after you have the region name and handle. + void loadObjectCache(); + void saveObjectCache(); + + void sendMessage(); // Send the current message to this region's simulator + void sendReliableMessage(); // Send the current message to this region's simulator + + void setOriginGlobal(const LLVector3d &origin); + //void setAgentOffset(const LLVector3d &offset); + void updateRenderMatrix(); + + void setAllowDamage(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_DAMAGE, b); } + void setAllowLandmark(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_LANDMARK, b); } + void setAllowSetHome(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_SET_HOME, b); } + void setResetHomeOnTeleport(BOOL b) { setRegionFlag(REGION_FLAGS_RESET_HOME_ON_TELEPORT, b); } + void setSunFixed(BOOL b) { setRegionFlag(REGION_FLAGS_SUN_FIXED, b); } + //void setBlockFly(BOOL b) { setRegionFlag(REGION_FLAGS_BLOCK_FLY, b); } Never used + void setAllowDirectTeleport(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_DIRECT_TELEPORT, b); } + + + inline BOOL getAllowDamage() const; + inline BOOL getAllowLandmark() const; + inline BOOL getAllowSetHome() const; + inline BOOL getResetHomeOnTeleport() const; + inline BOOL getSunFixed() const; + inline BOOL getBlockFly() const; + inline BOOL getAllowDirectTeleport() const; + inline BOOL isPrelude() const; + inline BOOL getAllowTerraform() const; + inline BOOL getRestrictPushObject() const; + inline BOOL getReleaseNotesRequested() const; + + bool isAlive(); // can become false if circuit disconnects + + void setWaterHeight(F32 water_level); + F32 getWaterHeight() const; + + BOOL isVoiceEnabled() const; + + void setBillableFactor(F32 billable_factor) { mBillableFactor = billable_factor; } + F32 getBillableFactor() const { return mBillableFactor; } + + // Maximum number of primitives allowed, regardless of object + // bonus factor. + U32 getMaxTasks() const { return mMaxTasks; } + void setMaxTasks(U32 max_tasks) { mMaxTasks = max_tasks; } + + // Draw lines in the dirt showing ownership. Return number of + // vertices drawn. + S32 renderPropertyLines(); + + // Call this whenever you change the height data in the region. + // (Automatically called by LLSurfacePatch's update routine) + void dirtyHeights(); + + LLViewerParcelOverlay *getParcelOverlay() const + { + return mParcelOverlay; + } + + inline void setRegionFlag(U64 flag, BOOL on); + inline BOOL getRegionFlag(U64 flag) const; + void setRegionFlags(U64 flags); + U64 getRegionFlags() const { return mRegionFlags; } + + inline void setRegionProtocol(U64 protocol, BOOL on); + BOOL getRegionProtocol(U64 protocol) const; + void setRegionProtocols(U64 protocols) { mRegionProtocols = protocols; } + U64 getRegionProtocols() const { return mRegionProtocols; } + + void setTimeDilation(F32 time_dilation); + F32 getTimeDilation() const { return mTimeDilation; } + + // Origin height is at zero. + const LLVector3d &getOriginGlobal() const; + LLVector3 getOriginAgent() const; + + // Center is at the height of the water table. + const LLVector3d &getCenterGlobal() const; + LLVector3 getCenterAgent() const; + + void setRegionNameAndZone(const std::string& name_and_zone); + const std::string& getName() const { return mName; } + const std::string& getZoning() const { return mZoning; } + + void setOwner(const LLUUID& owner_id); + const LLUUID& getOwner() const; + + // Is the current agent on the estate manager list for this region? + void setIsEstateManager(BOOL b) { mIsEstateManager = b; } + BOOL isEstateManager() const { return mIsEstateManager; } + BOOL canManageEstate() const; + + void setSimAccess(U8 sim_access) { mSimAccess = sim_access; } + U8 getSimAccess() const { return mSimAccess; } + const std::string getSimAccessString() const; + + // Homestead-related getters; there are no setters as nobody should be + // setting them other than the individual message handler which is a member + S32 getSimClassID() const { return mClassID; } + S32 getSimCPURatio() const { return mCPURatio; } + const std::string& getSimColoName() const { return mColoName; } + const std::string& getSimProductSKU() const { return mProductSKU; } + std::string getLocalizedSimProductName() const; + + // Returns "Sandbox", "Expensive", etc. + static std::string regionFlagsToString(U64 flags); + + // Returns translated version of "Mature", "PG", "Adult", etc. + static std::string accessToString(U8 sim_access); + + // Returns "M", "PG", "A" etc. + static std::string accessToShortString(U8 sim_access); + static U8 shortStringToAccess(const std::string &sim_access); - //check if the viewer camera is static - static BOOL isViewerCameraStatic(); - static void calcNewObjectCreationThrottle(); + // Return access icon name + static std::string getAccessIcon(U8 sim_access); - void setCacheID(const LLUUID& id); + // helper function which just makes sure all interested parties + // can process the message. + static void processRegionInfo(LLMessageSystem* msg, void**); + + //check if the viewer camera is static + static BOOL isViewerCameraStatic(); + static void calcNewObjectCreationThrottle(); - F32 getWidth() const { return mWidth; } + void setCacheID(const LLUUID& id); - void idleUpdate(F32 max_update_time); - void lightIdleUpdate(); - bool addVisibleGroup(LLViewerOctreeGroup* group); - void addVisibleChildCacheEntry(LLVOCacheEntry* parent, LLVOCacheEntry* child); - void addActiveCacheEntry(LLVOCacheEntry* entry); - void removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* drawablep); - void killCacheEntry(U32 local_id); //physically delete the cache entry + F32 getWidth() const { return mWidth; } - // Like idleUpdate, but forces everything to complete regardless of - // how long it takes. - void forceUpdate(); + void idleUpdate(F32 max_update_time); + void lightIdleUpdate(); + bool addVisibleGroup(LLViewerOctreeGroup* group); + void addVisibleChildCacheEntry(LLVOCacheEntry* parent, LLVOCacheEntry* child); + void addActiveCacheEntry(LLVOCacheEntry* entry); + void removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* drawablep); + void killCacheEntry(U32 local_id); //physically delete the cache entry - void connectNeighbor(LLViewerRegion *neighborp, U32 direction); + // Like idleUpdate, but forces everything to complete regardless of + // how long it takes. + void forceUpdate(); - void updateNetStats(); + void connectNeighbor(LLViewerRegion *neighborp, U32 direction); - U32 getPacketsLost() const; + void updateNetStats(); - S32 getHttpResponderID() const; + U32 getPacketsLost() const; - // Get/set named capability URLs for this region. - void setSeedCapability(const std::string& url); - S32 getNumSeedCapRetries(); - void setCapability(const std::string& name, const std::string& url); - void setCapabilityDebug(const std::string& name, const std::string& url); - bool isCapabilityAvailable(const std::string& name) const; - // implements LLCapabilityProvider + S32 getHttpResponderID() const; + + // Get/set named capability URLs for this region. + void setSeedCapability(const std::string& url); + S32 getNumSeedCapRetries(); + void setCapability(const std::string& name, const std::string& url); + void setCapabilityDebug(const std::string& name, const std::string& url); + bool isCapabilityAvailable(const std::string& name) const; + // implements LLCapabilityProvider virtual std::string getCapability(const std::string& name) const; std::string getCapabilityDebug(const std::string& name) const; - // has region received its final (not seed) capability list? - bool capabilitiesReceived() const; - void setCapabilitiesReceived(bool received); - boost::signals2::connection setCapabilitiesReceivedCallback(const caps_received_signal_t::slot_type& cb); + // has region received its final (not seed) capability list? + bool capabilitiesReceived() const; + void setCapabilitiesReceived(bool received); + boost::signals2::connection setCapabilitiesReceivedCallback(const caps_received_signal_t::slot_type& cb); - static bool isSpecialCapabilityName(const std::string &name); - void logActiveCapabilities() const; + static bool isSpecialCapabilityName(const std::string &name); + void logActiveCapabilities() const; /// implements LLCapabilityProvider - /*virtual*/ const LLHost& getHost() const; - const U64 &getHandle() const { return mHandle; } + /*virtual*/ const LLHost& getHost() const; + const U64 &getHandle() const { return mHandle; } - LLSurface &getLand() const; + LLSurface &getLand() const; - // set and get the region id - const LLUUID& getRegionID() const; - void setRegionID(const LLUUID& region_id); + // set and get the region id + const LLUUID& getRegionID() const; + void setRegionID(const LLUUID& region_id); - BOOL pointInRegionGlobal(const LLVector3d &point_global) const; - LLVector3 getPosRegionFromGlobal(const LLVector3d &point_global) const; - LLVector3 getPosRegionFromAgent(const LLVector3 &agent_pos) const; - LLVector3 getPosAgentFromRegion(const LLVector3 ®ion_pos) const; - LLVector3d getPosGlobalFromRegion(const LLVector3 &offset) const; + BOOL pointInRegionGlobal(const LLVector3d &point_global) const; + LLVector3 getPosRegionFromGlobal(const LLVector3d &point_global) const; + LLVector3 getPosRegionFromAgent(const LLVector3 &agent_pos) const; + LLVector3 getPosAgentFromRegion(const LLVector3 ®ion_pos) const; + LLVector3d getPosGlobalFromRegion(const LLVector3 &offset) const; - LLVLComposition *getComposition() const; - F32 getCompositionXY(const S32 x, const S32 y) const; + LLVLComposition *getComposition() const; + F32 getCompositionXY(const S32 x, const S32 y) const; - BOOL isOwnedSelf(const LLVector3& pos); + BOOL isOwnedSelf(const LLVector3& pos); - // Owned by a group you belong to? (officer OR member) - BOOL isOwnedGroup(const LLVector3& pos); + // Owned by a group you belong to? (officer OR member) + BOOL isOwnedGroup(const LLVector3& pos); - // deal with map object updates in the world. - void updateCoarseLocations(LLMessageSystem* msg); + // deal with map object updates in the world. + void updateCoarseLocations(LLMessageSystem* msg); - F32 getLandHeightRegion(const LLVector3& region_pos); + F32 getLandHeightRegion(const LLVector3& region_pos); - U8 getCentralBakeVersion() { return mCentralBakeVersion; } + U8 getCentralBakeVersion() { return mCentralBakeVersion; } - void getInfo(LLSD& info); - - bool meshRezEnabled() const; - bool meshUploadEnabled() const; + void getInfo(LLSD& info); - // has region received its simulator features list? Requires an additional query after caps received. - void setSimulatorFeaturesReceived(bool); - bool simulatorFeaturesReceived() const; - boost::signals2::connection setSimulatorFeaturesReceivedCallback(const caps_received_signal_t::slot_type& cb); - - void getSimulatorFeatures(LLSD& info) const; - void setSimulatorFeatures(const LLSD& info); + bool meshRezEnabled() const; + bool meshUploadEnabled() const; - - bool dynamicPathfindingEnabled() const; + // has region received its simulator features list? Requires an additional query after caps received. + void setSimulatorFeaturesReceived(bool); + bool simulatorFeaturesReceived() const; + boost::signals2::connection setSimulatorFeaturesReceivedCallback(const caps_received_signal_t::slot_type& cb); - bool avatarHoverHeightEnabled() const; + void getSimulatorFeatures(LLSD& info) const; + void setSimulatorFeatures(const LLSD& info); - typedef enum - { - CACHE_MISS_TYPE_FULL = 0, - CACHE_MISS_TYPE_CRC, - CACHE_MISS_TYPE_NONE - } eCacheMissType; - typedef enum - { - CACHE_UPDATE_DUPE = 0, - CACHE_UPDATE_CHANGED, - CACHE_UPDATE_ADDED, - CACHE_UPDATE_REPLACED - } eCacheUpdateResult; - - // handle a full update message - eCacheUpdateResult cacheFullUpdate(LLDataPackerBinaryBuffer &dp, U32 flags); - eCacheUpdateResult cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp, U32 flags); - LLVOCacheEntry* getCacheEntryForOctree(U32 local_id); - LLVOCacheEntry* getCacheEntry(U32 local_id, bool valid = true); - bool probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss_type); - U64 getRegionCacheHitCount() { return mRegionCacheHitCount; } - U64 getRegionCacheMissCount() { return mRegionCacheMissCount; } - void requestCacheMisses(); - void addCacheMissFull(const U32 local_id); - //update object cache if the object receives a full-update or terse update - LLViewerObject* updateCacheEntry(U32 local_id, LLViewerObject* objectp, U32 update_type); - void findOrphans(U32 parent_id); - void clearCachedVisibleObjects(); - void dumpCache(); - - void unpackRegionHandshake(); - - void calculateCenterGlobal(); - void calculateCameraDistance(); - - friend std::ostream& operator<<(std::ostream &s, const LLViewerRegion ®ion); + bool dynamicPathfindingEnabled() const; + + bool avatarHoverHeightEnabled() const; + + typedef enum + { + CACHE_MISS_TYPE_FULL = 0, + CACHE_MISS_TYPE_CRC, + CACHE_MISS_TYPE_NONE + } eCacheMissType; + + typedef enum + { + CACHE_UPDATE_DUPE = 0, + CACHE_UPDATE_CHANGED, + CACHE_UPDATE_ADDED, + CACHE_UPDATE_REPLACED + } eCacheUpdateResult; + + // handle a full update message + eCacheUpdateResult cacheFullUpdate(LLDataPackerBinaryBuffer &dp, U32 flags); + eCacheUpdateResult cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp, U32 flags); + LLVOCacheEntry* getCacheEntryForOctree(U32 local_id); + LLVOCacheEntry* getCacheEntry(U32 local_id, bool valid = true); + bool probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss_type); + U64 getRegionCacheHitCount() { return mRegionCacheHitCount; } + U64 getRegionCacheMissCount() { return mRegionCacheMissCount; } + void requestCacheMisses(); + void addCacheMissFull(const U32 local_id); + //update object cache if the object receives a full-update or terse update + LLViewerObject* updateCacheEntry(U32 local_id, LLViewerObject* objectp, U32 update_type); + void findOrphans(U32 parent_id); + void clearCachedVisibleObjects(); + void dumpCache(); + + void unpackRegionHandshake(); + + void calculateCenterGlobal(); + void calculateCameraDistance(); + + friend std::ostream& operator<<(std::ostream &s, const LLViewerRegion ®ion); /// implements LLCapabilityProvider virtual std::string getDescription() const; std::string getViewerAssetUrl() const { return mViewerAssetUrl; } - U32 getNumOfVisibleGroups() const; - U32 getNumOfActiveCachedObjects() const; - LLSpatialPartition* getSpatialPartition(U32 type); - LLVOCachePartition* getVOCachePartition(); + U32 getNumOfVisibleGroups() const; + U32 getNumOfActiveCachedObjects() const; + LLSpatialPartition* getSpatialPartition(U32 type); + LLVOCachePartition* getVOCachePartition(); - bool objectIsReturnable(const LLVector3& pos, const std::vector<LLBBox>& boxes) const; - bool childrenObjectReturnable( const std::vector<LLBBox>& boxes ) const; - bool objectsCrossParcel(const std::vector<LLBBox>& boxes) const; + bool objectIsReturnable(const LLVector3& pos, const std::vector<LLBBox>& boxes) const; + bool childrenObjectReturnable(const std::vector<LLBBox>& boxes) const; + bool objectsCrossParcel(const std::vector<LLBBox>& boxes) const; - void getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions ); - void getNeighboringRegionsStatus( std::vector<S32>& regions ); - const LLViewerRegionImpl * getRegionImpl() const { return mImpl; } - LLViewerRegionImpl * getRegionImplNC() { return mImpl; } + void getNeighboringRegions(std::vector<LLViewerRegion*>& uniqueRegions); + void getNeighboringRegionsStatus(std::vector<S32>& regions); + const LLViewerRegionImpl * getRegionImpl() const { return mImpl; } + LLViewerRegionImpl * getRegionImplNC() { return mImpl; } - // implements the materials capability throttle - bool materialsCapThrottled() const { return !mMaterialsCapThrottleTimer.hasExpired(); } - void resetMaterialsCapThrottle(); - - U32 getMaxMaterialsPerTransaction() const; + // implements the materials capability throttle + bool materialsCapThrottled() const { return !mMaterialsCapThrottleTimer.hasExpired(); } + void resetMaterialsCapThrottle(); + + U32 getMaxMaterialsPerTransaction() const; - void removeFromCreatedList(U32 local_id); - void addToCreatedList(U32 local_id); + void removeFromCreatedList(U32 local_id); + void addToCreatedList(U32 local_id); - BOOL isPaused() const {return mPaused;} - S32 getLastUpdate() const {return mLastUpdate;} + BOOL isPaused() const { return mPaused; } + S32 getLastUpdate() const { return mLastUpdate; } - static BOOL isNewObjectCreationThrottleDisabled() {return sNewObjectCreationThrottle < 0;} + static BOOL isNewObjectCreationThrottleDisabled() { return sNewObjectCreationThrottle < 0; } private: void addToVOCacheTree(LLVOCacheEntry* entry); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 3e0cec0f09..1c78bf36db 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -38,13 +38,13 @@ #include "llviewercontrol.h" #include "pipeline.h" #include "llworld.h" -#include "llwlparammanager.h" -#include "llwaterparammanager.h" #include "llsky.h" #include "llvosky.h" #include "llrender.h" #include "lljoint.h" #include "llskinningutil.h" +#include "llenvironment.h" +#include "llatmosphere.h" #ifdef LL_RELEASE_FOR_DOWNLOAD #define UNIFORM_ERRS LL_WARNS_ONCE("Shader") @@ -93,6 +93,8 @@ LLGLSLShader gDebugProgram; LLGLSLShader gClipProgram; LLGLSLShader gDownsampleDepthProgram; LLGLSLShader gDownsampleDepthRectProgram; +LLGLSLShader gDownsampleMinMaxDepthRectProgram; +LLGLSLShader gInscatterRectProgram; LLGLSLShader gAlphaMaskProgram; LLGLSLShader gBenchmarkProgram; @@ -475,7 +477,7 @@ void LLViewerShaderMgr::setShaders() S32 env_class = 2; S32 obj_class = 2; S32 effect_class = 2; - S32 wl_class = 2; + S32 wl_class = 3; S32 water_class = 2; S32 deferred_class = 0; S32 transform_class = gGLManager.mHasTransformFeedback ? 1 : 0; @@ -499,14 +501,13 @@ void LLViewerShaderMgr::setShaders() { //no shadows deferred_class = 1; } - - //make sure hardware skinning is enabled - //gSavedSettings.setBOOL("RenderAvatarVP", TRUE); - - //make sure atmospheric shaders are enabled - //gSavedSettings.setBOOL("WindLightUseAtmosShaders", TRUE); } + // clamp to WL class 2 if we have disabled adv atmo (class 3) + if (!gSavedSettings.getBOOL("RenderUseAdvancedAtmospherics")) + { + wl_class = llmin(wl_class, 2); + } if (!(LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders") && gSavedSettings.getBOOL("WindLightUseAtmosShaders"))) @@ -516,7 +517,6 @@ void LLViewerShaderMgr::setShaders() wl_class = 1; } - // Trigger a full rebuild of the fallback skybox / cubemap if we've toggled windlight shaders if (mVertexShaderLevel[SHADER_WINDLIGHT] != wl_class && gSky.mVOSkyp.notNull()) { @@ -544,6 +544,7 @@ void LLViewerShaderMgr::setShaders() // Load all shaders to set max levels loaded = loadShadersEnvironment(); + llassert(loaded); if (loaded) { @@ -580,14 +581,10 @@ void LLViewerShaderMgr::setShaders() if (gSavedSettings.getBOOL("RenderAvatarVP") && loadShadersObject()) { //hardware skinning is enabled and rigged attachment shaders loaded correctly BOOL avatar_cloth = gSavedSettings.getBOOL("RenderAvatarCloth"); - S32 avatar_class = 1; - - // cloth is a class3 shader - if(avatar_cloth) - { - avatar_class = 3; - } + // cloth is a class3 shader + S32 avatar_class = avatar_cloth ? 3 : 1; + // Set the actual level mVertexShaderLevel[SHADER_AVATAR] = avatar_class; loadShadersAvatar(); @@ -700,6 +697,8 @@ void LLViewerShaderMgr::unloadShaders() gClipProgram.unload(); gDownsampleDepthProgram.unload(); gDownsampleDepthRectProgram.unload(); + gDownsampleMinMaxDepthRectProgram.unload(); + gInscatterRectProgram.unload(); gBenchmarkProgram.unload(); gAlphaMaskProgram.unload(); gUIProgram.unload(); @@ -1955,15 +1954,19 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() { gDeferredWLSkyProgram.mName = "Deferred Windlight Sky Shader"; //gWLSkyProgram.mFeatures.hasGamma = true; - gDeferredWLSkyProgram.mShaderFiles.clear(); + gDeferredWLSkyProgram.mShaderFiles.clear(); gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredWLSkyProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + gDeferredWLSkyProgram.mShaderLevel = mVertexShaderLevel[SHADER_WINDLIGHT]; gDeferredWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY; + if (mVertexShaderLevel[SHADER_WINDLIGHT] >= 3) + { + gDeferredWLSkyProgram.mExtraLinkObject = gAtmosphere->getAtmosphericShaderForLink(); + } success = gDeferredWLSkyProgram.createShader(NULL, NULL); } - if (success) + if (success && (mVertexShaderLevel[SHADER_WINDLIGHT] < 3)) { gDeferredWLCloudProgram.mName = "Deferred Windlight Cloud Program"; gDeferredWLCloudProgram.mShaderFiles.clear(); @@ -3268,16 +3271,6 @@ BOOL LLViewerShaderMgr::loadShadersInterface() if (success) { - gDownsampleDepthRectProgram.mName = "DownsampleDepthRect Shader"; - gDownsampleDepthRectProgram.mShaderFiles.clear(); - gDownsampleDepthRectProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthV.glsl", GL_VERTEX_SHADER_ARB)); - gDownsampleDepthRectProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthRectF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDownsampleDepthRectProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; - success = gDownsampleDepthRectProgram.createShader(NULL, NULL); - } - - if (success) - { gAlphaMaskProgram.mName = "Alpha Mask Shader"; gAlphaMaskProgram.mShaderFiles.clear(); gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskV.glsl", GL_VERTEX_SHADER_ARB)); @@ -3296,17 +3289,49 @@ BOOL LLViewerShaderMgr::loadShadersInterface() } BOOL LLViewerShaderMgr::loadShadersWindLight() -{ +{ BOOL success = TRUE; if (mVertexShaderLevel[SHADER_WINDLIGHT] < 2) { gWLSkyProgram.unload(); gWLCloudProgram.unload(); + gDownsampleMinMaxDepthRectProgram.unload(); + gInscatterRectProgram.unload(); return TRUE; } - if (success) + if (mVertexShaderLevel[SHADER_WINDLIGHT] >= 3) + { + // Prepare precomputed atmospherics textures using libatmosphere + LLAtmosphere::initClass(); + } + + // this shader uses gather so it can't live with the other basic shaders safely + /*if (success && (mVertexShaderLevel[SHADER_WINDLIGHT] >= 3)) + { + gDownsampleMinMaxDepthRectProgram.mName = "DownsampleMinMaxDepthRect Shader"; + gDownsampleMinMaxDepthRectProgram.mShaderFiles.clear(); + gDownsampleMinMaxDepthRectProgram.mShaderFiles.push_back(make_pair("windlight/downsampleMinMaxDepthV.glsl", GL_VERTEX_SHADER_ARB)); + gDownsampleMinMaxDepthRectProgram.mShaderFiles.push_back(make_pair("windlight/downsampleMinMaxDepthRectF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDownsampleMinMaxDepthRectProgram.mShaderLevel = mVertexShaderLevel[SHADER_WINDLIGHT]; + success = gDownsampleMinMaxDepthRectProgram.createShader(NULL, NULL); + }*/ + + // this shader uses gather so it can't live with the other basic shaders safely + if (success && (mVertexShaderLevel[SHADER_WINDLIGHT] >= 3)) + { + gInscatterRectProgram.mName = "Inscatter Shader"; + gInscatterRectProgram.mShaderFiles.clear(); + gInscatterRectProgram.mShaderFiles.push_back(make_pair("windlight/advancedAtmoV.glsl", GL_VERTEX_SHADER_ARB)); + gInscatterRectProgram.mShaderFiles.push_back(make_pair("windlight/advancedAtmoF.glsl", GL_FRAGMENT_SHADER_ARB)); + gInscatterRectProgram.mShaderLevel = mVertexShaderLevel[SHADER_WINDLIGHT]; + llassert(gAtmosphere != nullptr); + gInscatterRectProgram.mExtraLinkObject = gAtmosphere->getAtmosphericShaderForLink(); + success = gInscatterRectProgram.createShader(NULL, NULL); + } + + if (success && (mVertexShaderLevel[SHADER_WINDLIGHT] < 3)) { gWLSkyProgram.mName = "Windlight Sky Shader"; //gWLSkyProgram.mFeatures.hasGamma = true; @@ -3318,7 +3343,7 @@ BOOL LLViewerShaderMgr::loadShadersWindLight() success = gWLSkyProgram.createShader(NULL, NULL); } - if (success) + if (success && (mVertexShaderLevel[SHADER_WINDLIGHT] < 3)) { gWLCloudProgram.mName = "Windlight Cloud Program"; //gWLCloudProgram.mFeatures.hasGamma = true; @@ -3429,8 +3454,7 @@ std::string LLViewerShaderMgr::getShaderDirPrefix(void) void LLViewerShaderMgr::updateShaderUniforms(LLGLSLShader * shader) { - LLWLParamManager::getInstance()->updateShaderUniforms(shader); - LLWaterParamManager::getInstance()->updateShaderUniforms(shader); + LLEnvironment::instance().updateShaderUniforms(shader); } LLViewerShaderMgr::shader_iter LLViewerShaderMgr::beginShaders() const diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 923aa522ad..10c60187f3 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -184,6 +184,8 @@ extern LLGLSLShader gDebugProgram; extern LLGLSLShader gClipProgram; extern LLGLSLShader gDownsampleDepthProgram; extern LLGLSLShader gDownsampleDepthRectProgram; +extern LLGLSLShader gDownsampleMinMaxDepthRectProgram; +extern LLGLSLShader gInscatterRectProgram; extern LLGLSLShader gBenchmarkProgram; //output tex0[tc0] + tex1[tc1] diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index 7d2d6e25c7..f860e3bbbe 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -540,7 +540,9 @@ LLUIImagePtr LLEmbeddedItems::getItemImage(llwchar ext_char) const case LLAssetType::AT_ANIMATION: img_name = "Inv_Animation"; break; case LLAssetType::AT_GESTURE: img_name = "Inv_Gesture"; break; case LLAssetType::AT_MESH: img_name = "Inv_Mesh"; break; - default: img_name = "Inv_Invalid"; break; // use the Inv_Invalid icon for undefined object types (see MAINT-3981) + case LLAssetType::AT_SETTINGS: img_name = "Inv_Settings"; break; + default: img_name = "Inv_Invalid"; break; // use the Inv_Invalid icon for undefined object types (see MAINT-3981) + } return LLUI::getUIImage(img_name); diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 39ffbfc989..c38f19f579 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -98,8 +98,8 @@ const S32 MAX_CACHED_RAW_IMAGE_AREA = 64 * 64; const S32 MAX_CACHED_RAW_SCULPT_IMAGE_AREA = LLViewerTexture::sMaxSculptRez * LLViewerTexture::sMaxSculptRez; const S32 MAX_CACHED_RAW_TERRAIN_IMAGE_AREA = 128 * 128; const S32 DEFAULT_ICON_DIMENTIONS = 32; -S32 LLViewerTexture::sMinLargeImageSize = 65536; //256 * 256. -S32 LLViewerTexture::sMaxSmallImageSize = MAX_CACHED_RAW_IMAGE_AREA; +U32 LLViewerTexture::sMinLargeImageSize = 65536; //256 * 256. +U32 LLViewerTexture::sMaxSmallImageSize = MAX_CACHED_RAW_IMAGE_AREA; BOOL LLViewerTexture::sFreezeImageScalingDown = FALSE; F32 LLViewerTexture::sCurrentTime = 0.0f; F32 LLViewerTexture::sTexelPixelRatio = 1.0f; @@ -1187,12 +1187,12 @@ void LLViewerFetchedTexture::loadFromFastCache() { return; //no need to access the fast cache. } - mInFastCacheList = FALSE; + mInFastCacheList = FALSE; mRawImage = LLAppViewer::getTextureCache()->readFromFastCache(getID(), mRawDiscardLevel); if(mRawImage.notNull()) { - mFullWidth = mRawImage->getWidth() << mRawDiscardLevel; + mFullWidth = mRawImage->getWidth() << mRawDiscardLevel; mFullHeight = mRawImage->getHeight() << mRawDiscardLevel; setTexelsPerImage(); @@ -1207,20 +1207,20 @@ void LLViewerFetchedTexture::loadFromFastCache() else { if (mBoostLevel == LLGLTexture::BOOST_ICON) + { + S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENTIONS; + S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENTIONS; + if (mRawImage && (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height)) { - S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENTIONS; - S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENTIONS; - if (mRawImage && (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height)) - { - // scale oversized icon, no need to give more work to gl - mRawImage->scale(expected_width, expected_height); - } + // scale oversized icon, no need to give more work to gl + mRawImage->scale(expected_width, expected_height); + } } - mRequestedDiscardLevel = mDesiredDiscardLevel + 1; - mIsRawImageValid = TRUE; - addToCreateTexture(); - } + mRequestedDiscardLevel = mDesiredDiscardLevel + 1; + mIsRawImageValid = TRUE; + addToCreateTexture(); + } } } @@ -1982,7 +1982,7 @@ bool LLViewerFetchedTexture::updateFetch() mIsFetched = TRUE; tester->updateTextureLoadingStats(this, mRawImage, LLAppViewer::getTextureFetch()->isFromLocalCache(mID)); } - mRawDiscardLevel = fetch_discard; + mRawDiscardLevel = fetch_discard; if ((mRawImage->getDataSize() > 0 && mRawDiscardLevel >= 0) && (current_discard < 0 || mRawDiscardLevel < current_discard)) { diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index 5d89f9f029..7b58c97bc4 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -225,8 +225,8 @@ public: static S8 sCameraMovingDiscardBias; static F32 sCameraMovingBias; static S32 sMaxSculptRez ; - static S32 sMinLargeImageSize ; - static S32 sMaxSmallImageSize ; + static U32 sMinLargeImageSize ; + static U32 sMaxSmallImageSize ; static BOOL sFreezeImageScalingDown ;//do not scale down image res if set. static F32 sCurrentTime ; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index e90b4ac86c..f981d40204 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1710,7 +1710,7 @@ LLViewerWindow::LLViewerWindow(const Params& p) U32 fsaa_samples) */ // create window - mWindow = LLWindowManager::createWindow(this, + mWindow = LLWindowManager::createWindow(this, p.title, p.name, p.x, p.y, p.width, p.height, 0, p.fullscreen, gHeadlessClient, diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index c131cb886f..9ba6aeb37f 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -48,8 +48,10 @@ #include "llworld.h" #include "pipeline.h" #include "lldrawpoolwlsky.h" -#include "llwlparammanager.h" -#include "llwaterparammanager.h" +#include "v3colorutil.h" + +#include "llsettingssky.h" +#include "llenvironment.h" #undef min #undef max @@ -326,27 +328,7 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) mWorldScale(1.f), mBumpSunDir(0.f, 0.f, 1.f) { - bool error = false; - /// WL PARAMS - dome_radius = 1.f; - dome_offset_ratio = 0.f; - sunlight_color = LLColor3(); - ambient = LLColor3(); - gamma = 1.f; - lightnorm = LLVector4(); - blue_density = LLColor3(); - blue_horizon = LLColor3(); - haze_density = 0.f; - haze_horizon = 1.f; - density_multiplier = 0.f; - max_y = 0.f; - glow = LLColor3(); - cloud_shadow = 0.f; - cloud_color = LLColor3(); - cloud_scale = 0.f; - cloud_pos_density1 = LLColor3(); - cloud_pos_density2 = LLColor3(); mInitialized = FALSE; mbCanSelect = FALSE; @@ -366,10 +348,13 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) mAtmHeight = ATM_HEIGHT; mEarthCenter = LLVector3(mCameraPosAgent.mV[0], mCameraPosAgent.mV[1], -EARTH_RADIUS); - mSunDefaultPosition = LLVector3(LLWLParamManager::getInstance()->mCurParams.getVector("lightnorm", error)); + // *LAPRAS + mSunDefaultPosition = LLEnvironment::instance().getCurrentSky()->getSunDirection(); + if (gSavedSettings.getBOOL("SkyOverrideSimSunPosition")) { - initSunDirection(mSunDefaultPosition, LLVector3(0, 0, 0)); + + initSunDirection(LLVector3(mSunDefaultPosition.mV[2], mSunDefaultPosition.mV[0], mSunDefaultPosition.mV[1]), LLVector3(0, 0, 0)); } mAmbientScale = gSavedSettings.getF32("SkyAmbientScale"); mNightColorShift = gSavedSettings.getColor3("SkyNightColorShift"); @@ -412,6 +397,7 @@ void LLVOSky::init() calcAtmospherics(); +// LEGACY_ATMOSPHERICS // Initialize the cached normalized direction vectors for (S32 side = 0; side < 6; ++side) { @@ -509,6 +495,7 @@ void LLVOSky::restoreGL() } +// LEGACY_ATMOSPHERICS void LLVOSky::initSkyTextureDirs(const S32 side, const S32 tile) { S32 tile_x = tile % NUM_TILES_X; @@ -560,107 +547,6 @@ void LLVOSky::createSkyTexture(const S32 side, const S32 tile) } } -static inline LLColor3 componentDiv(LLColor3 const &left, LLColor3 const & right) -{ - return LLColor3(left.mV[0]/right.mV[0], - left.mV[1]/right.mV[1], - left.mV[2]/right.mV[2]); -} - - -static inline LLColor3 componentMult(LLColor3 const &left, LLColor3 const & right) -{ - return LLColor3(left.mV[0]*right.mV[0], - left.mV[1]*right.mV[1], - left.mV[2]*right.mV[2]); -} - - -static inline LLColor3 componentExp(LLColor3 const &v) -{ - return LLColor3(exp(v.mV[0]), - exp(v.mV[1]), - exp(v.mV[2])); -} - -static inline LLColor3 componentPow(LLColor3 const &v, F32 exponent) -{ - return LLColor3(pow(v.mV[0], exponent), - pow(v.mV[1], exponent), - pow(v.mV[2], exponent)); -} - -static inline LLColor3 componentSaturate(LLColor3 const &v) -{ - return LLColor3(std::max(std::min(v.mV[0], 1.f), 0.f), - std::max(std::min(v.mV[1], 1.f), 0.f), - std::max(std::min(v.mV[2], 1.f), 0.f)); -} - - -static inline LLColor3 componentSqrt(LLColor3 const &v) -{ - return LLColor3(sqrt(v.mV[0]), - sqrt(v.mV[1]), - sqrt(v.mV[2])); -} - -static inline void componentMultBy(LLColor3 & left, LLColor3 const & right) -{ - left.mV[0] *= right.mV[0]; - left.mV[1] *= right.mV[1]; - left.mV[2] *= right.mV[2]; -} - -static inline LLColor3 colorMix(LLColor3 const & left, LLColor3 const & right, F32 amount) -{ - return (left + ((right - left) * amount)); -} - -static inline LLColor3 smear(F32 val) -{ - return LLColor3(val, val, val); -} - -void LLVOSky::initAtmospherics(void) -{ - bool error; - - // uniform parameters for convenience - dome_radius = LLWLParamManager::getInstance()->getDomeRadius(); - dome_offset_ratio = LLWLParamManager::getInstance()->getDomeOffset(); - sunlight_color = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("sunlight_color", error)); - ambient = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("ambient", error)); - //lightnorm = LLWLParamManager::getInstance()->mCurParams.getVector("lightnorm", error); - gamma = LLWLParamManager::getInstance()->mCurParams.getFloat("gamma", error); - blue_density = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("blue_density", error)); - blue_horizon = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("blue_horizon", error)); - haze_density = LLWLParamManager::getInstance()->mCurParams.getFloat("haze_density", error); - haze_horizon = LLWLParamManager::getInstance()->mCurParams.getFloat("haze_horizon", error); - density_multiplier = LLWLParamManager::getInstance()->mCurParams.getFloat("density_multiplier", error); - max_y = LLWLParamManager::getInstance()->mCurParams.getFloat("max_y", error); - glow = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("glow", error)); - cloud_shadow = LLWLParamManager::getInstance()->mCurParams.getFloat("cloud_shadow", error); - cloud_color = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("cloud_color", error)); - cloud_scale = LLWLParamManager::getInstance()->mCurParams.getFloat("cloud_scale", error); - cloud_pos_density1 = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("cloud_pos_density1", error)); - cloud_pos_density2 = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("cloud_pos_density2", error)); - - // light norm is different. We need the sun's direction, not the light direction - // which could be from the moon. And we need to clamp it - // just like for the gpu - LLVector3 sunDir = gSky.getSunDirection(); - - // CFR_TO_OGL - lightnorm = LLVector4(sunDir.mV[1], sunDir.mV[2], sunDir.mV[0], 0); - unclamped_lightnorm = lightnorm; - if(lightnorm.mV[1] < -0.1f) - { - lightnorm.mV[1] = -0.1f; - } - -} - LLColor4 LLVOSky::calcSkyColorInDir(const LLVector3 &dir, bool isShiny) { F32 saturation = 0.3f; @@ -733,6 +619,12 @@ void LLVOSky::calcSkyColorWLVert(LLVector3 & Pn, LLColor3 & vary_HazeColor, LLCo LLColor3 & vary_CloudColorAmbient, F32 & vary_CloudDensity, LLVector2 vary_HorizontalProjection[2]) { + LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); + + LLColor3 blue_density = psky->getBlueDensity(); + F32 max_y = psky->getMaxY(); + LLVector3 lightnorm = psky->getLightNormal(); + // project the direction ray onto the sky dome. F32 phi = acos(Pn[1]); F32 sinA = sin(F_PI - phi); @@ -741,7 +633,7 @@ void LLVOSky::calcSkyColorWLVert(LLVector3 & Pn, LLColor3 & vary_HazeColor, LLCo sinA = 0.01f; } - F32 Plen = dome_radius * sin(F_PI + phi + asin(dome_offset_ratio * sinA)) / sinA; + F32 Plen = psky->getDomeRadius() * sin(F_PI + phi + asin(psky->getDomeOffset() * sinA)) / sinA; Pn *= Plen; @@ -762,12 +654,18 @@ void LLVOSky::calcSkyColorWLVert(LLVector3 & Pn, LLColor3 & vary_HazeColor, LLCo Pn /= Plen; // Initialize temp variables - LLColor3 sunlight = sunlight_color; + LLColor3 sunlight = psky->getSunlightColor(); + LLColor3 ambient = psky->getAmbientColor(); + LLColor3 blue_horizon = psky->getBlueHorizon(); + F32 haze_density = psky->getHazeDensity(); + F32 haze_horizon = psky->getHazeHorizon(); + F32 density_multiplier = psky->getDensityMultiplier(); + LLColor3 glow = psky->getGlow(); + F32 cloud_shadow = psky->getCloudShadow(); // 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); + 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); @@ -789,7 +687,7 @@ void LLVOSky::calcSkyColorWLVert(LLVector3 & Pn, LLColor3 & vary_HazeColor, LLCo // Compute haze glow - temp2.mV[0] = Pn * LLVector3(lightnorm); + temp2.mV[0] = Pn * lightnorm; temp2.mV[0] = 1.f - temp2.mV[0]; // temp2.x is 0 at the sun and increases away from sun @@ -805,9 +703,7 @@ void LLVOSky::calcSkyColorWLVert(LLVector3 & Pn, LLColor3 & vary_HazeColor, LLCo // Haze color above cloud - vary_HazeColor = (blue_horizon * blue_weight * (sunlight + ambient) - + componentMult(haze_horizon * haze_weight, sunlight * temp2.mV[0] + ambient) - ); + vary_HazeColor = (blue_horizon * blue_weight * (sunlight + ambient) + componentMult(haze_horizon * haze_weight, sunlight * temp2.mV[0] + ambient)); // Increase ambient when there are more clouds LLColor3 tmpAmbient = ambient + (LLColor3::white - ambient) * cloud_shadow * 0.5f; @@ -816,14 +712,12 @@ void LLVOSky::calcSkyColorWLVert(LLVector3 & Pn, LLColor3 & vary_HazeColor, LLCo sunlight *= (1.f - cloud_shadow); // Haze color below cloud - LLColor3 additiveColorBelowCloud = (blue_horizon * blue_weight * (sunlight + tmpAmbient) - + componentMult(haze_horizon * haze_weight, sunlight * temp2.mV[0] + tmpAmbient) - ); + LLColor3 additiveColorBelowCloud = (blue_horizon * blue_weight * (sunlight + tmpAmbient) + componentMult(haze_horizon * haze_weight, sunlight * temp2.mV[0] + tmpAmbient)); // Final atmosphere additive componentMultBy(vary_HazeColor, LLColor3::white - temp1); - sunlight = sunlight_color; + sunlight = psky->getSunlightColor(); temp2.mV[1] = llmax(0.f, lightnorm[1] * 2.f); temp2.mV[1] = 1.f / temp2.mV[1]; componentMultBy(sunlight, componentExp((light_atten * -1.f) * temp2.mV[1])); @@ -832,8 +726,7 @@ void LLVOSky::calcSkyColorWLVert(LLVector3 & Pn, LLColor3 & vary_HazeColor, LLCo temp1 = componentSqrt(temp1); //less atmos opacity (more transparency) below clouds // At horizon, blend high altitude sky color towards the darker color below the clouds - vary_HazeColor += - componentMult(additiveColorBelowCloud - vary_HazeColor, LLColor3::white - componentSqrt(temp1)); + vary_HazeColor += componentMult(additiveColorBelowCloud - vary_HazeColor, LLColor3::white - componentSqrt(temp1)); if (Pn[1] < 0.f) { @@ -864,8 +757,10 @@ LLColor3 LLVOSky::calcSkyColorWLFrag(LLVector3 & Pn, LLColor3 & vary_HazeColor, LLColor3 & vary_CloudColorAmbient, F32 & vary_CloudDensity, LLVector2 vary_HorizontalProjection[2]) { - LLColor3 res; + LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); + F32 gamma = psky->getGamma(); + LLColor3 res; LLColor3 color0 = vary_HazeColor; if (!gPipeline.canUseWindLightShaders()) @@ -917,6 +812,7 @@ LLColor3 LLVOSky::calcSkyColorWLFrag(LLVector3 & Pn, LLColor3 & vary_HazeColor, return res; } + LLColor3 LLVOSky::createDiffuseFromWL(LLColor3 diffuse, LLColor3 ambient, LLColor3 sundiffuse, LLColor3 sunambient) { return componentMult(diffuse, sundiffuse) * 4.0f + @@ -928,81 +824,11 @@ LLColor3 LLVOSky::createAmbientFromWL(LLColor3 ambient, LLColor3 sundiffuse, LLC return (componentMult(ambient, sundiffuse) + sunambient) * 0.8f; } - void LLVOSky::calcAtmospherics(void) { - initAtmospherics(); - - LLColor3 vary_HazeColor; - LLColor3 vary_SunlightColor; - LLColor3 vary_AmbientColor; - { - // Initialize temp variables - LLColor3 sunlight = sunlight_color; - - // 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 = unclamped_lightnorm[1]; - if(lighty < LLSky::NIGHTTIME_ELEVATION_COS) - { - lighty = -lighty; - } + LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); - 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); - - } - - mSun.setColor(vary_SunlightColor); + mSun.setColor(psky->getSunlightColor()); mMoon.setColor(LLColor3(1.0f, 1.0f, 1.0f)); mSun.renewDirection(); @@ -1019,18 +845,8 @@ void LLVOSky::calcAtmospherics(void) // Since WL scales everything by 2, there should always be at least a 2:1 brightness ratio // between sunlight and point lights in windlight to normalize point lights. F32 sun_dynamic_range = llmax(gSavedSettings.getF32("RenderSunDynamicRange"), 0.0001f); - LLWLParamManager::getInstance()->mSceneLightStrength = 2.0f * (1.0f + sun_dynamic_range * dp); + LLEnvironment::instance().setSceneLightStrength(2.0f * (1.0f + sun_dynamic_range * dp)); - mSunDiffuse = vary_SunlightColor; - mSunAmbient = vary_AmbientColor; - mMoonDiffuse = vary_SunlightColor; - mMoonAmbient = vary_AmbientColor; - - mTotalAmbient = vary_AmbientColor; - mTotalAmbient.setAlpha(1); - - mFadeColor = mTotalAmbient + (mSunDiffuse + mMoonDiffuse) * 0.5f; - mFadeColor.setAlpha(0); } void LLVOSky::idleUpdate(LLAgent &agent, const F64 &time) @@ -1039,6 +855,10 @@ void LLVOSky::idleUpdate(LLAgent &agent, const F64 &time) BOOL LLVOSky::updateSky() { + LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); + + LLColor4 total_ambient = psky->getTotalAmbient(); + if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))) { return TRUE; @@ -1054,6 +874,7 @@ BOOL LLVOSky::updateSky() return TRUE; } +// LEGACY_ATMOSPHERICS static S32 next_frame = 0; const S32 total_no_tiles = 6 * NUM_TILES; const S32 cycle_frame_no = total_no_tiles + 1; @@ -1084,9 +905,9 @@ BOOL LLVOSky::updateSky() const F32 dot_lighting = direction * mLastLightingDirection; LLColor3 delta_color; - delta_color.setVec(mLastTotalAmbient.mV[0] - mTotalAmbient.mV[0], - mLastTotalAmbient.mV[1] - mTotalAmbient.mV[1], - mLastTotalAmbient.mV[2] - mTotalAmbient.mV[2]); + delta_color.setVec(mLastTotalAmbient.mV[0] - total_ambient.mV[0], + mLastTotalAmbient.mV[1] - total_ambient.mV[1], + mLastTotalAmbient.mV[2] - total_ambient.mV[2]); if ( mForceUpdate || (((dot_lighting < LIGHT_DIRECTION_THRESHOLD) @@ -1095,7 +916,7 @@ BOOL LLVOSky::updateSky() && !direction.isExactlyZero())) { mLastLightingDirection = direction; - mLastTotalAmbient = mTotalAmbient; + mLastTotalAmbient = total_ambient; mInitialized = TRUE; if (mCubeMap) @@ -1103,6 +924,7 @@ BOOL LLVOSky::updateSky() if (mForceUpdate) { updateFog(LLViewerCamera::getInstance()->getFar()); + for (int side = 0; side < 6; side++) { for (int tile = 0; tile < NUM_TILES; tile++) @@ -1171,6 +993,7 @@ BOOL LLVOSky::updateSky() { gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); } + return TRUE; } @@ -1267,6 +1090,7 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable) } mCameraPosAgent = drawable->getPositionAgent(); + mEarthCenter.mV[0] = mCameraPosAgent.mV[0]; mEarthCenter.mV[1] = mCameraPosAgent.mV[1]; @@ -1870,157 +1694,160 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H, LLFace *face = mFace[FACE_REFLECTION]; - if (!face->getVertexBuffer() || quads*4 != face->getGeomCount()) - { - face->setSize(quads * 4, quads * 6); - LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); - if (!buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE)) - { - LL_WARNS() << "Failed to allocate Vertex Buffer for vosky to " - << face->getGeomCount() << " vertices and " - << face->getIndicesCount() << " indices" << LL_ENDL; - } - face->setIndicesIndex(0); - face->setGeomIndex(0); - face->setVertexBuffer(buff); - } - - LLStrider<LLVector3> verticesp; - LLStrider<LLVector3> normalsp; - LLStrider<LLVector2> texCoordsp; - LLStrider<U16> indicesp; - S32 index_offset; - - index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp); - if (-1 == index_offset) - { - return; - } - - LLColor3 hb_col3 = HB.getInterpColor(); - hb_col3.clamp(); - const LLColor4 hb_col = LLColor4(hb_col3); - - const F32 min_attenuation = 0.4f; - const F32 max_attenuation = 0.7f; - const F32 attenuation = min_attenuation - + cos_angle_of_view * (max_attenuation - min_attenuation); - - LLColor4 hb_refl_col = (1-attenuation) * hb_col + attenuation * mFogColor; - face->setFaceColor(hb_refl_col); - - LLVector3 v_far[2]; - v_far[0] = v_refl_corner[1]; - v_far[1] = v_refl_corner[3]; - - if(dt_clip > 0) - { - if (dt_clip >= 1) - { - for (S32 vtx = 0; vtx < 4; ++vtx) - { - F32 ratio = far_clip / v_refl_corner[vtx].length(); - *(verticesp++) = v_refl_corner[vtx] = ratio * v_refl_corner[vtx] + mCameraPosAgent; - } - const LLVector3 draw_pos = 0.25 * - (v_refl_corner[0] + v_refl_corner[1] + v_refl_corner[2] + v_refl_corner[3]); - face->mCenterAgent = draw_pos; - } - else - { - F32 ratio = far_clip / v_refl_corner[1].length(); - v_sprite_corner[1] = v_refl_corner[1] * ratio; - - ratio = far_clip / v_refl_corner[3].length(); - v_sprite_corner[3] = v_refl_corner[3] * ratio; - - v_refl_corner[1] = (1 - dt_clip) * v_refl_corner[1] + dt_clip * v_refl_corner[0]; - v_refl_corner[3] = (1 - dt_clip) * v_refl_corner[3] + dt_clip * v_refl_corner[2]; - v_sprite_corner[0] = v_refl_corner[1]; - v_sprite_corner[2] = v_refl_corner[3]; - - for (S32 vtx = 0; vtx < 4; ++vtx) + if (face) + { + if (!face->getVertexBuffer() || quads * 4 != face->getGeomCount()) + { + face->setSize(quads * 4, quads * 6); + LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); + if (!buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE)) { - *(verticesp++) = v_sprite_corner[vtx] + mCameraPosAgent; + LL_WARNS() << "Failed to allocate Vertex Buffer for vosky to " + << face->getGeomCount() << " vertices and " + << face->getIndicesCount() << " indices" << LL_ENDL; } - - const LLVector3 draw_pos = 0.25 * - (v_refl_corner[0] + v_sprite_corner[1] + v_refl_corner[2] + v_sprite_corner[3]); - face->mCenterAgent = draw_pos; - } - - *(texCoordsp++) = TEX0tt; - *(texCoordsp++) = TEX0t; - *(texCoordsp++) = TEX1tt; - *(texCoordsp++) = TEX1t; - - *indicesp++ = index_offset + 0; - *indicesp++ = index_offset + 2; - *indicesp++ = index_offset + 1; - - *indicesp++ = index_offset + 1; - *indicesp++ = index_offset + 2; - *indicesp++ = index_offset + 3; - - index_offset += 4; - } - - if (dt_clip < 1) - { - if (dt_clip <= 0) - { - const LLVector3 draw_pos = 0.25 * - (v_refl_corner[0] + v_refl_corner[1] + v_refl_corner[2] + v_refl_corner[3]); - face->mCenterAgent = draw_pos; - } - - const F32 raws_inv = 1.f/raws; - const F32 cols_inv = 1.f/cols; - LLVector3 left = v_refl_corner[0] - v_refl_corner[1]; - LLVector3 right = v_refl_corner[2] - v_refl_corner[3]; - left *= raws_inv; - right *= raws_inv; - - F32 dt_raw = dt; - - for (S32 raw = 0; raw < raws; ++raw) - { - F32 dt_v0 = raw * raws_inv; - F32 dt_v1 = (raw + 1) * raws_inv; - const LLVector3 BL = v_refl_corner[1] + (F32)raw * left; - const LLVector3 BR = v_refl_corner[3] + (F32)raw * right; - const LLVector3 EL = BL + left; - const LLVector3 ER = BR + right; - dt_v0 = dt_raw; - dt_raw = dt_v1 = dtReflection(EL, cos_dir_from_top[0], sin_dir_from_top, diff_angl_dir); - for (S32 col = 0; col < cols; ++col) - { - F32 dt_h0 = col * cols_inv; - *(verticesp++) = (1 - dt_h0) * EL + dt_h0 * ER + mCameraPosAgent; - *(verticesp++) = (1 - dt_h0) * BL + dt_h0 * BR + mCameraPosAgent; - F32 dt_h1 = (col + 1) * cols_inv; - *(verticesp++) = (1 - dt_h1) * EL + dt_h1 * ER + mCameraPosAgent; - *(verticesp++) = (1 - dt_h1) * BL + dt_h1 * BR + mCameraPosAgent; - - *(texCoordsp++) = LLVector2(dt_h0, dt_v1); - *(texCoordsp++) = LLVector2(dt_h0, dt_v0); - *(texCoordsp++) = LLVector2(dt_h1, dt_v1); - *(texCoordsp++) = LLVector2(dt_h1, dt_v0); - - *indicesp++ = index_offset + 0; - *indicesp++ = index_offset + 2; - *indicesp++ = index_offset + 1; - - *indicesp++ = index_offset + 1; - *indicesp++ = index_offset + 2; - *indicesp++ = index_offset + 3; - - index_offset += 4; - } - } - } - - face->getVertexBuffer()->flush(); + face->setIndicesIndex(0); + face->setGeomIndex(0); + face->setVertexBuffer(buff); + } + + LLStrider<LLVector3> verticesp; + LLStrider<LLVector3> normalsp; + LLStrider<LLVector2> texCoordsp; + LLStrider<U16> indicesp; + S32 index_offset; + + index_offset = face->getGeometry(verticesp, normalsp, texCoordsp, indicesp); + if (-1 == index_offset) + { + return; + } + + LLColor3 hb_col3 = HB.getInterpColor(); + hb_col3.clamp(); + const LLColor4 hb_col = LLColor4(hb_col3); + + const F32 min_attenuation = 0.4f; + const F32 max_attenuation = 0.7f; + const F32 attenuation = min_attenuation + + cos_angle_of_view * (max_attenuation - min_attenuation); + + LLColor4 hb_refl_col = (1 - attenuation) * hb_col + attenuation * mFogColor; + face->setFaceColor(hb_refl_col); + + LLVector3 v_far[2]; + v_far[0] = v_refl_corner[1]; + v_far[1] = v_refl_corner[3]; + + if (dt_clip > 0) + { + if (dt_clip >= 1) + { + for (S32 vtx = 0; vtx < 4; ++vtx) + { + F32 ratio = far_clip / v_refl_corner[vtx].length(); + *(verticesp++) = v_refl_corner[vtx] = ratio * v_refl_corner[vtx] + mCameraPosAgent; + } + const LLVector3 draw_pos = 0.25 * + (v_refl_corner[0] + v_refl_corner[1] + v_refl_corner[2] + v_refl_corner[3]); + face->mCenterAgent = draw_pos; + } + else + { + F32 ratio = far_clip / v_refl_corner[1].length(); + v_sprite_corner[1] = v_refl_corner[1] * ratio; + + ratio = far_clip / v_refl_corner[3].length(); + v_sprite_corner[3] = v_refl_corner[3] * ratio; + + v_refl_corner[1] = (1 - dt_clip) * v_refl_corner[1] + dt_clip * v_refl_corner[0]; + v_refl_corner[3] = (1 - dt_clip) * v_refl_corner[3] + dt_clip * v_refl_corner[2]; + v_sprite_corner[0] = v_refl_corner[1]; + v_sprite_corner[2] = v_refl_corner[3]; + + for (S32 vtx = 0; vtx < 4; ++vtx) + { + *(verticesp++) = v_sprite_corner[vtx] + mCameraPosAgent; + } + + const LLVector3 draw_pos = 0.25 * + (v_refl_corner[0] + v_sprite_corner[1] + v_refl_corner[2] + v_sprite_corner[3]); + face->mCenterAgent = draw_pos; + } + + *(texCoordsp++) = TEX0tt; + *(texCoordsp++) = TEX0t; + *(texCoordsp++) = TEX1tt; + *(texCoordsp++) = TEX1t; + + *indicesp++ = index_offset + 0; + *indicesp++ = index_offset + 2; + *indicesp++ = index_offset + 1; + + *indicesp++ = index_offset + 1; + *indicesp++ = index_offset + 2; + *indicesp++ = index_offset + 3; + + index_offset += 4; + } + + if (dt_clip < 1) + { + if (dt_clip <= 0) + { + const LLVector3 draw_pos = 0.25 * + (v_refl_corner[0] + v_refl_corner[1] + v_refl_corner[2] + v_refl_corner[3]); + face->mCenterAgent = draw_pos; + } + + const F32 raws_inv = 1.f / raws; + const F32 cols_inv = 1.f / cols; + LLVector3 left = v_refl_corner[0] - v_refl_corner[1]; + LLVector3 right = v_refl_corner[2] - v_refl_corner[3]; + left *= raws_inv; + right *= raws_inv; + + F32 dt_raw = dt; + + for (S32 raw = 0; raw < raws; ++raw) + { + F32 dt_v0 = raw * raws_inv; + F32 dt_v1 = (raw + 1) * raws_inv; + const LLVector3 BL = v_refl_corner[1] + (F32)raw * left; + const LLVector3 BR = v_refl_corner[3] + (F32)raw * right; + const LLVector3 EL = BL + left; + const LLVector3 ER = BR + right; + dt_v0 = dt_raw; + dt_raw = dt_v1 = dtReflection(EL, cos_dir_from_top[0], sin_dir_from_top, diff_angl_dir); + for (S32 col = 0; col < cols; ++col) + { + F32 dt_h0 = col * cols_inv; + *(verticesp++) = (1 - dt_h0) * EL + dt_h0 * ER + mCameraPosAgent; + *(verticesp++) = (1 - dt_h0) * BL + dt_h0 * BR + mCameraPosAgent; + F32 dt_h1 = (col + 1) * cols_inv; + *(verticesp++) = (1 - dt_h1) * EL + dt_h1 * ER + mCameraPosAgent; + *(verticesp++) = (1 - dt_h1) * BL + dt_h1 * BR + mCameraPosAgent; + + *(texCoordsp++) = LLVector2(dt_h0, dt_v1); + *(texCoordsp++) = LLVector2(dt_h0, dt_v0); + *(texCoordsp++) = LLVector2(dt_h1, dt_v1); + *(texCoordsp++) = LLVector2(dt_h1, dt_v0); + + *indicesp++ = index_offset + 0; + *indicesp++ = index_offset + 2; + *indicesp++ = index_offset + 1; + + *indicesp++ = index_offset + 1; + *indicesp++ = index_offset + 2; + *indicesp++ = index_offset + 3; + + index_offset += 4; + } + } + } + + face->getVertexBuffer()->flush(); + } } @@ -2028,6 +1855,8 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H, void LLVOSky::updateFog(const F32 distance) { + +// LEGACY_ATMOSPHERICS if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOG)) { if (!LLGLSLShader::sNoFixedFunction) @@ -2074,7 +1903,6 @@ void LLVOSky::updateFog(const F32 distance) tosun_45.normalize(); // Sky colors, just slightly above the horizon in the direction of the sun, perpendicular to the sun, and at a 45 degree angle to the sun. - initAtmospherics(); res_color[0] = calcSkyColorInDir(tosun); res_color[1] = calcSkyColorInDir(perp_tosun); res_color[2] = calcSkyColorInDir(tosun_45); @@ -2133,11 +1961,12 @@ void LLVOSky::updateFog(const F32 distance) } else { + LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater(); F32 depth = water_height - camera_height; // get the water param manager variables - float water_fog_density = LLWaterParamManager::getInstance()->getFogDensity(); - LLColor4 water_fog_color(LLDrawPoolWater::sWaterFogColor.mV); + float water_fog_density = pwater->getFogDensity(); + LLColor4 water_fog_color(pwater->getFogColor()); // adjust the color based on depth. We're doing linear approximations float depth_scale = gSavedSettings.getF32("WaterGLFogDepthScale"); @@ -2245,7 +2074,7 @@ void LLVOSky::initSunDirection(const LLVector3 &sun_dir, const LLVector3 &sun_an } } -void LLVOSky::setSunDirection(const LLVector3 &sun_dir, const LLVector3 &sun_ang_velocity) +void LLVOSky::setSunDirection(const LLVector3 &sun_dir, const LLVector3 &moon_dir) { LLVector3 sun_direction = (sun_dir.length() == 0) ? LLVector3::x_axis : sun_dir; sun_direction.normalize(); @@ -2268,10 +2097,85 @@ void LLVOSky::setSunDirection(const LLVector3 &sun_dir, const LLVector3 &sun_ang F32 dp = mLastLightingDirection * sun_direction; mSun.setDirection(sun_direction); - mSun.setAngularVelocity(sun_ang_velocity); - mMoon.setDirection(-sun_direction); + + mMoon.setDirection(moon_dir); calcAtmospherics(); if (dp < 0.995f) { //the sun jumped a great deal, update immediately mForceUpdate = TRUE; } } + +// void LLVOSky::checkAndLoadSkyTextures(LLDrawPoolWLSky *pskypool) +// { +// LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); +// +// if (mMoonCurrentId != psky->getMoonTextureId()) +// { +// mMoonCurrentId = psky->getMoonTextureId(); +// if (mMoonCurrentId.isNull()) +// { +// mMoonTexturep = NULL; +// mMoon.setDraw(FALSE); +// } +// else +// { +// mMoonTexturep = LLViewerTextureManager::getFetchedTexture(mMoonCurrentId, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); +// if (mMoonTexturep) +// { +// mMoonTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); +// } +// mMoon.setDraw(TRUE); +// } +// mFace[FACE_MOON] = mDrawable->addFace(pskypool, mMoonTexturep); +// } +// +// if (mSunCurrentId != psky->getSunTextureId()) +// { +// mSunCurrentId = psky->getSunTextureId(); +// if (mSunCurrentId.isNull()) +// { +// mSunTexturep = NULL; +// mSun.setDraw(FALSE); +// } +// else +// { +// mSunTexturep = LLViewerTextureManager::getFetchedTexture(mSunCurrentId, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); +// if (mSunTexturep) +// { +// mSunTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); +// } +// mSun.setDraw(TRUE); +// } +// mFace[FACE_SUN] = mDrawable->addFace(pskypool, mSunTexturep); +// } +// } + +LLColor4U LLVOSky::getFadeColor() const +{ + return LLEnvironment::instance().getCurrentSky()->getFadeColor(); +} + +LLColor3 LLVOSky::getSunDiffuseColor() const +{ + return LLEnvironment::instance().getCurrentSky()->getSunDiffuse(); +} + +LLColor3 LLVOSky::getMoonDiffuseColor() const +{ + return LLEnvironment::instance().getCurrentSky()->getMoonDiffuse(); +} + +LLColor4 LLVOSky::getSunAmbientColor() const +{ + return LLEnvironment::instance().getCurrentSky()->getSunAmbient(); +} + +LLColor4 LLVOSky::getMoonAmbientColor() const +{ + return LLEnvironment::instance().getCurrentSky()->getMoonAmbient(); +} + +LLColor4 LLVOSky::getTotalAmbientColor() const +{ + return LLEnvironment::instance().getCurrentSky()->getTotalAmbient(); +} diff --git a/indra/newview/llvosky.h b/indra/newview/llvosky.h index 9cfb9773bd..2c253aed51 100644 --- a/indra/newview/llvosky.h +++ b/indra/newview/llvosky.h @@ -33,7 +33,8 @@ #include "llviewertexture.h" #include "llviewerobject.h" #include "llframetimer.h" - +#include "v3colorutil.h" +#include "llsettingssky.h" ////////////////////////////////// // @@ -85,26 +86,6 @@ BOOL clip_quad_to_horizon(F32& t_left, F32& t_right, LLVector3 v_clipped[4], const LLVector3 v_corner[4], const F32 cos_max_angle); F32 clip_side_to_horizon(const LLVector3& v0, const LLVector3& v1, const F32 cos_max_angle); -inline F32 color_intens ( const LLColor3 &col ) -{ - return col.mV[0] + col.mV[1] + col.mV[2]; -} - -inline F32 color_max(const LLColor3 &col) -{ - return llmax(col.mV[0], col.mV[1], col.mV[2]); -} - -inline F32 color_max(const LLColor4 &col) -{ - return llmax(col.mV[0], col.mV[1], col.mV[2]); -} - - -inline F32 color_min(const LLColor3 &col) -{ - return llmin(col.mV[0], col.mV[1], col.mV[2]); -} class LLFace; class LLHaze; @@ -398,31 +379,11 @@ class LLCubeMap; class LLVOSky : public LLStaticViewerObject { -public: - /// WL PARAMS - F32 dome_radius; - F32 dome_offset_ratio; - LLColor3 sunlight_color; - LLColor3 ambient; - F32 gamma; - LLVector4 lightnorm; - LLVector4 unclamped_lightnorm; - LLColor3 blue_density; - LLColor3 blue_horizon; - F32 haze_density; - F32 haze_horizon; - F32 density_multiplier; - F32 max_y; - LLColor3 glow; - F32 cloud_shadow; - LLColor3 cloud_color; - F32 cloud_scale; - LLColor3 cloud_pos_density1; - LLColor3 cloud_pos_density2; public: - void initAtmospherics(void); void calcAtmospherics(void); + +// LEGACY_ATMOSPHERICS LLColor3 createDiffuseFromWL(LLColor3 diffuse, LLColor3 ambient, LLColor3 sundiffuse, LLColor3 sunambient); LLColor3 createAmbientFromWL(LLColor3 ambient, LLColor3 sundiffuse, LLColor3 sunambient); @@ -433,8 +394,16 @@ public: LLColor3 calcSkyColorWLFrag(LLVector3 & Pn, LLColor3 & vary_HazeColor, LLColor3 & vary_CloudColorSun, LLColor3 & vary_CloudColorAmbient, F32 & vary_CloudDensity, LLVector2 vary_HorizontalProjection[2]); + LLColor4 calcSkyColorInDir(const LLVector3& dir, bool isShiny = false); + + LLColor3 calcRadianceAtPoint(const LLVector3& pos) const + { + F32 radiance = mBrightnessScaleGuess * mSun.getIntensity(); + return LLColor3(radiance, radiance, radiance); + } + void initSkyTextureDirs(const S32 side, const S32 tile); + void createSkyTexture(const S32 side, const S32 tile); -public: enum { FACE_SIDE0, @@ -470,17 +439,6 @@ public: /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); - void initSkyTextureDirs(const S32 side, const S32 tile); - void createSkyTexture(const S32 side, const S32 tile); - - LLColor4 calcSkyColorInDir(const LLVector3& dir, bool isShiny = false); - - LLColor3 calcRadianceAtPoint(const LLVector3& pos) const - { - F32 radiance = mBrightnessScaleGuess * mSun.getIntensity(); - return LLColor3(radiance, radiance, radiance); - } - const LLHeavenBody& getSun() const { return mSun; } const LLHeavenBody& getMoon() const { return mMoon; } @@ -489,13 +447,12 @@ public: const LLVector3& getToMoon() const { return mMoon.getDirection(); } const LLVector3& getToMoonLast() const { return mMoon.getDirectionCached(); } BOOL isSunUp() const { return mSun.getDirectionCached().mV[2] > -0.05f; } - void calculateColors(); - LLColor3 getSunDiffuseColor() const { return mSunDiffuse; } - LLColor3 getMoonDiffuseColor() const { return mMoonDiffuse; } - LLColor4 getSunAmbientColor() const { return mSunAmbient; } - LLColor4 getMoonAmbientColor() const { return mMoonAmbient; } - const LLColor4& getTotalAmbientColor() const { return mTotalAmbient; } + LLColor3 getSunDiffuseColor() const; + LLColor3 getMoonDiffuseColor() const; + LLColor4 getSunAmbientColor() const; + LLColor4 getMoonAmbientColor() const; + LLColor4 getTotalAmbientColor() const; LLColor4 getFogColor() const { return mFogColor; } LLColor4 getGLFogColor() const { return mGLFogCol; } @@ -503,7 +460,7 @@ public: void initSunDirection(const LLVector3 &sun_dir, const LLVector3 &sun_ang_velocity); - void setSunDirection(const LLVector3 &sun_dir, const LLVector3 &sun_ang_velocity); + void setSunDirection(const LLVector3 &sun_dir, const LLVector3 &moon_dir); BOOL updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 side, const BOOL is_sun, LLHeavenBody& hb, const F32 sin_max_angle, @@ -527,8 +484,8 @@ public: void setWorldScale(const F32 s) { mWorldScale = s; } void updateFog(const F32 distance); void setFogRatio(const F32 fog_ratio) { mFogRatio = fog_ratio; } - LLColor4U getFadeColor() const { return mFadeColor; } - F32 getFogRatio() const { return mFogRatio; } + LLColor4U getFadeColor() const; + F32 getFogRatio() const { return mFogRatio; } void setCloudDensity(F32 cloud_density) { mCloudDensity = cloud_density; } void setWind ( const LLVector3& wind ) { mWind = wind.length(); } @@ -595,13 +552,6 @@ protected: F32 mFogRatio; F32 mWorldScale; - LLColor4 mSunAmbient; - LLColor4 mMoonAmbient; - LLColor4 mTotalAmbient; - LLColor3 mSunDiffuse; - LLColor3 mMoonDiffuse; - LLColor4U mFadeColor; // Color to fade in from - LLPointer<LLCubeMap> mCubeMap; // Cube map for the environment S32 mDrawRefl; diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp index 3b9b96e9f1..0062eb5edd 100644 --- a/indra/newview/llvowlsky.cpp +++ b/indra/newview/llvowlsky.cpp @@ -32,8 +32,9 @@ #include "llsky.h" #include "lldrawpoolwlsky.h" #include "llface.h" -#include "llwlparammanager.h" #include "llviewercontrol.h" +#include "llenvironment.h" +#include "llsettingssky.h" #define DOME_SLICES 1 const F32 LLVOWLSky::DISTANCE_TO_STARS = (HORIZON_DIST - 10.f)*0.25f; @@ -232,7 +233,7 @@ void subdivide(LLVertexBuffer& in, LLVertexBuffer* ret) void chop(LLVertexBuffer& in, LLVertexBuffer* out) { //chop off all triangles below horizon - F32 d = LLWLParamManager::sParamMgr->getDomeOffset() * LLWLParamManager::sParamMgr->getDomeRadius(); + F32 d = LLEnvironment::instance().getCamHeight(); std::vector<LLVector3> vert; @@ -409,7 +410,7 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable) #else mStripsVerts = new LLVertexBuffer(LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB); - const F32 RADIUS = LLWLParamManager::sParamMgr->getDomeRadius(); + const F32 RADIUS = LLEnvironment::getCurrentSky()->getDomeRadius(); LLPointer<LLVertexBuffer> temp = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, 0); temp->allocateBuffer(12, 60, TRUE); @@ -584,7 +585,7 @@ void LLVOWLSky::buildFanBuffer(LLStrider<LLVector3> & vertices, LLStrider<LLVector2> & texCoords, LLStrider<U16> & indices) { - const F32 RADIUS = LLWLParamManager::getInstance()->getDomeRadius(); + const F32 RADIUS = LLEnvironment::instance().getCurrentSky()->getDomeRadius(); U32 i, num_slices; F32 phi0, theta, x0, y0, z0; @@ -645,7 +646,7 @@ void LLVOWLSky::buildStripsBuffer(U32 begin_stack, U32 end_stack, LLStrider<LLVector2> & texCoords, LLStrider<U16> & indices) { - const F32 RADIUS = LLWLParamManager::getInstance()->getDomeRadius(); + const F32 RADIUS = LLEnvironment::instance().getCurrentSky()->getDomeRadius(); U32 i, j, num_slices, num_stacks; F32 phi0, theta, x0, y0, z0; diff --git a/indra/newview/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp deleted file mode 100644 index b484b6d709..0000000000 --- a/indra/newview/llwaterparammanager.cpp +++ /dev/null @@ -1,442 +0,0 @@ -/** - * @file llwaterparammanager.cpp - * @brief Implementation for the LLWaterParamManager class. - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, 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 "llwaterparammanager.h" - -#include "llrender.h" - -#include "pipeline.h" -#include "llsky.h" - -#include "lldiriterator.h" -#include "llfloaterreg.h" -#include "llsliderctrl.h" -#include "llspinctrl.h" -#include "llcheckboxctrl.h" -#include "lluictrlfactory.h" -#include "llviewercontrol.h" -#include "llviewercamera.h" -#include "llcombobox.h" -#include "lllineeditor.h" -#include "llsdserialize.h" - -#include "v4math.h" -#include "llviewercontrol.h" -#include "lldrawpoolwater.h" -#include "llagent.h" -#include "llagentcamera.h" -#include "llviewerregion.h" - -#include "llwlparammanager.h" -#include "llwaterparamset.h" - -#include "curl/curl.h" - -LLWaterParamManager::LLWaterParamManager() : - mFogColor(22.f/255.f, 43.f/255.f, 54.f/255.f, 0.0f, 0.0f, "waterFogColor", "WaterFogColor"), - mFogDensity(4, "waterFogDensity", 2), - mUnderWaterFogMod(0.25, "underWaterFogMod"), - mNormalScale(2.f, 2.f, 2.f, "normScale"), - mFresnelScale(0.5f, "fresnelScale"), - mFresnelOffset(0.4f, "fresnelOffset"), - mScaleAbove(0.025f, "scaleAbove"), - mScaleBelow(0.2f, "scaleBelow"), - mBlurMultiplier(0.1f, "blurMultiplier"), - mWave1Dir(.5f, .5f, "wave1Dir"), - mWave2Dir(.5f, .5f, "wave2Dir"), - mDensitySliderValue(1.0f), - mWaterFogKS(1.0f) -{ -} - -LLWaterParamManager::~LLWaterParamManager() -{ -} - -void LLWaterParamManager::loadAllPresets() -{ - // First, load system (coming out of the box) water presets. - loadPresetsFromDir(getSysDir()); - - // Then load user presets. Note that user day presets will modify any system ones already loaded. - loadPresetsFromDir(getUserDir()); -} - -void LLWaterParamManager::loadPresetsFromDir(const std::string& dir) -{ - LL_DEBUGS("AppInit", "Shaders") << "Loading water presets from " << dir << LL_ENDL; - - LLDirIterator dir_iter(dir, "*.xml"); - while (1) - { - std::string file; - if (!dir_iter.next(file)) - { - break; // no more files - } - - std::string path = gDirUtilp->add(dir, file); - if (!loadPreset(path)) - { - LL_WARNS() << "Error loading water preset from " << path << LL_ENDL; - } - } -} - -bool LLWaterParamManager::loadPreset(const std::string& path) -{ - llifstream xml_file; - std::string name(gDirUtilp->getBaseFileName(LLURI::unescape(path), /*strip_exten = */ true)); - - xml_file.open(path.c_str()); - if (!xml_file) - { - return false; - } - - LL_DEBUGS("AppInit", "Shaders") << "Loading water " << name << LL_ENDL; - - LLSD params_data; - LLPointer<LLSDParser> parser = new LLSDXMLParser(); - parser->parse(xml_file, params_data, LLSDSerialize::SIZE_UNLIMITED); - xml_file.close(); - - if (hasParamSet(name)) - { - setParamSet(name, params_data); - } - else - { - addParamSet(name, params_data); - } - - return true; -} - -void LLWaterParamManager::savePreset(const std::string & name) -{ - llassert(!name.empty()); - - // make an empty llsd - LLSD paramsData(LLSD::emptyMap()); - std::string pathName(getUserDir() + LLURI::escape(name) + ".xml"); - - // fill it with LLSD windlight params - paramsData = mParamList[name].getAll(); - - // write to file - llofstream presetsXML(pathName.c_str()); - LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter(); - formatter->format(paramsData, presetsXML, LLSDFormatter::OPTIONS_PRETTY); - presetsXML.close(); - - propagateParameters(); -} - -void LLWaterParamManager::propagateParameters(void) -{ - // bind the variables only if we're using shaders - if(gPipeline.canUseVertexShaders()) - { - LLViewerShaderMgr::shader_iter shaders_iter, end_shaders; - end_shaders = LLViewerShaderMgr::instance()->endShaders(); - for(shaders_iter = LLViewerShaderMgr::instance()->beginShaders(); shaders_iter != end_shaders; ++shaders_iter) - { - if (shaders_iter->mProgramObject != 0 - && shaders_iter->mShaderGroup == LLGLSLShader::SG_WATER) - { - shaders_iter->mUniformsDirty = TRUE; - } - } - } - - bool err; - F32 fog_density_slider = - log(mCurParams.getFloat(mFogDensity.mName, err)) / - log(mFogDensity.mBase); - - setDensitySliderValue(fog_density_slider); -} - -void LLWaterParamManager::updateShaderUniforms(LLGLSLShader * shader) -{ - if (shader->mShaderGroup == LLGLSLShader::SG_WATER) - { - shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, LLWLParamManager::getInstance()->getRotatedLightDir().mV); -shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV); - shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, LLDrawPoolWater::sWaterFogColor.mV); - shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, mWaterPlane.mV); - shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, getFogDensity()); - shader->uniform1f(LLShaderMgr::WATER_FOGKS, mWaterFogKS); - shader->uniform1f(LLViewerShaderMgr::DISTANCE_MULTIPLIER, 0); - } -} - -void LLWaterParamManager::applyParams(const LLSD& params, bool interpolate) -{ - if (params.size() == 0) - { - LL_WARNS() << "Undefined water params" << LL_ENDL; - return; - } - - if (interpolate) - { - LLWLParamManager::getInstance()->mAnimator.startInterpolation(params); - } - else - { - mCurParams.setAll(params); - } -} - -static LLTrace::BlockTimerStatHandle FTM_UPDATE_WATERPARAM("Update Water Params"); - -void LLWaterParamManager::update(LLViewerCamera * cam) -{ - LL_RECORD_BLOCK_TIME(FTM_UPDATE_WATERPARAM); - - // update the shaders and the menu - propagateParameters(); - - // 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, gAgent.getRegion()->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)); - - LLVector3 sunMoonDir; - if (gSky.getSunDirection().mV[2] > LLSky::NIGHTTIME_ELEVATION_COS) - { - sunMoonDir = gSky.getSunDirection(); - } - else - { - sunMoonDir = gSky.getMoonDirection(); - } - sunMoonDir.normVec(); - mWaterFogKS = 1.f/llmax(sunMoonDir.mV[2], WATER_FOG_LIGHT_CLAMP); - - LLViewerShaderMgr::shader_iter shaders_iter, end_shaders; - end_shaders = LLViewerShaderMgr::instance()->endShaders(); - for(shaders_iter = LLViewerShaderMgr::instance()->beginShaders(); shaders_iter != end_shaders; ++shaders_iter) - { - if (shaders_iter->mProgramObject != 0 - && shaders_iter->mShaderGroup == LLGLSLShader::SG_WATER) - { - shaders_iter->mUniformsDirty = TRUE; - } - } - } -} - -bool LLWaterParamManager::addParamSet(const std::string& name, LLWaterParamSet& param) -{ - // add a new one if not one there already - preset_map_t::iterator mIt = mParamList.find(name); - if(mIt == mParamList.end()) - { - mParamList[name] = param; - mPresetListChangeSignal(); - return true; - } - - return false; -} - -BOOL LLWaterParamManager::addParamSet(const std::string& name, LLSD const & param) -{ - LLWaterParamSet param_set; - param_set.setAll(param); - return addParamSet(name, param_set); -} - -bool LLWaterParamManager::getParamSet(const std::string& name, LLWaterParamSet& param) -{ - // find it and set it - preset_map_t::iterator mIt = mParamList.find(name); - if(mIt != mParamList.end()) - { - param = mParamList[name]; - param.mName = name; - return true; - } - - return false; -} - -bool LLWaterParamManager::hasParamSet(const std::string& name) -{ - LLWaterParamSet dummy; - return getParamSet(name, dummy); -} - -bool LLWaterParamManager::setParamSet(const std::string& name, LLWaterParamSet& param) -{ - mParamList[name] = param; - - return true; -} - -bool LLWaterParamManager::setParamSet(const std::string& name, const LLSD & param) -{ - // quick, non robust (we won't be working with files, but assets) check - if(!param.isMap()) - { - return false; - } - - mParamList[name].setAll(param); - - return true; -} - -bool LLWaterParamManager::removeParamSet(const std::string& name, bool delete_from_disk) -{ - // remove from param list - preset_map_t::iterator it = mParamList.find(name); - if (it == mParamList.end()) - { - LL_WARNS("WindLight") << "No water preset named " << name << LL_ENDL; - return false; - } - - mParamList.erase(it); - - // remove from file system if requested - if (delete_from_disk) - { - if (gDirUtilp->deleteFilesInDir(getUserDir(), LLURI::escape(name) + ".xml") < 1) - { - LL_WARNS("WindLight") << "Error removing water preset " << name << " from disk" << LL_ENDL; - } - } - - // signal interested parties - mPresetListChangeSignal(); - return true; -} - -bool LLWaterParamManager::isSystemPreset(const std::string& preset_name) const -{ - // *TODO: file system access is excessive here. - return gDirUtilp->fileExists(getSysDir() + LLURI::escape(preset_name) + ".xml"); -} - -void LLWaterParamManager::getPresetNames(preset_name_list_t& presets) const -{ - presets.clear(); - - for (preset_map_t::const_iterator it = mParamList.begin(); it != mParamList.end(); ++it) - { - presets.push_back(it->first); - } -} - -void LLWaterParamManager::getPresetNames(preset_name_list_t& user_presets, preset_name_list_t& system_presets) const -{ - user_presets.clear(); - system_presets.clear(); - - for (preset_map_t::const_iterator it = mParamList.begin(); it != mParamList.end(); ++it) - { - if (isSystemPreset(it->first)) - { - system_presets.push_back(it->first); - } - else - { - user_presets.push_back(it->first); - } - } -} - -void LLWaterParamManager::getUserPresetNames(preset_name_list_t& user_presets) const -{ - preset_name_list_t dummy; - getPresetNames(user_presets, dummy); -} - -boost::signals2::connection LLWaterParamManager::setPresetListChangeCallback(const preset_list_signal_t::slot_type& cb) -{ - return mPresetListChangeSignal.connect(cb); -} - -F32 LLWaterParamManager::getFogDensity(void) -{ - bool err; - - F32 fogDensity = mCurParams.getFloat("waterFogDensity", err); - - // modify if we're underwater - const F32 water_height = gAgent.getRegion() ? gAgent.getRegion()->getWaterHeight() : 0.f; - F32 camera_height = gAgentCamera.getCameraPositionAgent().mV[2]; - if(camera_height <= water_height) - { - // raise it to the underwater fog density modifier - fogDensity = pow(fogDensity, mCurParams.getFloat("underWaterFogMod", err)); - } - - return fogDensity; -} - -// virtual static -void LLWaterParamManager::initSingleton() -{ - LL_DEBUGS("Windlight") << "Initializing water" << LL_ENDL; - loadAllPresets(); -} - -// static -std::string LLWaterParamManager::getSysDir() -{ - return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/water", ""); -} - -// static -std::string LLWaterParamManager::getUserDir() -{ - return gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS , "windlight/water", ""); -} diff --git a/indra/newview/llwaterparammanager.h b/indra/newview/llwaterparammanager.h deleted file mode 100644 index 3f169e439a..0000000000 --- a/indra/newview/llwaterparammanager.h +++ /dev/null @@ -1,413 +0,0 @@ -/** - * @file llwaterparammanager.h - * @brief Implementation for the LLWaterParamManager class. - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, 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_WATER_PARAMMANAGER_H -#define LL_WATER_PARAMMANAGER_H - -#include <list> -#include <map> -#include "llwaterparamset.h" -#include "llviewercamera.h" -#include "v4color.h" - -const F32 WATER_FOG_LIGHT_CLAMP = 0.3f; - -// color control -struct WaterColorControl { - - F32 mR, mG, mB, mA, mI; /// the values - std::string mName; /// name to use to dereference params - std::string mSliderName; /// name of the slider in menu - bool mHasSliderName; /// only set slider name for true color types - - inline WaterColorControl(F32 red, F32 green, F32 blue, F32 alpha, - F32 intensity, const std::string& n, const std::string& sliderName = LLStringUtil::null) - : mR(red), mG(green), mB(blue), mA(alpha), mI(intensity), mName(n), mSliderName(sliderName) - { - // if there's a slider name, say we have one - mHasSliderName = false; - if (mSliderName != "") { - mHasSliderName = true; - } - } - - inline WaterColorControl & operator = (LLColor4 const & val) - { - mR = val.mV[0]; - mG = val.mV[1]; - mB = val.mV[2]; - mA = val.mV[3]; - return *this; - } - - inline operator LLColor4 (void) const - { - return LLColor4(mR, mG, mB, mA); - } - - inline WaterColorControl & operator = (LLVector4 const & val) - { - mR = val.mV[0]; - mG = val.mV[1]; - mB = val.mV[2]; - mA = val.mV[3]; - return *this; - } - - inline operator LLVector4 (void) const - { - return LLVector4(mR, mG, mB, mA); - } - - inline operator LLVector3 (void) const - { - return LLVector3(mR, mG, mB); - } - - inline void update(LLWaterParamSet & params) const - { - params.set(mName, mR, mG, mB, mA); - } -}; - -struct WaterVector3Control -{ - F32 mX; - F32 mY; - F32 mZ; - - std::string mName; - - // basic constructor - inline WaterVector3Control(F32 valX, F32 valY, F32 valZ, const std::string& n) - : mX(valX), mY(valY), mZ(valZ), mName(n) - { - } - - inline WaterVector3Control & operator = (LLVector3 const & val) - { - mX = val.mV[0]; - mY = val.mV[1]; - mZ = val.mV[2]; - - return *this; - } - - inline void update(LLWaterParamSet & params) const - { - params.set(mName, mX, mY, mZ); - } - -}; - -struct WaterVector2Control -{ - F32 mX; - F32 mY; - - std::string mName; - - // basic constructor - inline WaterVector2Control(F32 valX, F32 valY, const std::string& n) - : mX(valX), mY(valY), mName(n) - { - } - - inline WaterVector2Control & operator = (LLVector2 const & val) - { - mX = val.mV[0]; - mY = val.mV[1]; - - return *this; - } - - inline void update(LLWaterParamSet & params) const - { - params.set(mName, mX, mY); - } -}; - -// float slider control -struct WaterFloatControl -{ - F32 mX; - std::string mName; - F32 mMult; - - inline WaterFloatControl(F32 val, const std::string& n, F32 m=1.0f) - : mX(val), mName(n), mMult(m) - { - } - - inline WaterFloatControl & operator = (LLVector4 const & val) - { - mX = val.mV[0]; - - return *this; - } - - inline operator F32 (void) const - { - return mX; - } - - inline void update(LLWaterParamSet & params) const - { - params.set(mName, mX); - } -}; - -// float slider control -struct WaterExpFloatControl -{ - F32 mExp; - std::string mName; - F32 mBase; - - inline WaterExpFloatControl(F32 val, const std::string& n, F32 b) - : mExp(val), mName(n), mBase(b) - { - } - - inline WaterExpFloatControl & operator = (F32 val) - { - mExp = log(val) / log(mBase); - - return *this; - } - - inline operator F32 (void) const - { - return pow(mBase, mExp); - } - - inline void update(LLWaterParamSet & params) const - { - params.set(mName, pow(mBase, mExp)); - } -}; - - -/// WindLight parameter manager class - what controls all the wind light shaders -class LLWaterParamManager : public LLSingleton<LLWaterParamManager> -{ - LLSINGLETON(LLWaterParamManager); - ~LLWaterParamManager(); - LOG_CLASS(LLWaterParamManager); -public: - typedef std::list<std::string> preset_name_list_t; - typedef std::map<std::string, LLWaterParamSet> preset_map_t; - typedef boost::signals2::signal<void()> preset_list_signal_t; - - /// save the parameter presets to file - void savePreset(const std::string & name); - - /// send the parameters to the shaders - void propagateParameters(void); - - // display specified water - void applyParams(const LLSD& params, bool interpolate); - - /// update information for the shader - void update(LLViewerCamera * cam); - - /// Update shader uniforms that have changed. - void updateShaderUniforms(LLGLSLShader * shader); - - /// add a param to the list - bool addParamSet(const std::string& name, LLWaterParamSet& param); - - /// add a param to the list - BOOL addParamSet(const std::string& name, LLSD const & param); - - /// get a param from the list - bool getParamSet(const std::string& name, LLWaterParamSet& param); - - /// check whether the preset is in the list - bool hasParamSet(const std::string& name); - - /// set the param in the list with a new param - bool setParamSet(const std::string& name, LLWaterParamSet& param); - - /// set the param in the list with a new param - bool setParamSet(const std::string& name, LLSD const & param); - - /// gets rid of a parameter and any references to it - /// returns true if successful - bool removeParamSet(const std::string& name, bool delete_from_disk); - - /// @return true if the preset comes out of the box - bool isSystemPreset(const std::string& preset_name) const; - - /// @return all named water presets. - const preset_map_t& getPresets() const { return mParamList; } - - /// @return user and system preset names as a single list - void getPresetNames(preset_name_list_t& presets) const; - - /// @return user and system preset names separately - void getPresetNames(preset_name_list_t& user_presets, preset_name_list_t& system_presets) const; - - /// @return list of user presets names - void getUserPresetNames(preset_name_list_t& user_presets) const; - - /// Emitted when a preset gets added or deleted. - boost::signals2::connection setPresetListChangeCallback(const preset_list_signal_t::slot_type& cb); - - /// set the normap map we want for water - bool setNormalMapID(const LLUUID& img); - - void setDensitySliderValue(F32 val); - - /// getters for all the different things water param manager maintains - LLUUID getNormalMapID(void); - LLVector2 getWave1Dir(void); - LLVector2 getWave2Dir(void); - F32 getScaleAbove(void); - F32 getScaleBelow(void); - LLVector3 getNormalScale(void); - F32 getFresnelScale(void); - F32 getFresnelOffset(void); - F32 getBlurMultiplier(void); - F32 getFogDensity(void); - LLColor4 getFogColor(void); - -public: - - LLWaterParamSet mCurParams; - - /// Atmospherics - WaterColorControl mFogColor; - WaterExpFloatControl mFogDensity; - WaterFloatControl mUnderWaterFogMod; - - /// wavelet scales and directions - WaterVector3Control mNormalScale; - WaterVector2Control mWave1Dir; - WaterVector2Control mWave2Dir; - - // controls how water is reflected and refracted - WaterFloatControl mFresnelScale; - WaterFloatControl mFresnelOffset; - WaterFloatControl mScaleAbove; - WaterFloatControl mScaleBelow; - WaterFloatControl mBlurMultiplier; - - F32 mDensitySliderValue; - -private: - /*virtual*/ void initSingleton(); - void loadAllPresets(); - void loadPresetsFromDir(const std::string& dir); - bool loadPreset(const std::string& path); - - static std::string getSysDir(); - static std::string getUserDir(); - - LLVector4 mWaterPlane; - F32 mWaterFogKS; - - // list of all the parameters, listed by name - preset_map_t mParamList; - - preset_list_signal_t mPresetListChangeSignal; -}; - -inline void LLWaterParamManager::setDensitySliderValue(F32 val) -{ - val /= 10.0f; - val = 1.0f - val; - val *= val * val; -// val *= val; - mDensitySliderValue = val; -} - -inline LLUUID LLWaterParamManager::getNormalMapID() -{ - return mCurParams.mParamValues["normalMap"].asUUID(); -} - -inline bool LLWaterParamManager::setNormalMapID(const LLUUID& id) -{ - mCurParams.mParamValues["normalMap"] = id; - return true; -} - -inline LLVector2 LLWaterParamManager::getWave1Dir(void) -{ - bool err; - return mCurParams.getVector2("wave1Dir", err); -} - -inline LLVector2 LLWaterParamManager::getWave2Dir(void) -{ - bool err; - return mCurParams.getVector2("wave2Dir", err); -} - -inline F32 LLWaterParamManager::getScaleAbove(void) -{ - bool err; - return mCurParams.getFloat("scaleAbove", err); -} - -inline F32 LLWaterParamManager::getScaleBelow(void) -{ - bool err; - return mCurParams.getFloat("scaleBelow", err); -} - -inline LLVector3 LLWaterParamManager::getNormalScale(void) -{ - bool err; - return mCurParams.getVector3("normScale", err); -} - -inline F32 LLWaterParamManager::getFresnelScale(void) -{ - bool err; - return mCurParams.getFloat("fresnelScale", err); -} - -inline F32 LLWaterParamManager::getFresnelOffset(void) -{ - bool err; - return mCurParams.getFloat("fresnelOffset", err); -} - -inline F32 LLWaterParamManager::getBlurMultiplier(void) -{ - bool err; - return mCurParams.getFloat("blurMultiplier", err); -} - -inline LLColor4 LLWaterParamManager::getFogColor(void) -{ - bool err; - return LLColor4(mCurParams.getVector4("waterFogColor", err)); -} - -#endif diff --git a/indra/newview/llwaterparamset.cpp b/indra/newview/llwaterparamset.cpp deleted file mode 100644 index 9cc91d2246..0000000000 --- a/indra/newview/llwaterparamset.cpp +++ /dev/null @@ -1,266 +0,0 @@ -/** - * @file llwaterparamset.cpp - * @brief Implementation for the LLWaterParamSet class. - * - * $LicenseInfo:firstyear=2005&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, 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 "llwaterparamset.h" -#include "llsd.h" - -#include "llwaterparammanager.h" -#include "lluictrlfactory.h" -#include "llsliderctrl.h" -#include "llviewertexturelist.h" -#include "llviewercontrol.h" -#include "lluuid.h" - -#include <llgl.h> - -#include <sstream> - -LLWaterParamSet::LLWaterParamSet(void) : - mName("Unnamed Preset") -{ - LLSD vec4; - LLSD vec3; - LLSD real(0.0f); - - vec4 = LLSD::emptyArray(); - vec4.append(22.f/255.f); - vec4.append(43.f/255.f); - vec4.append(54.f/255.f); - vec4.append(0.f/255.f); - - vec3 = LLSD::emptyArray(); - vec3.append(2); - vec3.append(2); - vec3.append(2); - - LLSD wave1, wave2; - wave1 = LLSD::emptyArray(); - wave2 = LLSD::emptyArray(); - wave1.append(0.5f); - wave1.append(-.17f); - wave2.append(0.58f); - wave2.append(-.67f); - - mParamValues.insert("waterFogColor", vec4); - mParamValues.insert("waterFogDensity", 16.0f); - mParamValues.insert("underWaterFogMod", 0.25f); - mParamValues.insert("normScale", vec3); - mParamValues.insert("fresnelScale", 0.5f); - mParamValues.insert("fresnelOffset", 0.4f); - mParamValues.insert("scaleAbove", 0.025f); - mParamValues.insert("scaleBelow", 0.2f); - mParamValues.insert("blurMultiplier", 0.01f); - mParamValues.insert("wave1Dir", wave1); - mParamValues.insert("wave2Dir", wave2); - mParamValues.insert("normalMap", DEFAULT_WATER_NORMAL); - -} - -void LLWaterParamSet::set(const std::string& paramName, float x) -{ - // handle case where no array - if(mParamValues[paramName].isReal()) - { - mParamValues[paramName] = x; - } - - // handle array - else if(mParamValues[paramName].isArray() && - mParamValues[paramName][0].isReal()) - { - mParamValues[paramName][0] = x; - } -} - -void LLWaterParamSet::set(const std::string& paramName, float x, float y) { - mParamValues[paramName][0] = x; - mParamValues[paramName][1] = y; -} - -void LLWaterParamSet::set(const std::string& paramName, float x, float y, float z) -{ - mParamValues[paramName][0] = x; - mParamValues[paramName][1] = y; - mParamValues[paramName][2] = z; -} - -void LLWaterParamSet::set(const std::string& paramName, float x, float y, float z, float w) -{ - mParamValues[paramName][0] = x; - mParamValues[paramName][1] = y; - mParamValues[paramName][2] = z; - mParamValues[paramName][3] = w; -} - -void LLWaterParamSet::set(const std::string& paramName, const float * val) -{ - mParamValues[paramName][0] = val[0]; - mParamValues[paramName][1] = val[1]; - mParamValues[paramName][2] = val[2]; - mParamValues[paramName][3] = val[3]; -} - -void LLWaterParamSet::set(const std::string& paramName, const LLVector4 & val) -{ - mParamValues[paramName][0] = val.mV[0]; - mParamValues[paramName][1] = val.mV[1]; - mParamValues[paramName][2] = val.mV[2]; - mParamValues[paramName][3] = val.mV[3]; -} - -void LLWaterParamSet::set(const std::string& paramName, const LLColor4 & val) -{ - mParamValues[paramName][0] = val.mV[0]; - mParamValues[paramName][1] = val.mV[1]; - mParamValues[paramName][2] = val.mV[2]; - mParamValues[paramName][3] = val.mV[3]; -} - -LLVector4 LLWaterParamSet::getVector4(const std::string& paramName, bool& error) -{ - - // test to see if right type - LLSD cur_val = mParamValues.get(paramName); - if (!cur_val.isArray() || cur_val.size() != 4) - { - error = true; - return LLVector4(0,0,0,0); - } - - LLVector4 val; - val.mV[0] = (F32) cur_val[0].asReal(); - val.mV[1] = (F32) cur_val[1].asReal(); - val.mV[2] = (F32) cur_val[2].asReal(); - val.mV[3] = (F32) cur_val[3].asReal(); - - error = false; - return val; -} - -LLVector3 LLWaterParamSet::getVector3(const std::string& paramName, bool& error) -{ - - // test to see if right type - LLSD cur_val = mParamValues.get(paramName); - if (!cur_val.isArray()|| cur_val.size() != 3) - { - error = true; - return LLVector3(0,0,0); - } - - LLVector3 val; - val.mV[0] = (F32) cur_val[0].asReal(); - val.mV[1] = (F32) cur_val[1].asReal(); - val.mV[2] = (F32) cur_val[2].asReal(); - - error = false; - return val; -} - -LLVector2 LLWaterParamSet::getVector2(const std::string& paramName, bool& error) -{ - // test to see if right type - LLSD cur_val = mParamValues.get(paramName); - if (!cur_val.isArray() || cur_val.size() != 2) - { - error = true; - return LLVector2(0,0); - } - - LLVector2 val; - val.mV[0] = (F32) cur_val[0].asReal(); - val.mV[1] = (F32) cur_val[1].asReal(); - - error = false; - return val; -} - -F32 LLWaterParamSet::getFloat(const std::string& paramName, bool& error) -{ - - // test to see if right type - LLSD cur_val = mParamValues.get(paramName); - if (cur_val.isArray() && cur_val.size() != 0) - { - error = false; - return (F32) cur_val[0].asReal(); - } - - if(cur_val.isReal()) - { - error = false; - return (F32) cur_val.asReal(); - } - - error = true; - return 0; -} - -// Added for interpolation effect in DEV-33645 -// Based on LLWLParamSet::mix, but written by Jacob without an intimate knowledge of how WindLight works. -// The function definition existed in the header but was never implemented. If you think there is something -// wrong with this, you're probably right. Ask Jacob, Q, or a member of the original WindLight team. -void LLWaterParamSet::mix(LLWaterParamSet& src, LLWaterParamSet& dest, F32 weight) -{ - // Setup - LLSD srcVal, destVal; // LLSD holders for get/set calls, reusable - - // Iterate through values - for(LLSD::map_iterator iter = mParamValues.beginMap(); iter != mParamValues.endMap(); ++iter) - { - // If param exists in both src and dest, set the holder variables, otherwise skip - if(src.mParamValues.has(iter->first) && dest.mParamValues.has(iter->first)) - { - srcVal = src.mParamValues[iter->first]; - destVal = dest.mParamValues[iter->first]; - } - else - { - continue; - } - - if(iter->second.isReal()) // If it's a real, interpolate directly - { - iter->second = srcVal.asReal() + ((destVal.asReal() - srcVal.asReal()) * weight); - } - else if(iter->second.isArray() && iter->second[0].isReal() // If it's an array of reals, loop through the reals and interpolate on those - && iter->second.size() == srcVal.size() && iter->second.size() == destVal.size()) - { - // Actually do interpolation: old value + (difference in values * factor) - for(int i=0; i < iter->second.size(); ++i) - { - // iter->second[i] = (1.f-weight)*(F32)srcVal[i].asReal() + weight*(F32)destVal[i].asReal(); // old way of doing it -- equivalent but one more operation - iter->second[i] = srcVal[i].asReal() + ((destVal[i].asReal() - srcVal[i].asReal()) * weight); - } - } - else // Else, skip - { - continue; - } - } -} diff --git a/indra/newview/llwaterparamset.h b/indra/newview/llwaterparamset.h deleted file mode 100644 index 368cb0ccba..0000000000 --- a/indra/newview/llwaterparamset.h +++ /dev/null @@ -1,165 +0,0 @@ -/** - * @file llwlparamset.h - * @brief Interface for the LLWaterParamSet class. - * - * $LicenseInfo:firstyear=2005&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, 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_WATER_PARAM_SET_H -#define LL_WATER_PARAM_SET_H - -#include <string> -#include <map> - -#include "v4math.h" -#include "v4color.h" -#include "llviewershadermgr.h" -#include "llstringtable.h" - -class LLWaterParamSet; - -/// A class representing a set of parameter values for the Water shaders. -class LLWaterParamSet -{ - friend class LLWaterParamManager; - -public: - std::string mName; - -private: - - LLSD mParamValues; - std::vector<LLStaticHashedString> mParamHashedNames; - - void updateHashedNames(); - -public: - - LLWaterParamSet(); - - /// Bind this set of parameter values to the uniforms of a particular shader. - void update(LLGLSLShader * shader) const; - - /// set the total llsd - void setAll(const LLSD& val); - - /// get the total llsd - const LLSD& getAll(); - - /// Set a float parameter. - /// \param paramName The name of the parameter to set. - /// \param x The float value to set. - void set(const std::string& paramName, float x); - - /// Set a float2 parameter. - /// \param paramName The name of the parameter to set. - /// \param x The x component's value to set. - /// \param y The y component's value to set. - void set(const std::string& paramName, float x, float y); - - /// Set a float3 parameter. - /// \param paramName The name of the parameter to set. - /// \param x The x component's value to set. - /// \param y The y component's value to set. - /// \param z The z component's value to set. - void set(const std::string& paramName, float x, float y, float z); - - /// Set a float4 parameter. - /// \param paramName The name of the parameter to set. - /// \param x The x component's value to set. - /// \param y The y component's value to set. - /// \param z The z component's value to set. - /// \param w The w component's value to set. - void set(const std::string& paramName, float x, float y, float z, float w); - - /// Set a float4 parameter. - /// \param paramName The name of the parameter to set. - /// \param val An array of the 4 float values to set the parameter to. - void set(const std::string& paramName, const float * val); - - /// Set a float4 parameter. - /// \param paramName The name of the parameter to set. - /// \param val A struct of the 4 float values to set the parameter to. - void set(const std::string& paramName, const LLVector4 & val); - - /// Set a float4 parameter. - /// \param paramName The name of the parameter to set. - /// \param val A struct of the 4 float values to set the parameter to. - void set(const std::string& paramName, const LLColor4 & val); - - /// Get a float4 parameter. - /// \param paramName The name of the parameter to set. - /// \param error A flag to set if it's not the proper return type - LLVector4 getVector4(const std::string& paramName, bool& error); - - /// Get a float3 parameter. - /// \param paramName The name of the parameter to set. - /// \param error A flag to set if it's not the proper return type - LLVector3 getVector3(const std::string& paramName, bool& error); - - /// Get a float2 parameter. - /// \param paramName The name of the parameter to set. - /// \param error A flag to set if it's not the proper return type - LLVector2 getVector2(const std::string& paramName, bool& error); - - /// Get an integer parameter - /// \param paramName The name of the parameter to set. - /// \param error A flag to set if it's not the proper return type - F32 getFloat(const std::string& paramName, bool& error); - - /// interpolate two parameter sets - /// \param src The parameter set to start with - /// \param dest The parameter set to end with - /// \param weight The amount to interpolate - void mix(LLWaterParamSet& src, LLWaterParamSet& dest, - F32 weight); - -}; - -inline void LLWaterParamSet::setAll(const LLSD& val) -{ - if(val.isMap()) { - LLSD::map_const_iterator mIt = val.beginMap(); - for(; mIt != val.endMap(); mIt++) - { - mParamValues[mIt->first] = mIt->second; - } - } - updateHashedNames(); -} - -inline void LLWaterParamSet::updateHashedNames() -{ - mParamHashedNames.clear(); - // Iterate through values - for(LLSD::map_iterator iter = mParamValues.beginMap(); iter != mParamValues.endMap(); ++iter) - { - mParamHashedNames.push_back(LLStaticHashedString(iter->first)); - } -} - -inline const LLSD& LLWaterParamSet::getAll() -{ - return mParamValues; -} - -#endif // LL_WaterPARAM_SET_H diff --git a/indra/newview/llwlanimator.cpp b/indra/newview/llwlanimator.cpp deleted file mode 100644 index c8879e73eb..0000000000 --- a/indra/newview/llwlanimator.cpp +++ /dev/null @@ -1,324 +0,0 @@ -/** - * @file llwlanimator.cpp - * @brief Implementation for the LLWLAnimator class. - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, 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 "llwlanimator.h" -#include "llsky.h" -#include "pipeline.h" -#include "llwlparammanager.h" -#include "llwaterparammanager.h" - -extern LLControlGroup gSavedSettings; - -F64 LLWLAnimator::INTERP_TOTAL_SECONDS = 3.f; - -LLWLAnimator::LLWLAnimator() : mStartTime(0.f), mDayRate(1.f), mDayTime(0.f), - mIsRunning(FALSE), mIsInterpolating(FALSE), mTimeType(TIME_LINDEN), - mInterpStartTime(), mInterpEndTime() -{ - mInterpBeginWL = new LLWLParamSet(); - mInterpBeginWater = new LLWaterParamSet(); - mInterpEndWater = new LLWaterParamSet(); -} - -void LLWLAnimator::update(LLWLParamSet& curParams) -{ - //llassert(mUseLindenTime != mUseLocalTime); - - F64 curTime; - curTime = getDayTime(); - - // don't do anything if empty - if(mTimeTrack.size() == 0) - { - return; - } - - // start it off - mFirstIt = mTimeTrack.begin(); - mSecondIt = mTimeTrack.begin(); - mSecondIt++; - - // grab the two tween iterators - while(mSecondIt != mTimeTrack.end() && curTime > mSecondIt->first) - { - mFirstIt++; - mSecondIt++; - } - - // scroll it around when you get to the end - if(mSecondIt == mTimeTrack.end() || mFirstIt->first > curTime) - { - mSecondIt = mTimeTrack.begin(); - mFirstIt = mTimeTrack.end(); - mFirstIt--; - } - - F32 weight = 0; - - if(mFirstIt->first < mSecondIt->first) - { - - // get the delta time and the proper weight - weight = F32 (curTime - mFirstIt->first) / - (mSecondIt->first - mFirstIt->first); - - // handle the ends - } - else if(mFirstIt->first > mSecondIt->first) - { - - // right edge of time line - if(curTime >= mFirstIt->first) - { - weight = F32 (curTime - mFirstIt->first) / - ((1 + mSecondIt->first) - mFirstIt->first); - // left edge of time line - } - else - { - weight = F32 ((1 + curTime) - mFirstIt->first) / - ((1 + mSecondIt->first) - mFirstIt->first); - } - - // handle same as whatever the last one is - } - else - { - weight = 1; - } - - if(mIsInterpolating) - { - // *TODO_JACOB: this is kind of laggy. Not sure why. The part that lags is the curParams.mix call, and none of the other mixes. It works, though. - clock_t current = clock(); - if(current >= mInterpEndTime) - { - mIsInterpolating = false; - return; - } - - // determine moving target for final interpolation value - // *TODO: this will not work with lazy loading of sky presets. - LLWLParamSet buf = LLWLParamSet(); - buf.setAll(LLWLParamManager::getInstance()->mParamList[mFirstIt->second].getAll()); // just give it some values, otherwise it has no params to begin with (see comment in constructor) - buf.mix(LLWLParamManager::getInstance()->mParamList[mFirstIt->second], LLWLParamManager::getInstance()->mParamList[mSecondIt->second], weight); // mix to determine moving target for interpolation finish (as below) - - // mix from previous value to moving target - weight = (current - mInterpStartTime) / (INTERP_TOTAL_SECONDS * CLOCKS_PER_SEC); - curParams.mix(*mInterpBeginWL, buf, weight); - - // mix water - LLWaterParamManager::getInstance()->mCurParams.mix(*mInterpBeginWater, *mInterpEndWater, weight); - } - else - { - // do the interpolation and set the parameters - // *TODO: this will not work with lazy loading of sky presets. - curParams.mix(LLWLParamManager::getInstance()->mParamList[mFirstIt->second], LLWLParamManager::getInstance()->mParamList[mSecondIt->second], weight); - } -} - -F64 LLWLAnimator::getDayTime() -{ - if(!mIsRunning) - { - return mDayTime; - } - else if(mTimeType == TIME_LINDEN) - { - F32 phase = gSky.getSunPhase() / F_PI; - - // we're not solving the non-linear equation that determines sun phase - // we're just linearly interpolating between the major points - - if (phase <= 5.0 / 4.0) - { - // mDayTime from 0.33 to 0.75 (6:00 to 21:00) - mDayTime = (1.0 / 3.0) * phase + (1.0 / 3.0); - } - else if (phase > 7.0 / 4.0) - { - // maximum value for phase is 2 - // mDayTime from 0.25 to 0.33 (3:00 to 6:00) - mDayTime = (1.0 / 3.0) - (1.0 / 3.0) * (2 - phase); - } - else - { - // phase == 3/2 is where day restarts (24:00) - // mDayTime from 0.75 to 0.999 and 0 to 0.25 (21:00 to 03:00) - mDayTime = phase - (1.0 / 2.0); - - if(mDayTime > 1) - { - mDayTime--; - } - } - - return mDayTime; - } - else if(mTimeType == TIME_LOCAL) - { - return getLocalTime(); - } - - // get the time; - mDayTime = (LLTimer::getElapsedSeconds() - mStartTime) / mDayRate; - - // clamp it - if(mDayTime < 0) - { - mDayTime = 0; - } - while(mDayTime > 1) - { - mDayTime--; - } - - return (F32)mDayTime; -} - -void LLWLAnimator::setDayTime(F64 dayTime) -{ - //retroactively set start time; - mStartTime = LLTimer::getElapsedSeconds() - dayTime * mDayRate; - mDayTime = dayTime; - - // clamp it - if(mDayTime < 0) - { - mDayTime = 0; - } - else if(mDayTime > 1) - { - mDayTime = 1; - } -} - - -void LLWLAnimator::setTrack(std::map<F32, LLWLParamKey>& curTrack, - F32 dayRate, F64 dayTime, bool run) -{ - mTimeTrack = curTrack; - mDayRate = dayRate; - setDayTime(dayTime); - - mIsRunning = run; -} - -void LLWLAnimator::startInterpolation(const LLSD& targetWater) -{ - mInterpBeginWL->setAll(LLWLParamManager::getInstance()->mCurParams.getAll()); - mInterpBeginWater->setAll(LLWaterParamManager::getInstance()->mCurParams.getAll()); - - mInterpStartTime = clock(); - mInterpEndTime = mInterpStartTime + clock_t(INTERP_TOTAL_SECONDS) * CLOCKS_PER_SEC; - - // Don't set any ending WL -- this is continuously calculated as the animator updates since it's a moving target - mInterpEndWater->setAll(targetWater); - - mIsInterpolating = true; -} - -std::string LLWLAnimator::timeToString(F32 curTime) -{ - S32 hours; - S32 min; - bool isPM = false; - - // get hours and minutes - hours = (S32) (24.0 * curTime); - curTime -= ((F32) hours / 24.0f); - min = ll_round(24.0f * 60.0f * curTime); - - // handle case where it's 60 - if(min == 60) - { - hours++; - min = 0; - } - - // set for PM - if(hours >= 12 && hours < 24) - { - isPM = true; - } - - // convert to non-military notation - if(hours >= 24) - { - hours = 12; - } - else if(hours > 12) - { - hours -= 12; - } - else if(hours == 0) - { - hours = 12; - } - - // make the string - std::stringstream newTime; - newTime << hours << ":"; - - // double 0 - if(min < 10) - { - newTime << 0; - } - - // finish it - newTime << min << " "; - if(isPM) - { - newTime << "PM"; - } - else - { - newTime << "AM"; - } - - return newTime.str(); -} - -F64 LLWLAnimator::getLocalTime() -{ - char buffer[9]; - time_t rawtime; - struct tm* timeinfo; - - time(&rawtime); - timeinfo = localtime(&rawtime); - strftime(buffer, 9, "%H:%M:%S", timeinfo); - std::string timeStr(buffer); - - F64 tod = ((F64)atoi(timeStr.substr(0,2).c_str())) / 24.f + - ((F64)atoi(timeStr.substr(3,2).c_str())) / 1440.f + - ((F64)atoi(timeStr.substr(6,2).c_str())) / 86400.f; - return tod; -} diff --git a/indra/newview/llwlanimator.h b/indra/newview/llwlanimator.h deleted file mode 100644 index e2e49c7305..0000000000 --- a/indra/newview/llwlanimator.h +++ /dev/null @@ -1,139 +0,0 @@ -/** - * @file llwlanimator.h - * @brief Interface for the LLWLAnimator class. - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, 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_WL_ANIMATOR_H -#define LL_WL_ANIMATOR_H - -#include "llwlparamset.h" -#include "llenvmanager.h" -#include "llwaterparamset.h" -#include <string> -#include <map> - -class LLWLAnimator { -public: - typedef enum e_time - { - TIME_LINDEN, - TIME_LOCAL, - TIME_CUSTOM - } ETime; - - F64 mStartTime; - F32 mDayRate; - F64 mDayTime; - - // track to play - std::map<F32, LLWLParamKey> mTimeTrack; - std::map<F32, LLWLParamKey>::iterator mFirstIt, mSecondIt; - - // simple constructor - LLWLAnimator(); - - ~LLWLAnimator() - { - delete mInterpBeginWL; - delete mInterpBeginWater; - delete mInterpEndWater; - } - - // update the parameters - void update(LLWLParamSet& curParams); - - // get time in seconds - //F64 getTime(void); - - // returns a float 0 - 1 saying what time of day is it? - F64 getDayTime(void); - - // sets a float 0 - 1 saying what time of day it is - void setDayTime(F64 dayTime); - - // set an animation track - void setTrack(std::map<F32, LLWLParamKey>& track, - F32 dayRate, F64 dayTime = 0, bool run = true); - - void deactivate() - { - mIsRunning = false; - } - - void activate(ETime time) - { - mIsRunning = true; - mTimeType = time; - } - - void startInterpolation(const LLSD& targetWater); - - bool getIsRunning() - { - return mIsRunning; - } - - bool getUseCustomTime() - { - return mTimeType == TIME_CUSTOM; - } - - bool getUseLocalTime() - { - return mTimeType == TIME_LOCAL; - } - - bool getUseLindenTime() - { - return mTimeType == TIME_LINDEN; - } - - void setTimeType(ETime time) - { - mTimeType = time; - } - - ETime getTimeType() - { - return mTimeType; - } - - /// convert the present time to a digital clock time - static std::string timeToString(F32 curTime); - - /// get local time between 0 and 1 - static F64 getLocalTime(); - -private: - ETime mTimeType; - bool mIsRunning, mIsInterpolating; - LLWLParamSet *mInterpBeginWL; - LLWaterParamSet *mInterpBeginWater, *mInterpEndWater; - clock_t mInterpStartTime, mInterpEndTime; - - static F64 INTERP_TOTAL_SECONDS; -}; - -#endif // LL_WL_ANIMATOR_H - diff --git a/indra/newview/llwldaycycle.cpp b/indra/newview/llwldaycycle.cpp index 106f17f61b..0a331d1823 100644 --- a/indra/newview/llwldaycycle.cpp +++ b/indra/newview/llwldaycycle.cpp @@ -46,6 +46,7 @@ LLWLDayCycle::~LLWLDayCycle() void LLWLDayCycle::loadDayCycle(const LLSD& day_data, LLWLParamKey::EScope scope) { +#if 0 LL_DEBUGS() << "Loading day cycle (day_data.size() = " << day_data.size() << ", scope = " << scope << ")" << LL_ENDL; mTimeMap.clear(); @@ -88,6 +89,7 @@ void LLWLDayCycle::loadDayCycle(const LLSD& day_data, LLWLParamKey::EScope scope // then add the keyframe addKeyframe((F32)day_data[i][0].asReal(), frame); } +#endif } void LLWLDayCycle::loadDayCycleFromFile(const std::string & fileName) @@ -158,35 +160,35 @@ LLSD LLWLDayCycle::asLLSD() return day_data; } -bool LLWLDayCycle::getSkyRefs(std::map<LLWLParamKey, LLWLParamSet>& refs) const -{ - bool result = true; - LLWLParamManager& wl_mgr = LLWLParamManager::instance(); - - refs.clear(); - for (std::map<F32, LLWLParamKey>::const_iterator iter = mTimeMap.begin(); iter != mTimeMap.end(); ++iter) - { - const LLWLParamKey& key = iter->second; - if (!wl_mgr.getParamSet(key, refs[key])) - { - LL_WARNS() << "Cannot find sky [" << key.name << "] referenced by a day cycle" << LL_ENDL; - result = false; - } - } - - return result; -} +// bool LLWLDayCycle::getSkyRefs(std::map<LLWLParamKey, LLWLParamSet>& refs) const +// { +// bool result = true; +// LLWLParamManager& wl_mgr = LLWLParamManager::instance(); +// +// refs.clear(); +// for (std::map<F32, LLWLParamKey>::const_iterator iter = mTimeMap.begin(); iter != mTimeMap.end(); ++iter) +// { +// const LLWLParamKey& key = iter->second; +// if (!wl_mgr.getParamSet(key, refs[key])) +// { +// LL_WARNS() << "Cannot find sky [" << key.name << "] referenced by a day cycle" << LL_ENDL; +// result = false; +// } +// } +// +// return result; +// } bool LLWLDayCycle::getSkyMap(LLSD& sky_map) const { - std::map<LLWLParamKey, LLWLParamSet> refs; - - if (!getSkyRefs(refs)) - { - return false; - } - - sky_map = LLWLParamManager::createSkyMap(refs); +// std::map<LLWLParamKey, LLWLParamSet> refs; +// +// if (!getSkyRefs(refs)) +// { +// return false; +// } +// +// sky_map = LLWLParamManager::createSkyMap(refs); return true; } @@ -235,23 +237,23 @@ bool LLWLDayCycle::changeKeyframeTime(F32 oldTime, F32 newTime) return addKeyframe(newTime, frame); } -bool LLWLDayCycle::changeKeyframeParam(F32 time, LLWLParamKey key) -{ - LL_DEBUGS() << "Changing key frame param (" << time << ", " << key.toLLSD() << ")" << LL_ENDL; - - // just remove and add back - // make sure param exists - LLWLParamSet tmp; - bool stat = LLWLParamManager::getInstance()->getParamSet(key, tmp); - if(stat == false) - { - LL_DEBUGS() << "Failed to change key frame param (" << time << ", " << key.toLLSD() << ")" << LL_ENDL; - return stat; - } - - mTimeMap[time] = key; - return true; -} +// bool LLWLDayCycle::changeKeyframeParam(F32 time, LLWLParamKey key) +// { +// LL_DEBUGS() << "Changing key frame param (" << time << ", " << key.toLLSD() << ")" << LL_ENDL; +// +// // just remove and add back +// // make sure param exists +// LLWLParamSet tmp; +// bool stat = LLWLParamManager::getInstance()->getParamSet(key, tmp); +// if(stat == false) +// { +// LL_DEBUGS() << "Failed to change key frame param (" << time << ", " << key.toLLSD() << ")" << LL_ENDL; +// return stat; +// } +// +// mTimeMap[time] = key; +// return true; +// } bool LLWLDayCycle::removeKeyframe(F32 time) @@ -285,19 +287,19 @@ bool LLWLDayCycle::getKeytime(LLWLParamKey frame, F32& key_time) const return false; } -bool LLWLDayCycle::getKeyedParam(F32 time, LLWLParamSet& param) -{ - // just scroll on through till you find it - std::map<F32, LLWLParamKey>::iterator mIt = mTimeMap.find(time); - if(mIt != mTimeMap.end()) - { - return LLWLParamManager::getInstance()->getParamSet(mIt->second, param); - } - - // return error if not found - LL_DEBUGS() << "Key " << time << " not found" << LL_ENDL; - return false; -} +// bool LLWLDayCycle::getKeyedParam(F32 time, LLWLParamSet& param) +// { +// // just scroll on through till you find it +// std::map<F32, LLWLParamKey>::iterator mIt = mTimeMap.find(time); +// if(mIt != mTimeMap.end()) +// { +// return LLWLParamManager::getInstance()->getParamSet(mIt->second, param); +// } +// +// // return error if not found +// LL_DEBUGS() << "Key " << time << " not found" << LL_ENDL; +// return false; +// } bool LLWLDayCycle::getKeyedParamName(F32 time, std::string & name) { diff --git a/indra/newview/llwldaycycle.h b/indra/newview/llwldaycycle.h index c8585564ed..2f9a2e5c4a 100644 --- a/indra/newview/llwldaycycle.h +++ b/indra/newview/llwldaycycle.h @@ -32,10 +32,8 @@ class LLWLDayCycle; #include <vector> #include <map> #include <string> -#include "llwlparamset.h" -#include "llwlanimator.h" +#include "llenvmanager.h" struct LLWLParamKey; -#include "llenvmanager.h" // for LLEnvKey::EScope class LLWLDayCycle { @@ -78,7 +76,7 @@ public: LLSD asLLSD(); // get skies referenced by this day cycle - bool getSkyRefs(std::map<LLWLParamKey, LLWLParamSet>& refs) const; +// bool getSkyRefs(std::map<LLWLParamKey, LLWLParamSet>& refs) const; // get referenced skies as LLSD bool getSkyMap(LLSD& sky_map) const; @@ -110,7 +108,7 @@ public: /// get the param set at a given time /// returns true if found one - bool getKeyedParam(F32 time, LLWLParamSet& param); +// bool getKeyedParam(F32 time, LLWLParamSet& param); /// get the name /// returns true if it found one diff --git a/indra/newview/llwlhandlers.cpp b/indra/newview/llwlhandlers.cpp index ea65a0c6d9..6aa379e0de 100644 --- a/indra/newview/llwlhandlers.cpp +++ b/indra/newview/llwlhandlers.cpp @@ -30,10 +30,11 @@ #include "llagent.h" #include "llviewerregion.h" -#include "llenvmanager.h" #include "llnotificationsutil.h" #include "llcorehttputil.h" +#include "llenvironment.h" + /**** * LLEnvironmentRequest ****/ @@ -51,7 +52,7 @@ bool LLEnvironmentRequest::initiate() if (!cur_region->capabilitiesReceived()) { LL_INFOS("WindlightCaps") << "Deferring windlight settings request until we've got region caps" << LL_ENDL; - cur_region->setCapabilitiesReceivedCallback(boost::bind(&LLEnvironmentRequest::onRegionCapsReceived, _1)); + cur_region->setCapabilitiesReceivedCallback([](LLUUID region_id) { LLEnvironmentRequest::onRegionCapsReceived(region_id); }); return false; } @@ -84,7 +85,7 @@ bool LLEnvironmentRequest::doRequest() std::string coroname = LLCoros::instance().launch("LLEnvironmentRequest::environmentRequestCoro", - boost::bind(&LLEnvironmentRequest::environmentRequestCoro, url)); + [url]() { LLEnvironmentRequest::environmentRequestCoro(url); }); LL_INFOS("WindlightCaps") << "Requesting region windlight settings via " << url << LL_ENDL; return true; @@ -103,6 +104,8 @@ void LLEnvironmentRequest::environmentRequestCoro(std::string url) LLSD result = httpAdapter->getAndSuspend(httpRequest, url); + LL_WARNS("WindlightCaps") << "Using legacy Windlight caps." << LL_ENDL; + if (requestId != LLEnvironmentRequest::sLastRequest) { LL_INFOS("WindlightCaps") << "Got superseded by another responder; ignoring..." << LL_ENDL; @@ -114,11 +117,12 @@ void LLEnvironmentRequest::environmentRequestCoro(std::string url) if (!status) { LL_WARNS("WindlightCaps") << "Got an error, not using region windlight... " << LL_ENDL; - LLEnvManagerNew::getInstance()->onRegionSettingsResponse(LLSD()); + LLEnvironment::instance().onLegacyRegionSettings(LLSD()); + return; } result = result["content"]; - LL_INFOS("WindlightCaps") << "Received region windlight settings" << LL_ENDL; + LL_INFOS("WindlightCaps") << "Received region legacy windlight settings" << LL_ENDL; LLUUID regionId; if (gAgent.getRegion()) @@ -134,7 +138,7 @@ void LLEnvironmentRequest::environmentRequestCoro(std::string url) return; } - LLEnvManagerNew::getInstance()->onRegionSettingsResponse(result); + LLEnvironment::instance().onLegacyRegionSettings(result); } @@ -162,7 +166,7 @@ bool LLEnvironmentApply::initiateRequest(const LLSD& content) sLastUpdate = current; // Send update request. - std::string url = gAgent.getRegionCapability("EnvironmentSettings"); + std::string url = gAgent.getRegionCapability("ExtEnvironment"); if (url.empty()) { LL_WARNS("WindlightCaps") << "Applying windlight settings not supported" << LL_ENDL; @@ -174,7 +178,7 @@ bool LLEnvironmentApply::initiateRequest(const LLSD& content) std::string coroname = LLCoros::instance().launch("LLEnvironmentApply::environmentApplyCoro", - boost::bind(&LLEnvironmentApply::environmentApplyCoro, url, content)); + [url, content]() { LLEnvironmentApply::environmentApplyCoro(url, content); }); return true; } @@ -242,13 +246,11 @@ void LLEnvironmentApply::environmentApplyCoro(std::string url, LLSD content) } LL_DEBUGS("WindlightCaps") << "Success in applying windlight settings to region " << result["regionID"].asUUID() << LL_ENDL; - LLEnvManagerNew::instance().onRegionSettingsApplyResponse(true); } while (false); if (!notify.isUndefined()) { LLNotificationsUtil::add("WLRegionApplyFail", notify); - LLEnvManagerNew::instance().onRegionSettingsApplyResponse(false); } } diff --git a/indra/newview/llwlhandlers.h b/indra/newview/llwlhandlers.h index eb2bbf9553..857ffa9bd3 100644 --- a/indra/newview/llwlhandlers.h +++ b/indra/newview/llwlhandlers.h @@ -60,4 +60,6 @@ private: static void environmentApplyCoro(std::string url, LLSD content); }; + + #endif // LL_LLWLHANDLERS_H diff --git a/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp deleted file mode 100644 index 4b4393b07b..0000000000 --- a/indra/newview/llwlparammanager.cpp +++ /dev/null @@ -1,710 +0,0 @@ -/** - * @file llwlparammanager.cpp - * @brief Implementation for the LLWLParamManager class. - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, 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 "llwlparammanager.h" - -#include "pipeline.h" -#include "llsky.h" - -#include "lldiriterator.h" -#include "llfloaterreg.h" -#include "llsliderctrl.h" -#include "llspinctrl.h" -#include "llcheckboxctrl.h" -#include "lluictrlfactory.h" -#include "llviewercamera.h" -#include "llcombobox.h" -#include "lllineeditor.h" -#include "llsdserialize.h" - -#include "v4math.h" -#include "llviewerdisplay.h" -#include "llviewercontrol.h" -#include "llviewerwindow.h" -#include "lldrawpoolwater.h" -#include "llagent.h" -#include "llviewerregion.h" - -#include "llwlparamset.h" -#include "llpostprocess.h" - -#include "llviewershadermgr.h" -#include "llglslshader.h" - -#include "curl/curl.h" -#include "llstreamtools.h" - -LLWLParamManager::LLWLParamManager() : - - //set the defaults for the controls - - /// Sun Delta Terrain tweak variables. - mSunDeltaYaw(180.0f), - mSceneLightStrength(2.0f), - mWLGamma(1.0f, "gamma"), - - mBlueHorizon(0.25f, 0.25f, 1.0f, 1.0f, "blue_horizon", "WLBlueHorizon"), - mHazeDensity(1.0f, "haze_density"), - mBlueDensity(0.25f, 0.25f, 0.25f, 1.0f, "blue_density", "WLBlueDensity"), - mDensityMult(1.0f, "density_multiplier", 1000), - mHazeHorizon(1.0f, "haze_horizon"), - mMaxAlt(4000.0f, "max_y"), - - // Lighting - mLightnorm(0.f, 0.707f, -0.707f, 1.f, "lightnorm"), - mSunlight(0.5f, 0.5f, 0.5f, 1.0f, "sunlight_color", "WLSunlight"), - mAmbient(0.5f, 0.75f, 1.0f, 1.19f, "ambient", "WLAmbient"), - mGlow(18.0f, 0.0f, -0.01f, 1.0f, "glow"), - - // Clouds - mCloudColor(0.5f, 0.5f, 0.5f, 1.0f, "cloud_color", "WLCloudColor"), - mCloudMain(0.5f, 0.5f, 0.125f, 1.0f, "cloud_pos_density1"), - mCloudCoverage(0.0f, "cloud_shadow"), - mCloudDetail(0.0f, 0.0f, 0.0f, 1.0f, "cloud_pos_density2"), - mDistanceMult(1.0f, "distance_multiplier"), - mCloudScale(0.42f, "cloud_scale"), - - // sky dome - mDomeOffset(0.96f), - mDomeRadius(15000.f) -{ -} - -LLWLParamManager::~LLWLParamManager() -{ -} - -void LLWLParamManager::clearParamSetsOfScope(LLWLParamKey::EScope scope) -{ - if (LLWLParamKey::SCOPE_LOCAL == scope) - { - LL_WARNS("Windlight") << "Tried to clear windlight sky presets from local system! This shouldn't be called..." << LL_ENDL; - return; - } - - std::set<LLWLParamKey> to_remove; - for(std::map<LLWLParamKey, LLWLParamSet>::iterator iter = mParamList.begin(); iter != mParamList.end(); ++iter) - { - if(iter->first.scope == scope) - { - to_remove.insert(iter->first); - } - } - - for(std::set<LLWLParamKey>::iterator iter = to_remove.begin(); iter != to_remove.end(); ++iter) - { - mParamList.erase(*iter); - } -} - -// returns all skies referenced by the day cycle, with their final names -// side effect: applies changes to all internal structures! -std::map<LLWLParamKey, LLWLParamSet> LLWLParamManager::finalizeFromDayCycle(LLWLParamKey::EScope scope) -{ - LL_DEBUGS() << "mDay before finalizing:" << LL_ENDL; - { - for (std::map<F32, LLWLParamKey>::iterator iter = mDay.mTimeMap.begin(); iter != mDay.mTimeMap.end(); ++iter) - { - LLWLParamKey& key = iter->second; - LL_DEBUGS() << iter->first << "->" << key.name << LL_ENDL; - } - } - - std::map<LLWLParamKey, LLWLParamSet> final_references; - - // Move all referenced to desired scope, renaming if necessary - // First, save skies referenced - std::map<LLWLParamKey, LLWLParamSet> current_references; // all skies referenced by the day cycle, with their current names - // guard against skies with same name and different scopes - std::set<std::string> inserted_names; - std::map<std::string, unsigned int> conflicted_names; // integer later used as a count, for uniquely renaming conflicts - - LLWLDayCycle& cycle = mDay; - for(std::map<F32, LLWLParamKey>::iterator iter = cycle.mTimeMap.begin(); - iter != cycle.mTimeMap.end(); - ++iter) - { - LLWLParamKey& key = iter->second; - std::string desired_name = key.name; - replace_newlines_with_whitespace(desired_name); // already shouldn't have newlines, but just in case - if(inserted_names.find(desired_name) == inserted_names.end()) - { - inserted_names.insert(desired_name); - } - else - { - // make exist in map - conflicted_names[desired_name] = 0; - } - current_references[key] = mParamList[key]; - } - - // forget all old skies in target scope, and rebuild, renaming as needed - clearParamSetsOfScope(scope); - for(std::map<LLWLParamKey, LLWLParamSet>::iterator iter = current_references.begin(); iter != current_references.end(); ++iter) - { - const LLWLParamKey& old_key = iter->first; - - std::string desired_name(old_key.name); - replace_newlines_with_whitespace(desired_name); - - LLWLParamKey new_key(desired_name, scope); // name will be replaced later if necessary - - // if this sky is one with a non-unique name, rename via appending a number - // an existing preset of the target scope gets to keep its name - if (scope != old_key.scope && conflicted_names.find(desired_name) != conflicted_names.end()) - { - std::string& new_name = new_key.name; - - do - { - // if this executes more than once, this is an absurdly pathological case - // (e.g. "x" repeated twice, but "x 1" already exists, so need to use "x 2") - std::stringstream temp; - temp << desired_name << " " << (++conflicted_names[desired_name]); - new_name = temp.str(); - } while (inserted_names.find(new_name) != inserted_names.end()); - - // yay, found one that works - inserted_names.insert(new_name); // track names we consume here; shouldn't be necessary due to ++int? but just in case - - // *TODO factor out below into a rename()? - - LL_INFOS("Windlight") << "Renamed " << old_key.name << " (scope" << old_key.scope << ") to " - << new_key.name << " (scope " << new_key.scope << ")" << LL_ENDL; - - // update name in sky - iter->second.mName = new_name; - - // update keys in day cycle - for(std::map<F32, LLWLParamKey>::iterator frame = cycle.mTimeMap.begin(); frame != cycle.mTimeMap.end(); ++frame) - { - if (frame->second == old_key) - { - frame->second = new_key; - } - } - - // add to master sky map - mParamList[new_key] = iter->second; - } - - final_references[new_key] = iter->second; - } - - LL_DEBUGS() << "mDay after finalizing:" << LL_ENDL; - { - for (std::map<F32, LLWLParamKey>::iterator iter = mDay.mTimeMap.begin(); iter != mDay.mTimeMap.end(); ++iter) - { - LLWLParamKey& key = iter->second; - LL_DEBUGS() << iter->first << "->" << key.name << LL_ENDL; - } - } - - return final_references; -} - -// static -LLSD LLWLParamManager::createSkyMap(std::map<LLWLParamKey, LLWLParamSet> refs) -{ - LLSD skies = LLSD::emptyMap(); - for(std::map<LLWLParamKey, LLWLParamSet>::iterator iter = refs.begin(); iter != refs.end(); ++iter) - { - skies.insert(iter->first.name, iter->second.getAll()); - } - return skies; -} - -void LLWLParamManager::addAllSkies(const LLWLParamKey::EScope scope, const LLSD& sky_presets) -{ - for(LLSD::map_const_iterator iter = sky_presets.beginMap(); iter != sky_presets.endMap(); ++iter) - { - LLWLParamSet set; - set.setAll(iter->second); - mParamList[LLWLParamKey(iter->first, scope)] = set; - } -} - -void LLWLParamManager::refreshRegionPresets(const LLSD& region_sky_presets) -{ - // Remove all region sky presets because they may belong to a previously visited region. - clearParamSetsOfScope(LLEnvKey::SCOPE_REGION); - - // Add all sky presets belonging to the current region. - addAllSkies(LLEnvKey::SCOPE_REGION, region_sky_presets); -} - -void LLWLParamManager::loadAllPresets() -{ - // First, load system (coming out of the box) sky presets. - loadPresetsFromDir(getSysDir()); - - // Then load user presets. Note that user day presets will modify any system ones already loaded. - loadPresetsFromDir(getUserDir()); -} - -void LLWLParamManager::loadPresetsFromDir(const std::string& dir) -{ - LL_INFOS("AppInit", "Shaders") << "Loading sky presets from " << dir << LL_ENDL; - - LLDirIterator dir_iter(dir, "*.xml"); - while (1) - { - std::string file; - if (!dir_iter.next(file)) - { - break; // no more files - } - - std::string path = gDirUtilp->add(dir, file); - if (!loadPreset(path)) - { - LL_WARNS() << "Error loading sky preset from " << path << LL_ENDL; - } - } -} - -bool LLWLParamManager::loadPreset(const std::string& path) -{ - llifstream xml_file; - std::string name(gDirUtilp->getBaseFileName(LLURI::unescape(path), /*strip_exten = */ true)); - - xml_file.open(path.c_str()); - if (!xml_file) - { - return false; - } - - LL_DEBUGS("AppInit", "Shaders") << "Loading sky " << name << LL_ENDL; - - LLSD params_data; - LLPointer<LLSDParser> parser = new LLSDXMLParser(); - parser->parse(xml_file, params_data, LLSDSerialize::SIZE_UNLIMITED); - xml_file.close(); - - LLWLParamKey key(name, LLEnvKey::SCOPE_LOCAL); - if (hasParamSet(key)) - { - setParamSet(key, params_data); - } - else - { - addParamSet(key, params_data); - } - - return true; -} - -void LLWLParamManager::savePreset(LLWLParamKey key) -{ - llassert(key.scope == LLEnvKey::SCOPE_LOCAL && !key.name.empty()); - - // make an empty llsd - LLSD paramsData(LLSD::emptyMap()); - std::string pathName(getUserDir() + escapeString(key.name) + ".xml"); - - // fill it with LLSD windlight params - paramsData = mParamList[key].getAll(); - - // write to file - llofstream presetsXML(pathName.c_str()); - LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter(); - formatter->format(paramsData, presetsXML, LLSDFormatter::OPTIONS_PRETTY); - presetsXML.close(); - - propagateParameters(); -} - -void LLWLParamManager::updateShaderUniforms(LLGLSLShader * shader) -{ - if (gPipeline.canUseWindLightShaders()) - { - mCurParams.update(shader); - } - - if (shader->mShaderGroup == LLGLSLShader::SG_DEFAULT) - { - shader->uniform4fv(LLShaderMgr::LIGHTNORM, 1, mRotatedLightDir.mV); - shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV); - } - - else if (shader->mShaderGroup == LLGLSLShader::SG_SKY) - { - shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, mClampedLightDir.mV); - } - - shader->uniform1f(LLShaderMgr::SCENE_LIGHT_STRENGTH, mSceneLightStrength); - -} - -static LLTrace::BlockTimerStatHandle FTM_UPDATE_WLPARAM("Update Windlight Params"); - -void LLWLParamManager::propagateParameters(void) -{ - LL_RECORD_BLOCK_TIME(FTM_UPDATE_WLPARAM); - - LLVector4 sunDir; - LLVector4 moonDir; - - // set the sun direction from SunAngle and EastAngle - F32 sinTheta = sin(mCurParams.getEastAngle()); - F32 cosTheta = cos(mCurParams.getEastAngle()); - - F32 sinPhi = sin(mCurParams.getSunAngle()); - F32 cosPhi = cos(mCurParams.getSunAngle()); - - sunDir.mV[0] = -sinTheta * cosPhi; - sunDir.mV[1] = sinPhi; - sunDir.mV[2] = cosTheta * cosPhi; - sunDir.mV[3] = 0; - - moonDir = -sunDir; - - // is the normal from the sun or the moon - if(sunDir.mV[1] >= 0) - { - mLightDir = sunDir; - } - else if(sunDir.mV[1] < 0 && sunDir.mV[1] > LLSky::NIGHTTIME_ELEVATION_COS) - { - // clamp v1 to 0 so sun never points up and causes weirdness on some machines - LLVector3 vec(sunDir.mV[0], sunDir.mV[1], sunDir.mV[2]); - vec.mV[1] = 0; - vec.normVec(); - mLightDir = LLVector4(vec, 0.f); - } - else - { - mLightDir = moonDir; - } - - // calculate the clamp lightnorm for sky (to prevent ugly banding in sky - // when haze goes below the horizon - mClampedLightDir = sunDir; - - if (mClampedLightDir.mV[1] < -0.1f) - { - mClampedLightDir.mV[1] = -0.1f; - } - - mCurParams.set("lightnorm", mLightDir); - - // bind the variables for all shaders only if we're using WindLight - LLViewerShaderMgr::shader_iter shaders_iter, end_shaders; - end_shaders = LLViewerShaderMgr::instance()->endShaders(); - for(shaders_iter = LLViewerShaderMgr::instance()->beginShaders(); shaders_iter != end_shaders; ++shaders_iter) - { - if (shaders_iter->mProgramObject != 0 - && (gPipeline.canUseWindLightShaders() - || shaders_iter->mShaderGroup == LLGLSLShader::SG_WATER)) - { - shaders_iter->mUniformsDirty = TRUE; - } - } - - // get the cfr version of the sun's direction - LLVector3 cfrSunDir(sunDir.mV[2], sunDir.mV[0], sunDir.mV[1]); - - // set direction and don't allow overriding - gSky.setSunDirection(cfrSunDir, LLVector3(0,0,0)); - gSky.setOverrideSun(TRUE); -} - -void LLWLParamManager::update(LLViewerCamera * cam) -{ - LL_RECORD_BLOCK_TIME(FTM_UPDATE_WLPARAM); - - // update clouds, sun, and general - mCurParams.updateCloudScrolling(); - - // update only if running - if(mAnimator.getIsRunning()) - { - mAnimator.update(mCurParams); - } - - // update the shaders and the menu - propagateParameters(); - - F32 camYaw = cam->getYaw(); - - stop_glerror(); - - // *TODO: potential optimization - this block may only need to be - // executed some of the time. For example for water shaders only. - { - F32 camYawDelta = mSunDeltaYaw * DEG_TO_RAD; - - LLVector3 lightNorm3(mLightDir); - lightNorm3 *= LLQuaternion(-(camYaw + camYawDelta), LLVector3(0.f, 1.f, 0.f)); - mRotatedLightDir = LLVector4(lightNorm3, 0.f); - - LLViewerShaderMgr::shader_iter shaders_iter, end_shaders; - end_shaders = LLViewerShaderMgr::instance()->endShaders(); - for(shaders_iter = LLViewerShaderMgr::instance()->beginShaders(); shaders_iter != end_shaders; ++shaders_iter) - { - if (shaders_iter->mProgramObject != 0 - && (gPipeline.canUseWindLightShaders() - || shaders_iter->mShaderGroup == LLGLSLShader::SG_WATER)) - { - shaders_iter->mUniformsDirty = TRUE; - } - } - } -} - -bool LLWLParamManager::applyDayCycleParams(const LLSD& params, LLEnvKey::EScope scope, F32 time) -{ - mDay.loadDayCycle(params, scope); - resetAnimator(time, true); // set to specified time and start animator - return true; -} - -void LLWLParamManager::setDefaultDay() -{ - mDay.loadDayCycleFromFile("Default.xml"); -} - -bool LLWLParamManager::applySkyParams(const LLSD& params) -{ - mAnimator.deactivate(); - mCurParams.setAll(params); - return true; -} - -void LLWLParamManager::setDefaultSky() -{ - getParamSet(LLWLParamKey("Default", LLWLParamKey::SCOPE_LOCAL), mCurParams); -} - - -void LLWLParamManager::resetAnimator(F32 curTime, bool run) -{ - mAnimator.setTrack(mDay.mTimeMap, mDay.mDayRate, - curTime, run); - - return; -} - -bool LLWLParamManager::addParamSet(const LLWLParamKey& key, LLWLParamSet& param) -{ - // add a new one if not one there already - std::map<LLWLParamKey, LLWLParamSet>::iterator mIt = mParamList.find(key); - if(mIt == mParamList.end()) - { - llassert(!key.name.empty()); - // *TODO: validate params - mParamList[key] = param; - mPresetListChangeSignal(); - return true; - } - - return false; -} - -BOOL LLWLParamManager::addParamSet(const LLWLParamKey& key, LLSD const & param) -{ - LLWLParamSet param_set; - param_set.setAll(param); - return addParamSet(key, param_set); -} - -bool LLWLParamManager::getParamSet(const LLWLParamKey& key, LLWLParamSet& param) -{ - // find it and set it - std::map<LLWLParamKey, LLWLParamSet>::iterator mIt = mParamList.find(key); - if(mIt != mParamList.end()) - { - param = mParamList[key]; - param.mName = key.name; - return true; - } - - return false; -} - -bool LLWLParamManager::hasParamSet(const LLWLParamKey& key) -{ - LLWLParamSet dummy; - return getParamSet(key, dummy); -} - -bool LLWLParamManager::setParamSet(const LLWLParamKey& key, LLWLParamSet& param) -{ - llassert(!key.name.empty()); - // *TODO: validate params - mParamList[key] = param; - - return true; -} - -bool LLWLParamManager::setParamSet(const LLWLParamKey& key, const LLSD & param) -{ - llassert(!key.name.empty()); - // *TODO: validate params - - // quick, non robust (we won't be working with files, but assets) check - // this might not actually be true anymore.... - if(!param.isMap()) - { - return false; - } - - LLWLParamSet param_set; - param_set.setAll(param); - return setParamSet(key, param_set); -} - -void LLWLParamManager::removeParamSet(const LLWLParamKey& key, bool delete_from_disk) -{ - // *NOTE: Removing a sky preset invalidates day cycles that refer to it. - - if (key.scope == LLEnvKey::SCOPE_REGION) - { - LL_WARNS() << "Removing region skies not supported" << LL_ENDL; - llassert(key.scope == LLEnvKey::SCOPE_LOCAL); - return; - } - - // remove from param list - std::map<LLWLParamKey, LLWLParamSet>::iterator it = mParamList.find(key); - if (it == mParamList.end()) - { - LL_WARNS("WindLight") << "No sky preset named " << key.name << LL_ENDL; - return; - } - - mParamList.erase(it); - mDay.removeReferencesTo(key); - - // remove from file system if requested - if (delete_from_disk) - { - std::string path_name(getUserDir()); - std::string escaped_name = escapeString(key.name); - - if(gDirUtilp->deleteFilesInDir(path_name, escaped_name + ".xml") < 1) - { - LL_WARNS("WindLight") << "Error removing sky preset " << key.name << " from disk" << LL_ENDL; - } - } - - // signal interested parties - mPresetListChangeSignal(); -} - -bool LLWLParamManager::isSystemPreset(const std::string& preset_name) const -{ - // *TODO: file system access is excessive here. - return gDirUtilp->fileExists(getSysDir() + escapeString(preset_name) + ".xml"); -} - -void LLWLParamManager::getPresetNames(preset_name_list_t& region, preset_name_list_t& user, preset_name_list_t& sys) const -{ - region.clear(); - user.clear(); - sys.clear(); - - for (std::map<LLWLParamKey, LLWLParamSet>::const_iterator it = mParamList.begin(); it != mParamList.end(); it++) - { - const LLWLParamKey& key = it->first; - const std::string& name = key.name; - - if (key.scope == LLEnvKey::SCOPE_REGION) - { - region.push_back(name); - } - else - { - if (isSystemPreset(name)) - { - sys.push_back(name); - } - else - { - user.push_back(name); - } - } - } -} - -void LLWLParamManager::getUserPresetNames(preset_name_list_t& user) const -{ - preset_name_list_t region, sys; // unused - getPresetNames(region, user, sys); -} - -void LLWLParamManager::getPresetKeys(preset_key_list_t& keys) const -{ - keys.clear(); - - for (std::map<LLWLParamKey, LLWLParamSet>::const_iterator it = mParamList.begin(); it != mParamList.end(); it++) - { - keys.push_back(it->first); - } -} - -boost::signals2::connection LLWLParamManager::setPresetListChangeCallback(const preset_list_signal_t::slot_type& cb) -{ - return mPresetListChangeSignal.connect(cb); -} - -// virtual static -void LLWLParamManager::initSingleton() -{ - LL_DEBUGS("Windlight") << "Initializing sky" << LL_ENDL; - - loadAllPresets(); - - // but use linden time sets it to what the estate is - mAnimator.setTimeType(LLWLAnimator::TIME_LINDEN); -} - -// static -std::string LLWLParamManager::getSysDir() -{ - return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", ""); -} - -// static -std::string LLWLParamManager::getUserDir() -{ - return gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS , "windlight/skies", ""); -} - -// static -std::string LLWLParamManager::escapeString(const std::string& str) -{ - // Don't use LLURI::escape() because it doesn't encode '-' characters - // which may break handling of some system presets like "A-12AM". - char* curl_str = curl_escape(str.c_str(), str.size()); - std::string escaped_str(curl_str); - curl_free(curl_str); - - return escaped_str; -} diff --git a/indra/newview/llwlparammanager.h b/indra/newview/llwlparammanager.h deleted file mode 100644 index 61f86b747f..0000000000 --- a/indra/newview/llwlparammanager.h +++ /dev/null @@ -1,323 +0,0 @@ -/** - * @file llwlparammanager.h - * @brief Implementation for the LLWLParamManager class. - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, 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_WLPARAMMANAGER_H -#define LL_WLPARAMMANAGER_H - -#include <list> -#include <map> -#include "llwlparamset.h" -#include "llwlanimator.h" -#include "llwldaycycle.h" -#include "llviewercamera.h" -#include "lltrans.h" - -class LLGLSLShader; - -// color control -struct WLColorControl { - - F32 r, g, b, i; /// the values - std::string mName; /// name to use to dereference params - std::string mSliderName; /// name of the slider in menu - bool hasSliderName; /// only set slider name for true color types - bool isSunOrAmbientColor; /// flag for if it's the sun or ambient color controller - bool isBlueHorizonOrDensity; /// flag for if it's the Blue Horizon or Density color controller - - inline WLColorControl(F32 red, F32 green, F32 blue, F32 intensity, - const std::string& n, const std::string& sliderName = LLStringUtil::null) - : r(red), g(green), b(blue), i(intensity), mName(n), mSliderName(sliderName) - { - // if there's a slider name, say we have one - hasSliderName = false; - if (mSliderName != "") { - hasSliderName = true; - } - - // if it's the sun controller - isSunOrAmbientColor = false; - if (mSliderName == "WLSunlight" || mSliderName == "WLAmbient") { - isSunOrAmbientColor = true; - } - - isBlueHorizonOrDensity = false; - if (mSliderName == "WLBlueHorizon" || mSliderName == "WLBlueDensity") { - isBlueHorizonOrDensity = true; - } - } - - inline WLColorControl & operator = (LLVector4 const & val) { - r = val.mV[0]; - g = val.mV[1]; - b = val.mV[2]; - i = val.mV[3]; - return *this; - } - - inline operator LLVector4 (void) const { - return LLVector4(r, g, b, i); - } - - inline operator LLVector3 (void) const { - return LLVector3(r, g, b); - } - - inline void update(LLWLParamSet & params) const { - params.set(mName, r, g, b, i); - } -}; - -// float slider control -struct WLFloatControl { - F32 x; - std::string mName; - F32 mult; - - inline WLFloatControl(F32 val, const std::string& n, F32 m=1.0f) - : x(val), mName(n), mult(m) - { - } - - inline WLFloatControl & operator = (F32 val) { - x = val; - return *this; - } - - inline operator F32 (void) const { - return x; - } - - inline void update(LLWLParamSet & params) const { - params.set(mName, x); - } -}; - -/// WindLight parameter manager class - what controls all the wind light shaders -class LLWLParamManager : public LLSingleton<LLWLParamManager> -{ - LLSINGLETON(LLWLParamManager); - ~LLWLParamManager(); - LOG_CLASS(LLWLParamManager); - -public: - typedef std::list<std::string> preset_name_list_t; - typedef std::list<LLWLParamKey> preset_key_list_t; - typedef boost::signals2::signal<void()> preset_list_signal_t; - - /// save the parameter presets to file - void savePreset(const LLWLParamKey key); - - /// Set shader uniforms dirty, so they'll update automatically. - void propagateParameters(void); - - /// Update shader uniforms that have changed. - void updateShaderUniforms(LLGLSLShader * shader); - - /// setup the animator to run - void resetAnimator(F32 curTime, bool run); - - /// update information camera dependent parameters - void update(LLViewerCamera * cam); - - /// apply specified day cycle, setting time to noon by default - bool applyDayCycleParams(const LLSD& params, LLEnvKey::EScope scope, F32 time = 0.5); - - /// Apply Default.xml map - void setDefaultDay(); - - /// apply specified fixed sky params - bool applySkyParams(const LLSD& params); - - void setDefaultSky(); - - // get where the light is pointing - inline LLVector4 getLightDir(void) const; - - // get where the light is pointing - inline LLVector4 getClampedLightDir(void) const; - - // get where the light is pointing - inline LLVector4 getRotatedLightDir(void) const; - - /// get the dome's offset - inline F32 getDomeOffset(void) const; - - /// get the radius of the dome - inline F32 getDomeRadius(void) const; - - /// add a param set (preset) to the list - bool addParamSet(const LLWLParamKey& key, LLWLParamSet& param); - - /// add a param set (preset) to the list - BOOL addParamSet(const LLWLParamKey& key, LLSD const & param); - - /// get a param set (preset) from the list - bool getParamSet(const LLWLParamKey& key, LLWLParamSet& param); - - /// check whether the preset is in the list - bool hasParamSet(const LLWLParamKey& key); - - /// set the param in the list with a new param - bool setParamSet(const LLWLParamKey& key, LLWLParamSet& param); - - /// set the param in the list with a new param - bool setParamSet(const LLWLParamKey& key, LLSD const & param); - - /// gets rid of a parameter and any references to it - /// ignores "delete_from_disk" if the scope is not local - void removeParamSet(const LLWLParamKey& key, bool delete_from_disk); - - /// clear parameter mapping of a given scope - void clearParamSetsOfScope(LLEnvKey::EScope scope); - - /// @return true if the preset comes out of the box - bool isSystemPreset(const std::string& preset_name) const; - - /// @return user and system preset names as a single list - void getPresetNames(preset_name_list_t& region, preset_name_list_t& user, preset_name_list_t& sys) const; - - /// @return user preset names - void getUserPresetNames(preset_name_list_t& user) const; - - /// @return keys of all known presets - void getPresetKeys(preset_key_list_t& keys) const; - - /// Emitted when a preset gets added or deleted. - boost::signals2::connection setPresetListChangeCallback(const preset_list_signal_t::slot_type& cb); - - /// add all skies in LLSD using the given scope - void addAllSkies(LLEnvKey::EScope scope, const LLSD& preset_map); - - /// refresh region-scope presets - void refreshRegionPresets(const LLSD& region_sky_presets); - - // returns all skies referenced by the current day cycle (in mDay), with their final names - // side effect: applies changes to all internal structures! (trashes all unreferenced skies in scope, keys in day cycle rescoped to scope, etc.) - std::map<LLWLParamKey, LLWLParamSet> finalizeFromDayCycle(LLWLParamKey::EScope scope); - - // returns all skies in map (intended to be called with output from a finalize) - static LLSD createSkyMap(std::map<LLWLParamKey, LLWLParamSet> map); - - /// escape string in a way different from LLURI::escape() - static std::string escapeString(const std::string& str); - - // helper variables - LLWLAnimator mAnimator; - - /// actual direction of the sun - LLVector4 mLightDir; - - /// light norm adjusted so haze works correctly - LLVector4 mRotatedLightDir; - - /// clamped light norm for shaders that - /// are adversely affected when the sun goes below the - /// horizon - LLVector4 mClampedLightDir; - - // list of params and how they're cycled for days - LLWLDayCycle mDay; - - LLWLParamSet mCurParams; - - /// Sun Delta Terrain tweak variables. - F32 mSunDeltaYaw; - WLFloatControl mWLGamma; - - F32 mSceneLightStrength; - - /// Atmospherics - WLColorControl mBlueHorizon; - WLFloatControl mHazeDensity; - WLColorControl mBlueDensity; - WLFloatControl mDensityMult; - WLFloatControl mHazeHorizon; - WLFloatControl mMaxAlt; - - /// Lighting - WLColorControl mLightnorm; - WLColorControl mSunlight; - WLColorControl mAmbient; - WLColorControl mGlow; - - /// Clouds - WLColorControl mCloudColor; - WLColorControl mCloudMain; - WLFloatControl mCloudCoverage; - WLColorControl mCloudDetail; - WLFloatControl mDistanceMult; - WLFloatControl mCloudScale; - - /// sky dome - F32 mDomeOffset; - F32 mDomeRadius; - - -private: - - friend class LLWLAnimator; - - void loadAllPresets(); - void loadPresetsFromDir(const std::string& dir); - bool loadPreset(const std::string& path); - - static std::string getSysDir(); - static std::string getUserDir(); - - /*virtual*/ void initSingleton(); - // list of all the parameters, listed by name - std::map<LLWLParamKey, LLWLParamSet> mParamList; - - preset_list_signal_t mPresetListChangeSignal; -}; - -inline F32 LLWLParamManager::getDomeOffset(void) const -{ - return mDomeOffset; -} - -inline F32 LLWLParamManager::getDomeRadius(void) const -{ - return mDomeRadius; -} - -inline LLVector4 LLWLParamManager::getLightDir(void) const -{ - return mLightDir; -} - -inline LLVector4 LLWLParamManager::getClampedLightDir(void) const -{ - return mClampedLightDir; -} - -inline LLVector4 LLWLParamManager::getRotatedLightDir(void) const -{ - return mRotatedLightDir; -} - -#endif - diff --git a/indra/newview/llwlparamset.cpp b/indra/newview/llwlparamset.cpp deleted file mode 100644 index 066cb9a0ac..0000000000 --- a/indra/newview/llwlparamset.cpp +++ /dev/null @@ -1,418 +0,0 @@ -/** - * @file llwlparamset.cpp - * @brief Implementation for the LLWLParamSet class. - * - * $LicenseInfo:firstyear=2005&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, 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 "llwlparamset.h" -#include "llwlanimator.h" - -#include "llwlparammanager.h" -#include "llglslshader.h" -#include "lluictrlfactory.h" -#include "llsliderctrl.h" -#include "pipeline.h" - -#include <llgl.h> - -#include <sstream> - -static LLStaticHashedString sStarBrightness("star_brightness"); -static LLStaticHashedString sPresetNum("preset_num"); -static LLStaticHashedString sSunAngle("sun_angle"); -static LLStaticHashedString sEastAngle("east_angle"); -static LLStaticHashedString sEnableCloudScroll("enable_cloud_scroll"); -static LLStaticHashedString sCloudScrollRate("cloud_scroll_rate"); -static LLStaticHashedString sLightNorm("lightnorm"); -static LLStaticHashedString sCloudDensity("cloud_pos_density1"); -static LLStaticHashedString sCloudScale("cloud_scale"); -static LLStaticHashedString sCloudShadow("cloud_shadow"); -static LLStaticHashedString sDensityMultiplier("density_multiplier"); -static LLStaticHashedString sDistanceMultiplier("distance_multiplier"); -static LLStaticHashedString sHazeDensity("haze_density"); -static LLStaticHashedString sHazeHorizon("haze_horizon"); -static LLStaticHashedString sMaxY("max_y"); - -LLWLParamSet::LLWLParamSet(void) : - mName("Unnamed Preset"), - mCloudScrollXOffset(0.f), mCloudScrollYOffset(0.f) -{} - -static LLTrace::BlockTimerStatHandle FTM_WL_PARAM_UPDATE("WL Param Update"); - -void LLWLParamSet::update(LLGLSLShader * shader) const -{ - LL_RECORD_BLOCK_TIME(FTM_WL_PARAM_UPDATE); - LLSD::map_const_iterator i = mParamValues.beginMap(); - std::vector<LLStaticHashedString>::const_iterator n = mParamHashedNames.begin(); - for(;(i != mParamValues.endMap()) && (n != mParamHashedNames.end());++i, n++) - { - const LLStaticHashedString& param = *n; - - // check that our pre-hashed names are still tracking the mParamValues map correctly - // - llassert(param.String() == i->first); - - if (param == sStarBrightness || param == sPresetNum || param == sSunAngle || - param == sEastAngle || param == sEnableCloudScroll || - param == sCloudScrollRate || param == sLightNorm ) - { - continue; - } - - if (param == sCloudDensity) - { - LLVector4 val; - val.mV[0] = F32(i->second[0].asReal()) + mCloudScrollXOffset; - val.mV[1] = F32(i->second[1].asReal()) + mCloudScrollYOffset; - val.mV[2] = (F32) i->second[2].asReal(); - val.mV[3] = (F32) i->second[3].asReal(); - - stop_glerror(); - shader->uniform4fv(param, 1, val.mV); - stop_glerror(); - } - else if (param == sCloudScale || param == sCloudShadow || - param == sDensityMultiplier || param == sDistanceMultiplier || - param == sHazeDensity || param == sHazeHorizon || - param == sMaxY ) - { - F32 val = (F32) i->second[0].asReal(); - - stop_glerror(); - shader->uniform1f(param, val); - stop_glerror(); - } - else // param is the uniform name - { - // handle all the different cases - if (i->second.isArray() && i->second.size() == 4) - { - LLVector4 val; - - val.mV[0] = (F32) i->second[0].asReal(); - val.mV[1] = (F32) i->second[1].asReal(); - val.mV[2] = (F32) i->second[2].asReal(); - val.mV[3] = (F32) i->second[3].asReal(); - - stop_glerror(); - shader->uniform4fv(param, 1, val.mV); - stop_glerror(); - } - else if (i->second.isReal()) - { - F32 val = (F32) i->second.asReal(); - - stop_glerror(); - shader->uniform1f(param, val); - stop_glerror(); - } - else if (i->second.isInteger()) - { - S32 val = (S32) i->second.asInteger(); - - stop_glerror(); - shader->uniform1i(param, val); - stop_glerror(); - } - else if (i->second.isBoolean()) - { - S32 val = (i->second.asBoolean() ? 1 : 0); - - stop_glerror(); - shader->uniform1i(param, val); - stop_glerror(); - } - } - } - - if (LLPipeline::sRenderDeferred && !LLPipeline::sReflectionRender && !LLPipeline::sUnderWaterRender) - { - shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2); - } else { - shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0); - } -} - -void LLWLParamSet::set(const std::string& paramName, float x) -{ - // handle case where no array - if(mParamValues[paramName].isReal()) - { - mParamValues[paramName] = x; - } - - // handle array - else if(mParamValues[paramName].isArray() && - mParamValues[paramName][0].isReal()) - { - mParamValues[paramName][0] = x; - } -} - -void LLWLParamSet::set(const std::string& paramName, float x, float y) -{ - mParamValues[paramName][0] = x; - mParamValues[paramName][1] = y; -} - -void LLWLParamSet::set(const std::string& paramName, float x, float y, float z) -{ - mParamValues[paramName][0] = x; - mParamValues[paramName][1] = y; - mParamValues[paramName][2] = z; -} - -void LLWLParamSet::set(const std::string& paramName, float x, float y, float z, float w) -{ - mParamValues[paramName][0] = x; - mParamValues[paramName][1] = y; - mParamValues[paramName][2] = z; - mParamValues[paramName][3] = w; -} - -void LLWLParamSet::set(const std::string& paramName, const float * val) -{ - mParamValues[paramName][0] = val[0]; - mParamValues[paramName][1] = val[1]; - mParamValues[paramName][2] = val[2]; - mParamValues[paramName][3] = val[3]; -} - -void LLWLParamSet::set(const std::string& paramName, const LLVector4 & val) -{ - mParamValues[paramName][0] = val.mV[0]; - mParamValues[paramName][1] = val.mV[1]; - mParamValues[paramName][2] = val.mV[2]; - mParamValues[paramName][3] = val.mV[3]; -} - -void LLWLParamSet::set(const std::string& paramName, const LLColor4 & val) -{ - mParamValues[paramName][0] = val.mV[0]; - mParamValues[paramName][1] = val.mV[1]; - mParamValues[paramName][2] = val.mV[2]; - mParamValues[paramName][3] = val.mV[3]; -} - -LLVector4 LLWLParamSet::getVector(const std::string& paramName, bool& error) -{ - // test to see if right type - LLSD cur_val = mParamValues.get(paramName); - if (!cur_val.isArray()) - { - error = true; - return LLVector4(0,0,0,0); - } - - LLVector4 val; - val.mV[0] = (F32) cur_val[0].asReal(); - val.mV[1] = (F32) cur_val[1].asReal(); - val.mV[2] = (F32) cur_val[2].asReal(); - val.mV[3] = (F32) cur_val[3].asReal(); - - error = false; - return val; -} - -F32 LLWLParamSet::getFloat(const std::string& paramName, bool& error) -{ - // test to see if right type - LLSD cur_val = mParamValues.get(paramName); - if (cur_val.isArray() && cur_val.size() != 0) - { - error = false; - return (F32) cur_val[0].asReal(); - } - - if(cur_val.isReal()) - { - error = false; - return (F32) cur_val.asReal(); - } - - error = true; - return 0; -} - -void LLWLParamSet::setSunAngle(float val) -{ - // keep range 0 - 2pi - if(val > F_TWO_PI || val < 0) - { - F32 num = val / F_TWO_PI; - num -= floor(num); - val = F_TWO_PI * num; - } - - mParamValues["sun_angle"] = val; -} - - -void LLWLParamSet::setEastAngle(float val) -{ - // keep range 0 - 2pi - if(val > F_TWO_PI || val < 0) - { - F32 num = val / F_TWO_PI; - num -= floor(num); - val = F_TWO_PI * num; - } - - mParamValues["east_angle"] = val; -} - -void LLWLParamSet::mix(LLWLParamSet& src, LLWLParamSet& dest, F32 weight) -{ - // set up the iterators - - // keep cloud positions and coverage the same - /// TODO masking will do this later - F32 cloudPos1X = (F32) mParamValues["cloud_pos_density1"][0].asReal(); - F32 cloudPos1Y = (F32) mParamValues["cloud_pos_density1"][1].asReal(); - F32 cloudPos2X = (F32) mParamValues["cloud_pos_density2"][0].asReal(); - F32 cloudPos2Y = (F32) mParamValues["cloud_pos_density2"][1].asReal(); - F32 cloudCover = (F32) mParamValues["cloud_shadow"][0].asReal(); - - LLSD srcVal; - LLSD destVal; - - // Iterate through values - for(LLSD::map_iterator iter = mParamValues.beginMap(); iter != mParamValues.endMap(); ++iter) - { - // If param exists in both src and dest, set the holder variables, otherwise skip - if(src.mParamValues.has(iter->first) && dest.mParamValues.has(iter->first)) - { - srcVal = src.mParamValues[iter->first]; - destVal = dest.mParamValues[iter->first]; - } - else - { - continue; - } - - if(iter->second.isReal()) // If it's a real, interpolate directly - { - iter->second = srcVal.asReal() + ((destVal.asReal() - srcVal.asReal()) * weight); - } - else if(iter->second.isArray() && iter->second[0].isReal() // If it's an array of reals, loop through the reals and interpolate on those - && iter->second.size() == srcVal.size() && iter->second.size() == destVal.size()) - { - // Actually do interpolation: old value + (difference in values * factor) - for(int i=0; i < iter->second.size(); ++i) - { - // iter->second[i] = (1.f-weight)*(F32)srcVal[i].asReal() + weight*(F32)destVal[i].asReal(); // old way of doing it -- equivalent but one more operation - iter->second[i] = srcVal[i].asReal() + ((destVal[i].asReal() - srcVal[i].asReal()) * weight); - } - } - else // Else, skip - { - continue; - } - } - - // now mix the extra parameters - setStarBrightness((1 - weight) * (F32) src.getStarBrightness() - + weight * (F32) dest.getStarBrightness()); - - llassert(src.getSunAngle() >= - F_PI && - src.getSunAngle() <= 3 * F_PI); - llassert(dest.getSunAngle() >= - F_PI && - dest.getSunAngle() <= 3 * F_PI); - llassert(src.getEastAngle() >= 0 && - src.getEastAngle() <= 4 * F_PI); - llassert(dest.getEastAngle() >= 0 && - dest.getEastAngle() <= 4 * F_PI); - - // sun angle and east angle require some handling to make sure - // they go in circles. Yes quaternions would work better. - F32 srcSunAngle = src.getSunAngle(); - F32 destSunAngle = dest.getSunAngle(); - F32 srcEastAngle = src.getEastAngle(); - F32 destEastAngle = dest.getEastAngle(); - - if(fabsf(srcSunAngle - destSunAngle) > F_PI) - { - if(srcSunAngle > destSunAngle) - { - destSunAngle += 2 * F_PI; - } - else - { - srcSunAngle += 2 * F_PI; - } - } - - if(fabsf(srcEastAngle - destEastAngle) > F_PI) - { - if(srcEastAngle > destEastAngle) - { - destEastAngle += 2 * F_PI; - } - else - { - srcEastAngle += 2 * F_PI; - } - } - - setSunAngle((1 - weight) * srcSunAngle + weight * destSunAngle); - setEastAngle((1 - weight) * srcEastAngle + weight * destEastAngle); - - // now setup the sun properly - - // reset those cloud positions - mParamValues["cloud_pos_density1"][0] = cloudPos1X; - mParamValues["cloud_pos_density1"][1] = cloudPos1Y; - mParamValues["cloud_pos_density2"][0] = cloudPos2X; - mParamValues["cloud_pos_density2"][1] = cloudPos2Y; - mParamValues["cloud_shadow"][0] = cloudCover; -} - -void LLWLParamSet::updateCloudScrolling(void) -{ - static LLTimer s_cloud_timer; - - F64 delta_t = s_cloud_timer.getElapsedTimeAndResetF64(); - - if(getEnableCloudScrollX()) - { - mCloudScrollXOffset += F32(delta_t * (getCloudScrollX() - 10.f) / 100.f); - } - if(getEnableCloudScrollY()) - { - mCloudScrollYOffset += F32(delta_t * (getCloudScrollY() - 10.f) / 100.f); - } -} - -void LLWLParamSet::updateHashedNames() -{ - mParamHashedNames.clear(); - // Iterate through values - for(LLSD::map_iterator iter = mParamValues.beginMap(); iter != mParamValues.endMap(); ++iter) - { - mParamHashedNames.push_back(LLStaticHashedString(iter->first)); - } -} - diff --git a/indra/newview/llwlparamset.h b/indra/newview/llwlparamset.h deleted file mode 100644 index 6e5f1d3a4b..0000000000 --- a/indra/newview/llwlparamset.h +++ /dev/null @@ -1,246 +0,0 @@ -/** - * @file llwlparamset.h - * @brief Interface for the LLWLParamSet class. - * - * $LicenseInfo:firstyear=2005&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, 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_WLPARAM_SET_H -#define LL_WLPARAM_SET_H - -#include <string> -#include <map> -#include <vector> - -#include "v4math.h" -#include "v4color.h" -#include "llstaticstringtable.h" - -class LLWLParamSet; -class LLGLSLShader; - -/// A class representing a set of parameter values for the WindLight shaders. -class LLWLParamSet { - - friend class LLWLParamManager; - -public: - std::string mName; - -private: - - LLSD mParamValues; - std::vector<LLStaticHashedString> mParamHashedNames; - - float mCloudScrollXOffset, mCloudScrollYOffset; - - void updateHashedNames(); - -public: - - LLWLParamSet(); - - /// Update this set of shader uniforms from the parameter values. - void update(LLGLSLShader * shader) const; - - /// set the total llsd - void setAll(const LLSD& val); - - /// get the total llsd - const LLSD& getAll(); - - - /// Set a float parameter. - /// \param paramName The name of the parameter to set. - /// \param x The float value to set. - void set(const std::string& paramName, float x); - - /// Set a float2 parameter. - /// \param paramName The name of the parameter to set. - /// \param x The x component's value to set. - /// \param y The y component's value to set. - void set(const std::string& paramName, float x, float y); - - /// Set a float3 parameter. - /// \param paramName The name of the parameter to set. - /// \param x The x component's value to set. - /// \param y The y component's value to set. - /// \param z The z component's value to set. - void set(const std::string& paramName, float x, float y, float z); - - /// Set a float4 parameter. - /// \param paramName The name of the parameter to set. - /// \param x The x component's value to set. - /// \param y The y component's value to set. - /// \param z The z component's value to set. - /// \param w The w component's value to set. - void set(const std::string& paramName, float x, float y, float z, float w); - - /// Set a float4 parameter. - /// \param paramName The name of the parameter to set. - /// \param val An array of the 4 float values to set the parameter to. - void set(const std::string& paramName, const float * val); - - /// Set a float4 parameter. - /// \param paramName The name of the parameter to set. - /// \param val A struct of the 4 float values to set the parameter to. - void set(const std::string& paramName, const LLVector4 & val); - - /// Set a float4 parameter. - /// \param paramName The name of the parameter to set. - /// \param val A struct of the 4 float values to set the parameter to. - void set(const std::string& paramName, const LLColor4 & val); - - /// Get a float4 parameter. - /// \param paramName The name of the parameter to set. - /// \param error A flag to set if it's not the proper return type - LLVector4 getVector(const std::string& paramName, bool& error); - - /// Get a float parameter - /// \param paramName The name of the parameter to set. - /// \param error A flag to set if it's not the proper return type - F32 getFloat(const std::string& paramName, bool& error); - - - // specific getters and setters - - - /// set the star's brightness - /// \param val brightness value - void setStarBrightness(F32 val); - - /// get the star brightness value; - F32 getStarBrightness(); - - void setSunAngle(F32 val); - F32 getSunAngle(); - - void setEastAngle(F32 val); - F32 getEastAngle(); - - - - /// set the cloud scroll x enable value - /// \param val scroll x value - void setEnableCloudScrollX(bool val); - - /// get the scroll x enable value; - bool getEnableCloudScrollX(); - - /// set the star's brightness - /// \param val scroll y bool value - void setEnableCloudScrollY(bool val); - - /// get the scroll enable y value; - bool getEnableCloudScrollY(); - - /// set the cloud scroll x enable value - /// \param val scroll x value - void setCloudScrollX(F32 val); - - /// get the scroll x enable value; - F32 getCloudScrollX(); - - /// set the star's brightness - /// \param val scroll y bool value - void setCloudScrollY(F32 val); - - /// get the scroll enable y value; - F32 getCloudScrollY(); - - /// interpolate two parameter sets - /// \param src The parameter set to start with - /// \param dest The parameter set to end with - /// \param weight The amount to interpolate - void mix(LLWLParamSet& src, LLWLParamSet& dest, - F32 weight); - - void updateCloudScrolling(void); -}; - -inline void LLWLParamSet::setAll(const LLSD& val) -{ - if(val.isMap()) { - mParamValues = val; - } - - updateHashedNames(); -} - -inline const LLSD& LLWLParamSet::getAll() -{ - return mParamValues; -} - -inline void LLWLParamSet::setStarBrightness(float val) { - mParamValues["star_brightness"] = val; -} - -inline F32 LLWLParamSet::getStarBrightness() { - return (F32) mParamValues["star_brightness"].asReal(); -} - -inline F32 LLWLParamSet::getSunAngle() { - return (F32) mParamValues["sun_angle"].asReal(); -} - -inline F32 LLWLParamSet::getEastAngle() { - return (F32) mParamValues["east_angle"].asReal(); -} - - -inline void LLWLParamSet::setEnableCloudScrollX(bool val) { - mParamValues["enable_cloud_scroll"][0] = val; -} - -inline bool LLWLParamSet::getEnableCloudScrollX() { - return mParamValues["enable_cloud_scroll"][0].asBoolean(); -} - -inline void LLWLParamSet::setEnableCloudScrollY(bool val) { - mParamValues["enable_cloud_scroll"][1] = val; -} - -inline bool LLWLParamSet::getEnableCloudScrollY() { - return mParamValues["enable_cloud_scroll"][1].asBoolean(); -} - - -inline void LLWLParamSet::setCloudScrollX(F32 val) { - mParamValues["cloud_scroll_rate"][0] = val; -} - -inline F32 LLWLParamSet::getCloudScrollX() { - return (F32) mParamValues["cloud_scroll_rate"][0].asReal(); -} - -inline void LLWLParamSet::setCloudScrollY(F32 val) { - mParamValues["cloud_scroll_rate"][1] = val; -} - -inline F32 LLWLParamSet::getCloudScrollY() { - return (F32) mParamValues["cloud_scroll_rate"][1].asReal(); -} - - -#endif // LL_WLPARAM_SET_H - diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 1d083bb2fd..634a23b461 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -100,8 +100,6 @@ #include "llviewerstats.h" #include "llviewerjoystick.h" #include "llviewerdisplay.h" -#include "llwlparammanager.h" -#include "llwaterparammanager.h" #include "llspatialpartition.h" #include "llmutelist.h" #include "lltoolpie.h" @@ -116,6 +114,8 @@ #include "llprogressview.h" #include "llcleanup.h" +#include "llenvironment.h" + #ifdef _DEBUG // Debug indices is disabled for now for debug performance - djs 4/24/02 //#define DEBUG_INDICES @@ -381,6 +381,7 @@ bool LLPipeline::sRenderBump = true; bool LLPipeline::sBakeSunlight = false; bool LLPipeline::sNoAlpha = false; bool LLPipeline::sUseTriStrips = true; +bool LLPipeline::sUseAdvancedAtmospherics = false; bool LLPipeline::sUseFarClip = true; bool LLPipeline::sShadowRender = false; bool LLPipeline::sWaterReflections = false; @@ -480,6 +481,7 @@ void LLPipeline::init() sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD"); sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips"); + sUseAdvancedAtmospherics = gSavedSettings.getBOOL("RenderUseAdvancedAtmospherics"); LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO"); LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO"); LLVertexBuffer::sPreferStreamDraw = gSavedSettings.getBOOL("RenderPreferStreamDraw"); @@ -981,7 +983,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) for (U32 i = 0; i < 4; i++) { if (!mShadow[i].allocate(sun_shadow_map_width,U32(resY*scale), 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) return false; - if (!mShadowOcclusion[i].allocate(mShadow[i].getWidth()/occlusion_divisor, mShadow[i].getHeight()/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) return false; + if (!mShadowOcclusion[i].allocate(mShadow[i].getWidth()/occlusion_divisor, mShadow[i].getHeight()/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) return false; } } else @@ -993,6 +995,13 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) } } +// for EEP atmospherics + bool allocated_inscatter = mInscatter.allocate(resX >> 2, resY >> 2, GL_RGBA16F_ARB, FALSE, FALSE, LLTexUnit::TT_TEXTURE); + if (!allocated_inscatter) + { + return false; + } + U32 width = (U32) (resX*scale); U32 height = width; @@ -1229,6 +1238,8 @@ void LLPipeline::releaseScreenBuffers() mShadow[i].release(); mShadowOcclusion[i].release(); } + + mInscatter.release(); } @@ -2646,6 +2657,65 @@ void LLPipeline::markOccluder(LLSpatialGroup* group) } } +void LLPipeline::downsampleMinMaxDepthBuffer(LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space) +{ + LLGLSLShader* last_shader = LLGLSLShader::sCurBoundShaderPtr; + + LLGLSLShader* shader = NULL; + + if (scratch_space) + { + scratch_space->copyContents(source, + 0, 0, source.getWidth(), source.getHeight(), + 0, 0, scratch_space->getWidth(), scratch_space->getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); + } + + dest.bindTarget(); + dest.clear(GL_COLOR_BUFFER_BIT); // dest should be an RG16F target + + LLStrider<LLVector3> vert; + mDeferredVB->getVertexStrider(vert); + LLStrider<LLVector2> tc0; + + vert[0].set(-1, 1, 0); + vert[1].set(-1, -3, 0); + vert[2].set(3, 1, 0); + + if (source.getUsage() == LLTexUnit::TT_RECT_TEXTURE) + { + shader = &gDownsampleMinMaxDepthRectProgram; + shader->bind(); + shader->uniform2f(sDelta, 1.f, 1.f); + shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, source.getWidth(), source.getHeight()); + } + else + { + shader = &gDownsampleMinMaxDepthRectProgram; + shader->bind(); + shader->uniform2f(sDelta, 1.f / source.getWidth(), 1.f / source.getHeight()); + shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, 1.f, 1.f); + } + + gGL.getTexUnit(0)->bind(scratch_space ? scratch_space : &source, TRUE); + + { + LLGLDepthTest depth(GL_FALSE, GL_FALSE, GL_ALWAYS); + mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); + } + + dest.flush(); + + if (last_shader) + { + last_shader->bind(); + } + else + { + shader->unbind(); + } +} + void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space) { LLGLSLShader* last_shader = LLGLSLShader::sCurBoundShaderPtr; @@ -8282,6 +8352,21 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n } } + channel = shader.enableTexture(LLShaderMgr::INSCATTER_RT, LLTexUnit::TT_TEXTURE); + stop_glerror(); + if (channel > -1) + { + stop_glerror(); + gGL.getTexUnit(channel)->bind(&mInscatter, TRUE); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); + stop_glerror(); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_ALWAYS); + stop_glerror(); + } + stop_glerror(); F32 mat[16*6]; @@ -9095,6 +9180,7 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target) } } +// pretty sure this doesn't work as expected since the shaders using 'shadow_ofset' all declare it as a single uniform float, no array or vec gDeferredSunProgram.uniform3fv(LLShaderMgr::DEFERRED_SHADOW_OFFSET, slice, offset); gDeferredSunProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mDeferredLight.getWidth(), mDeferredLight.getHeight()); @@ -9911,9 +9997,9 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) } else { - renderGeom(camera); - } - } + renderGeom(camera); + } + } } if (LLPipeline::sRenderDeferred && materials_in_water) @@ -9957,7 +10043,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLColor4& col = LLDrawPoolWater::sWaterFogColor; + LLColor3 col = LLEnvironment::instance().getCurrentWater()->getFogColor(); glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f); mWaterDis.bindTarget(); LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER1; @@ -9994,7 +10080,19 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) } else { - renderGeom(camera); + renderGeom(camera); + + if (LLGLSLShader::sNoFixedFunction) + { + gUIProgram.bind(); + } + + LLWorld::getInstance()->renderPropertyLines(); + + if (LLGLSLShader::sNoFixedFunction) + { + gUIProgram.unbind(); + } } if (LLPipeline::sRenderDeferred && materials_in_water) @@ -10400,23 +10498,25 @@ bool LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector for (U32 j = 0; j < 3; ++j) { - if (p[j] < ext[0].mV[j] || - p[j] > ext[1].mV[j]) + if (p[j] < ext[0].mV[j] || p[j] > ext[1].mV[j]) { found = false; break; } } - - for (U32 j = 0; j < LLCamera::AGENT_PLANE_NO_USER_CLIP_NUM; ++j) + + if (found) // don't bother testing user clip planes if we're already rejected... { - const LLPlane& cp = camera.getAgentPlane(j); - F32 dist = cp.dist(pp[i]); - if (dist > 0.05f) //point is above some plane, not contained - { - found = false; - break; - } + for (U32 j = 0; j < LLCamera::AGENT_PLANE_NO_USER_CLIP_NUM; ++j) + { + const LLPlane& cp = camera.getAgentPlane(j); + F32 dist = cp.dist(pp[i]); + if (dist > 0.05f) //point is above some plane, not contained + { + found = false; + break; + } + } } if (found) @@ -11947,3 +12047,7 @@ void LLPipeline::restoreHiddenObject( const LLUUID& id ) } } +bool LLPipeline::useAdvancedAtmospherics() const +{ + return sUseAdvancedAtmospherics; +} diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index c9670a60f2..6023a41ca2 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -168,6 +168,9 @@ public: // if source's depth buffer cannot be bound for reading, a scratch space depth buffer must be provided void downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space = NULL); + // Downsample depth buffer with gather and find local min/max depth values. Writes to a 16F RG render target. + void downsampleMinMaxDepthBuffer(LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space = NULL); + void doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space = NULL); void doOcclusion(LLCamera& camera); void markNotCulled(LLSpatialGroup* group, LLCamera &camera); @@ -541,6 +544,8 @@ public: void updateCamera(bool reset = false); + bool useAdvancedAtmospherics() const; + LLVector3 mFlyCamPosition; LLQuaternion mFlyCamRotation; @@ -568,6 +573,7 @@ public: static bool sBakeSunlight; static bool sNoAlpha; static bool sUseTriStrips; + static bool sUseAdvancedAtmospherics; static bool sUseFarClip; static bool sShadowRender; static bool sWaterReflections; @@ -614,12 +620,13 @@ public: //sun shadow map LLRenderTarget mShadow[6]; LLRenderTarget mShadowOcclusion[6]; - std::vector<LLVector3> mShadowFrustPoints[4]; - LLVector4 mShadowError; - LLVector4 mShadowFOV; - LLVector3 mShadowFrustOrigin[4]; - LLCamera mShadowCamera[8]; - LLVector3 mShadowExtents[4][2]; + LLRenderTarget mInscatter; + std::vector<LLVector3> mShadowFrustPoints[4]; + LLVector4 mShadowError; + LLVector4 mShadowFOV; + LLVector3 mShadowFrustOrigin[4]; + LLCamera mShadowCamera[8]; + LLVector3 mShadowExtents[4][2]; glh::matrix4f mSunShadowMatrix[6]; glh::matrix4f mShadowModelview[6]; glh::matrix4f mShadowProjection[6]; diff --git a/indra/newview/skins/default/textures/icons/Inv_Settings.png b/indra/newview/skins/default/textures/icons/Inv_Settings.png Binary files differnew file mode 100644 index 0000000000..c43ba349c4 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Settings.png diff --git a/indra/newview/skins/default/textures/icons/Inv_SettingsDay.png b/indra/newview/skins/default/textures/icons/Inv_SettingsDay.png Binary files differnew file mode 100644 index 0000000000..258ade1327 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_SettingsDay.png diff --git a/indra/newview/skins/default/textures/icons/Inv_SettingsSky.png b/indra/newview/skins/default/textures/icons/Inv_SettingsSky.png Binary files differnew file mode 100644 index 0000000000..77858b23c3 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_SettingsSky.png diff --git a/indra/newview/skins/default/textures/icons/Inv_SettingsWater.png b/indra/newview/skins/default/textures/icons/Inv_SettingsWater.png Binary files differnew file mode 100644 index 0000000000..46fb58c3f2 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_SettingsWater.png diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index d757e39366..a16b1a68ad 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -323,6 +323,12 @@ with the same filename but different name <texture name="Inv_Underpants" file_name="icons/Inv_Underpants.png" preload="false" /> <texture name="Inv_Undershirt" file_name="icons/Inv_Undershirt.png" preload="false" /> <texture name="Inv_Link" file_name="icons/Inv_Link.png" preload="false" /> + + <texture name="Inv_Settings" file_name="icons/Inv_Settings.png" preload="false" /> + <texture name="Inv_SettingsSky" file_name="icons/Inv_SettingsSky.png" preload="false" /> + <texture name="Inv_SettingsWater" file_name="icons/Inv_SettingsWater.png" preload="false" /> + <texture name="Inv_SettingsDay" file_name="icons/Inv_SettingsDay.png" preload="false" /> + <texture name="Inv_Invalid" file_name="icons/Inv_Invalid.png" preload="false" /> <texture name="Inv_VersionFolderClosed" file_name="icons/Inv_VersionFolderClosed.png" preload="false" /> <texture name="Inv_VersionFolderOpen" file_name="icons/Inv_VersionFolderOpen.png" preload="false" /> diff --git a/indra/newview/skins/default/xui/de/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/de/floater_delete_env_preset.xml deleted file mode 100644 index cc14ce640d..0000000000 --- a/indra/newview/skins/default/xui/de/floater_delete_env_preset.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<floater name="Delete Env Preset" title="UMGEB.VOREINST. LÖSCHEN"> - <string name="title_water"> - Wasser-Voreinstellung löschen - </string> - <string name="title_sky"> - Himmel-Voreinstellung löschen - </string> - <string name="title_day_cycle"> - Tageszyklus löschen - </string> - <string name="label_water"> - Voreinstellung: - </string> - <string name="label_sky"> - Voreinstellung: - </string> - <string name="label_day_cycle"> - Tageszyklus: - </string> - <string name="msg_confirm_deletion"> - Möchten Sie die ausgewählte Voreinstellung wirklich löschen? - </string> - <string name="msg_sky_is_referenced"> - Eine Voreinstellung, auf die sich ein Tageszyklus bezieht, kann nicht gelöscht werden. - </string> - <string name="combo_label"> - -Voreinstellung auswählen- - </string> - <text name="label"> - Voreinstellung: - </text> - <button label="Löschen" name="delete"/> - <button label="Abbrechen" name="cancel"/> -</floater> diff --git a/indra/newview/skins/default/xui/de/menu_viewer.xml b/indra/newview/skins/default/xui/de/menu_viewer.xml index 58c691351c..183aa24008 100644 --- a/indra/newview/skins/default/xui/de/menu_viewer.xml +++ b/indra/newview/skins/default/xui/de/menu_viewer.xml @@ -89,17 +89,14 @@ <menu label="Wasser-Voreinstellungen" name="Water Presets"> <menu_item_call label="Neue Voreinstellung..." name="new_water_preset"/> <menu_item_call label="Voreinstellung bearbeiten..." name="edit_water_preset"/> - <menu_item_call label="Voreinstellung löschen..." name="delete_water_preset"/> </menu> <menu label="Himmel-Voreinstellungen" name="Sky Presets"> <menu_item_call label="Neue Voreinstellung..." name="new_sky_preset"/> <menu_item_call label="Voreinstellung bearbeiten..." name="edit_sky_preset"/> - <menu_item_call label="Voreinstellung löschen..." name="delete_sky_preset"/> </menu> <menu label="Tag-Voreinstellungen" name="Day Presets"> <menu_item_call label="Neue Voreinstellung..." name="new_day_preset"/> <menu_item_call label="Voreinstellung bearbeiten..." name="edit_day_preset"/> - <menu_item_call label="Voreinstellung löschen..." name="delete_day_preset"/> </menu> </menu> </menu> diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml index 535af317d9..334de8e3db 100644 --- a/indra/newview/skins/default/xui/en/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en/floater_about_land.xml @@ -2109,5 +2109,17 @@ Only large parcels can be listed in search. class="land_experiences_panel" filename="panel_region_experiences.xml"> </panel> + <panel + border="true" + follows="all" + label="ENVIRONMENT" + layout="topleft" + left="0" + top="0" + help_topic="land_environment_tab" + name="land_environment_panel" + class="land_environment_panel" + filename="panel_region_environment.xml"> + </panel> </tab_container> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/en/floater_delete_env_preset.xml deleted file mode 100644 index b5de4166f6..0000000000 --- a/indra/newview/skins/default/xui/en/floater_delete_env_preset.xml +++ /dev/null @@ -1,59 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<floater - legacy_header_height="18" - height="130" - help_topic="" - layout="topleft" - name="Delete Env Preset" - save_rect="true" - title="DELETE ENV PRESET" - width="550"> - - <string name="title_water">Delete Water Preset</string> - <string name="title_sky">Delete Sky Preset</string> - <string name="title_day_cycle">Delete Day Cycle</string> - - <string name="label_water">Preset:</string> - <string name="label_sky">Preset:</string> - <string name="label_day_cycle">Day cycle:</string> - - <string name="msg_confirm_deletion">Are you sure you want to delete the selected preset?</string> - <string name="msg_sky_is_referenced">Cannot remove a preset that is referenced by some day cycle(s).</string> - - <string name="combo_label">-Select a preset-</string> - - <text - follows="top|left|right" - font="SansSerif" - height="10" - layout="topleft" - left="50" - name="label" - top="60" - width="60"> - Preset: - </text> - <combo_box - follows="top|left" - layout="topleft" - left_pad="10" - name="preset_combo" - top_delta="-5" - width="200"/> - <button - follows="bottom|right" - height="23" - label="Delete" - layout="topleft" - left_pad="15" - name="delete" - width="70"/> - <button - follows="bottom|right" - height="23" - label="Cancel" - layout="topleft" - left_pad="5" - name="cancel" - width="70"/> -</floater> 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 new file mode 100644 index 0000000000..86c580f354 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml @@ -0,0 +1,518 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + height="602" + layout="topleft" + name="env_edit_extdaycycle" + help_topic="day_presets" + save_rect="true" + title="Edit Day Cycle" + width="705"> + + <!-- obsolete?, add as hint for 'save' button? --> + <string name="title_new">Create a New Day Cycle</string> + <string name="title_edit">Edit Day Cycle</string> + <string name="hint_new">Name your day cycle, adjust the controls to create it, and click "Save".</string> + <string name="hint_edit">To edit your day cycle, adjust the controls below and click "Save".</string> + + <!-- Todo: These 5 strings might be subjected to a change to get dynamic labels, consider using layout_stack to get dynamic width adjustment--> + <string name="time_label"> ([HH]:[MM])</string> + + <layout_stack name="test_stack" + width="705" + height="602" + follows="all" + animate="false" + top="0" + orientation="vertical"> + <layout_panel name="temp" + border="false" + auto_resize="false" + user_resize="true" + height="29" + min_height="29" + background_visible="false"> + <!-- This layout_panel is for loading legacy presets --> + <text + follows="top|left" + font="SansSerif" + height="10" + layout="topleft" + name="label" + left="15" + top="5" + width="105"> + Day Cycle Name: + </text> + <line_editor + follows="top|left" + layout="topleft" + left_pad="10" + max_length_bytes="100" + name="day_cycle_name" + top="5" + width="200" + height="21" /> + <button + height="23" + label="Import" + follows="right|top" + right="-10" + font="SansSerif" + top_delta="0" + name="btn_import" + tool_tip="Import legacy settings from disk." + width="96" /> + </layout_panel> + <layout_panel name="timeline_track_selection" + border="false" + bevel_style="in" + auto_resize="false" + user_resize="true" + height="150" + min_height="0" + visible="true"> + <panel name="timeline_layers" + border="false" + follows="left|top" + height="150" + width="110" + top_pad="0" + min_height="0" + visible="true"> + <button + follows="left|top" + height="23" + label="Sky 4" + layout="topleft" + top_pad="5" + left="10" + name="sky4_track" + width="100"> + <button.commit_callback + function="DayCycle.Track" + parameter="4" /> + </button> + <button + follows="left|top" + height="23" + label="Sky 3" + layout="topleft" + top_pad="0" + left="10" + name="sky3_track" + width="100"> + <button.commit_callback + function="DayCycle.Track" + parameter="3" /> + </button> + <button + follows="left|top" + height="23" + label="Sky 2" + layout="topleft" + top_pad="0" + left="10" + name="sky2_track" + width="100"> + <button.commit_callback + function="DayCycle.Track" + parameter="2" /> + </button> + <button + follows="left|top" + height="23" + label="Ground Level" + layout="topleft" + top_pad="0" + left="10" + name="sky1_track" + width="100"> + <button.commit_callback + function="DayCycle.Track" + parameter="1" /> + </button> + <button + follows="left|top" + height="23" + label="Water" + layout="topleft" + top_pad="0" + left="10" + name="water_track" + width="100"> + <button.commit_callback + function="DayCycle.Track" + parameter="0" /> + </button> + </panel> + <panel name="timeline" + border="true" + follows="left|top" + height="150" + min_height="0" + width="595" + min_width="595" + left_pad="0" + visible="true"> + <!-- Todo: These 5 tests might be subjected to a change to be dynamically generated, consider using layout_stack to get dynamic width adjustment--> + <text + follows="left|top" + height="15" + layout="topleft" + left="10" + name="p0" + top_pad="5" + value="0%[DSC]" + width="80" /> + <text + follows="left|top|right" + height="15" + layout="topleft" + left_pad="39" + name="p1" + top_delta="0" + value="25%[DSC]" + width="80" /> + <text + follows="left|top|right" + height="15" + layout="topleft" + left_pad="39" + name="p2" + top_delta="0" + value="50%[DSC]" + width="80" /> + <text + follows="left|top|right" + height="15" + layout="topleft" + left_pad="39" + name="p3" + top_delta="0" + value="75%[DSC]" + width="80" /> + <text + follows="left|top|right" + height="15" + layout="topleft" + left_pad="39" + name="p4" + top_delta="0" + value="100%[DSC]" + width="80" /> + <multi_slider + decimal_digits="0" + draw_track="false" + follows="bottom" + height="10" + increment="0.01" + initial_value="0" + layout="topleft" + left="10" + max_sliders="1" + max_val="1" + name="WLTimeSlider" + show_text="false" + top_pad="0" + use_triangle="true" + width="525" /> + + <multi_slider + decimal_digits="0" + follows="bottom" + height="10" + increment="0.01" + initial_value="0" + layout="topleft" + left="10" + max_sliders="20" + max_val="1" + name="WLDayCycleFrames" + show_text="false" + top_pad="15" + width="525" /> + + <text + follows="left|bottom" + height="20" + layout="topleft" + left_pad="0" + name="current_time" + value="[PRCNT]%[DSC]" + top_delta="-5" + width="70" /> + + <layout_stack + name="progress_control" + follows="top|left" + height="25" + width="83" + layout="topleft" + animate="false" + left="225" + top_pad="40" + orientation="horizontal"> + + <layout_panel + name="skip_back" + mouse_opaque="false" + auto_resize="false" + layout="topleft" + top="0" + height="25" + min_width="25" + width="25"> + <button + name="skip_back_btn" + follows="top" + image_overlay="SkipBackward_Off" + image_disabled="PushButton_Disabled" + image_disabled_selected="PushButton_Disabled" + image_selected="PushButton_Selected" + image_unselected="PushButton_Off" + hover_glow_amount="0.15" + auto_resize="false" + width="25" + height="25" + layout="topleft" + tool_tip="Step back" + top="0" + left="0"> + <button.commit_callback + function="DayCycle.PlayActions" + parameter="back" /> + </button> + </layout_panel> + + <layout_panel + name="play_layout" + mouse_opaque="false" + auto_resize="false" + layout="topleft" + top="0" + height="25" + min_width="25" + width="25"> + <button + name="play_btn" + follows="top" + image_overlay="Play_Off" + image_disabled="PushButton_Disabled" + image_disabled_selected="PushButton_Disabled" + image_selected="PushButton_Selected" + image_unselected="PushButton_Off" + hover_glow_amount="0.15" + auto_resize="false" + layout="topleft" + height="25" + width="25" + left="0" + top="0"> + <button.commit_callback + function="DayCycle.PlayActions" + parameter="play" /> + </button> + </layout_panel> + + <layout_panel + name="pause_layout" + mouse_opaque="false" + auto_resize="false" + layout="topleft" + top="0" + height="25" + min_width="25" + width="25" + visible="false"> + <button + name="pause_btn" + follows="top" + image_overlay="Pause_Off" + image_disabled="PushButton_Disabled" + image_disabled_selected="PushButton_Disabled" + image_selected="PushButton_Selected" + image_unselected="PushButton_Off" + hover_glow_amount="0.15" + auto_resize="false" + layout="topleft" + height="25" + width="25" + left="0" + top="0"> + <button.commit_callback + function="DayCycle.PlayActions" + parameter="pause" /> + </button> + </layout_panel> + + <layout_panel + name="skip_forward" + mouse_opaque="false" + auto_resize="false" + layout="topleft" + top="0" + height="25" + min_width="25" + width="25"> + <button + name="skip_forward_btn" + follows="top" + image_overlay="SkipForward_Off" + image_disabled="PushButton_Disabled" + image_disabled_selected="PushButton_Disabled" + image_selected="PushButton_Selected" + image_unselected="PushButton_Off" + hover_glow_amount="0.15" + width="25" + height="25" + layout="topleft" + tool_tip="Step forward" + top="0"> + <button.commit_callback + function="DayCycle.PlayActions" + parameter="forward" /> + </button> + </layout_panel> + </layout_stack> + + <button + follows="top|left" + height="23" + width="90" + label="Add Frame" + left_pad="175" + top_delta="-12" + name="add_frame" /> + <button + follows="left|top" + height="23" + width="90" + label="Delete Frame" + top_pad="0" + left_delta="0" + name="delete_frame" /> + </panel> + </layout_panel> + <layout_panel name="frame_settings_water" + auto_resize="false" + user_resize="true" + height="386" + width="700" + min_height="0" + visible="false"> + <tab_container + follows="all" + halign="left" + height="386" + layout="topleft" + left="0" + name="water_tabs" + tab_position="top" + tab_width="140" + tab_padding_right="3" + top_pad="0" + width="700"> + <panel + border="true" + class="panel_settings_water" + filename="panel_settings_water.xml" + label="Water" + layout="topleft" + left_delta="0" + top_pad="5" + name="water_panel"/> + </tab_container> + </layout_panel> + <layout_panel name="frame_settings_sky" + auto_resize="false" + user_resize="true" + height="386" + width="700" + min_height="0" + visible="true"> + <tab_container + follows="all" + halign="left" + height="386" + visible="true" + layout="topleft" + left="0" + name="sky_tabs" + tab_position="top" + tab_width="140" + tab_padding_right="3" + top_pad="0" + width="700"> + <panel + border="true" + class="panel_settings_atmos" + filename="panel_settings_sky_atmos.xml" + label="Atmosphere & Lighting" + layout="topleft" + left_delta="0" + top_pad="5" + name="atmosphere_panel" /> + <panel + border="true" + class="panel_settings_cloud" + filename="panel_settings_sky_clouds.xml" + label="Clouds" + layout="topleft" + left_delta="0" + top_pad="5" + name="clouds_panel" /> + <panel + border="true" + class="panel_settings_sunmoon" + filename="panel_settings_sky_sunmoon.xml" + label="Sun & Moon" + layout="topleft" + left_delta="0" + top_pad="5" + name="moon_panel" /> + </tab_container> + </layout_panel> + <layout_panel name="buttons" + auto_resize="false" + user_resize="true" + height="26" + min_height="0" + visible="true" + width="700"> + <button + follows="top|left" + height="23" + label="Save" + left="5" + top_pad="0" + name="save_btn" + width="100" /> + + <button + follows="top|left" + height="23" + name="btn_flyout" + label="" + layout="topleft" + left_pad="-20" + top="0" + image_selected="SegmentedBtn_Right_Selected_Press" + image_unselected="SegmentedBtn_Right_Off" + image_pressed="SegmentedBtn_Right_Press" + image_pressed_selected="SegmentedBtn_Right_Selected_Press" + image_overlay="Arrow_Small_Up" + width="20"/> + + <button + follows="top|left" + height="23" + label="Cancel" + layout="topleft" + left_pad="10" + name="cancel_btn" + width="100" /> + + </layout_panel> + </layout_stack> + +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_edit_sky_preset.xml b/indra/newview/skins/default/xui/en/floater_edit_sky_preset.xml deleted file mode 100644 index 56233d91ee..0000000000 --- a/indra/newview/skins/default/xui/en/floater_edit_sky_preset.xml +++ /dev/null @@ -1,953 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater - legacy_header_height="18" - height="375" - layout="topleft" - name="Edit Sky Preset" - help_topic="sky_preset" - save_rect="true" - title="Edit Sky Preset" - width="840"> - - <string name="title_new">Create a New Sky Preset</string> - <string name="title_edit">Edit Sky Preset</string> - <string name="hint_new">Name your preset, adjust the controls to create it, and click "Save".</string> - <string name="hint_edit">To edit your sky preset, adjust the controls and click "Save".</string> - <string name="combo_label">-Select a preset-</string> - - <text - follows="top|left|right" - height="10" - layout="topleft" - left="30" - name="hint" - top="25" - width="700"> - To edit your preset, adjust the controls then click "Save" - </text> - <text - follows="top|left|right" - font="SansSerif" - height="10" - layout="topleft" - left="30" - name="label" - top_pad="25" - width="120"> - Preset Name: - </text> - <combo_box - allow_text_entry="true" - follows="top|left" - layout="topleft" - left_pad="10" - max_chars="100" - name="sky_preset_combo" - top_delta="-5" - width="200"/> - <line_editor - height="20" - left_delta="0" - name="sky_preset_name" - top_delta="0" - width="200" /> - <text - follows="top|left|right" - height="40" - layout="topleft" - left_pad="10" - name="note" - top_delta="0" - width="405" - wrap="true"> - Note: if you change the name of your preset, you will be creating a new preset and the existing preset will not be changed. - </text> - <!--======== Controls panel ========--> - <view_border - bevel_style="none" - follows="top|left" - height="203" - layout="topleft" - left="25" - name="panel_water_preset" - top="122" - visible="true" - width="790"/> - <tab_container - follows="left|top" - height="225" - halign="center" - layout="topleft" - left="22" - name="WindLight Tabs" - tab_position="top" - top="101" - width="794"> - <panel - border="true" - bevel_style="none" - follows="left|top|right|bottom" - height="196" - label="ATMOSPHERE" - layout="topleft" - left="1" - help_topic="sky_preset_atmosphere" - mouse_opaque="false" - name="Atmosphere" - top="60" - width="698"> - - <!--======== Tab Panel I. I conlumn of controls ========--> - - <text - type="string" - length="1" - follows="left|top" - font="SansSerif" - height="16" - layout="topleft" - left="40" - name="BHText" - top="25" - width="200"> - Blue Horizon - </text> - <color_swatch - can_apply_immediately="true" - follows="left|top" - height="37" - label_height="0" - layout="topleft" - left_delta="0" - name="WLBlueHorizon" - top_pad="6" - width="60" /> - <text - type="string" - length="1" - follows="left|top" - font="SansSerif" - height="16" - layout="topleft" - left_delta="0" - top_pad="20" - name="BDensText" - width="200"> - Haze Horizon - </text> - <slider - control_name="WLHazeHorizon" - decimal_digits="2" - follows="left|top" - height="10" - increment="0.01" - initial_value="0.25" - layout="topleft" - left_delta="0" - top_pad="6" - name="WLHazeHorizon" - width="200" /> - - <!--======== Tab Panel I. II conlumn of controls ========--> - - <text - type="string" - length="1" - follows="left|top" - font="SansSerif" - height="16" - layout="topleft" - left_pad="55" - name="BDensText2" - top="25" - width="200"> - Blue Density - </text> - <color_swatch - can_apply_immediately="true" - follows="left|top" - height="37" - label_height="0" - layout="topleft" - left_delta="0" - name="WLBlueDensity" - top_pad="6" - width="60" /> - <text - type="string" - length="1" - follows="left|top" - font="SansSerif" - height="16" - layout="topleft" - left_delta="0" - name="HDText" - top_pad="20" - width="200"> - Haze Density - </text> - <slider - control_name="WLHazeDensity" - decimal_digits="2" - follows="left|top" - height="10" - increment="0.01" - initial_value="0.7" - layout="topleft" - left_delta="0" - max_val="4" - name="WLHazeDensity" - top_pad="6" - width="200" /> - - <!--======== Tab Panel I. III conlumn of controls ========--> - - <text - type="string" - length="1" - follows="left|top" - font="SansSerif" - height="16" - layout="topleft" - left_pad="55" - name="DensMultText" - top="25" - width="200"> - Density Multiplier - </text> - <slider - control_name="WLDensityMult" - decimal_digits="2" - follows="left|top" - height="10" - increment="0.01" - initial_value="0.1" - layout="topleft" - left_delta="15" - max_val="0.9" - name="WLDensityMult" - top_pad="6" - width="200" /> - - <text - type="string" - length="1" - follows="left|top" - font="SansSerif" - height="16" - layout="topleft" - left_delta="-15" - name="WLDistanceMultText" - top_pad="20" - width="200"> - Distance Multiplier - </text> - <slider - control_name="WLDistancMult" - decimal_digits="1" - follows="left|top" - height="10" - initial_value="1.0" - layout="topleft" - left_delta="15" - max_val="100" - name="WLDistanceMult" - top_pad="6" - width="200" /> - <text - type="string" - length="1" - follows="left|top" - font="SansSerif" - height="16" - layout="topleft" - left_delta="-15" - name="MaxAltText" - top_pad="20" - width="200"> - Max Altitude - </text> - <slider - control_name="WLMaxAltitude" - decimal_digits="0" - follows="left|top" - height="10" - increment="1" - initial_value="500" - layout="topleft" - left_delta="15" - max_val="4000" - name="WLMaxAltitude" - top_pad="6" - width="200" /> - </panel> - <panel - border="true" - bevel_style="none" - follows="left|top|right|bottom" - height="196" - label="LIGHTING" - layout="topleft" - left_delta="0" - help_topic="sky_preset_lighting" - name="Lighting" - top_delta="4" - width="698"> - - <!--======== Tab Panel II. I conlumn of controls ========--> - - <text - type="string" - length="1" - follows="left|top" - font="SansSerif" - height="16" - layout="topleft" - left="20" - name="SLCText" - top="25" - width="150"> - Sun/Moon Color - </text> - <color_swatch - can_apply_immediately="true" - follows="left|top" - height="37" - label_height="0" - layout="topleft" - left_delta="10" - name="WLSunlight" - top_pad="6" - width="60" /> - <text - type="string" - length="1" - follows="left|top" - font="SansSerif" - height="16" - layout="topleft" - left_delta="-10" - name="WLAmbientText" - top_pad="20" - width="150"> - Ambient - </text> - <color_swatch - can_apply_immediately="true" - follows="left|top" - height="37" - label_height="0" - layout="topleft" - left_delta="10" - name="WLAmbient" - top_pad="6" - width="60" /> - - <!--======== Tab Panel II. II conlumn of controls ========--> - <text - type="string" - length="1" - follows="left|top" - font="SansSerif" - height="16" - layout="topleft" - left_pad="100" - name="SunGlowText" - top="25" - width="200"> - Sun Glow - </text> - <slider - control_name="WLGlowB" - decimal_digits="2" - follows="left|top" - height="10" - increment="0.01" - initial_value="0.1" - label="Focus " - layout="topleft" - left_delta="10" - max_val="0.5" - name="WLGlowB" - top_pad="6" - width="200" /> - <slider - control_name="WLGlowR" - decimal_digits="2" - follows="top|left" - height="10" - increment="0.01" - initial_value="0.25" - label="Size " - layout="topleft" - left_delta="0" - max_val="1.99" - min_val="1" - name="WLGlowR" - top_pad="6" - width="200" /> - <text - type="string" - length="1" - follows="left|top" - font="SansSerif" - height="16" - layout="topleft" - left_delta="-10" - name="WLStarText" - top_pad="20" - width="200"> - Star Brightness - </text> - <slider - control_name="WLStarAlpha" - decimal_digits="2" - follows="top|left" - height="10" - increment="0.01" - initial_value="0" - layout="topleft" - left_delta="10" - max_val="2" - name="WLStarAlpha" - top_pad="6" - width="200" /> - <text - type="string" - length="1" - follows="left|top" - font="SansSerif" - height="16" - layout="topleft" - left_delta="-10" - name="SceneGammaText" - top_pad="20" - width="200"> - Scene Gamma - </text> - <slider - control_name="WLGamma" - decimal_digits="2" - follows="top|left" - height="10" - increment="0.01" - initial_value="2.0" - layout="topleft" - left_delta="10" - max_val="10" - name="WLGamma" - top_pad="6" - width="200" /> - - <!--======== Tab Panel II. III conlumn of controls ========--> - - <text - type="string" - length="1" - follows="left|top" - font="SansSerif" - height="16" - layout="topleft" - left_pad="60" - name="TODText" - top="25" - width="200"> - Sun/Moon Position - </text> - <multi_slider - can_edit_text="true" - control_name="WLSunPos" - decimal_digits="0" - follows="bottom" - height="10" - increment="0.0833333" - initial_value="0" - layout="topleft" - left_delta="0" - max_sliders="1" - max_val="24" - name="WLSunPos" - show_text="false" - top_pad="0" - width="300" /> - - <text - type="string" - length="1" - border_visible="true" - follows="left|top|right" - font="SansSerif" - height="14" - layout="topleft" - left_delta="2" - name="WL12amHash" - top_pad="6" - width="6"> - | - </text> - <text - type="string" - length="1" - border_visible="true" - follows="left|top|right" - font="SansSerif" - height="14" - layout="topleft" - left_pad="66" - name="WL6amHash" - top_delta="0" - width="6"> - | - </text> - <text - type="string" - length="1" - border_visible="true" - follows="left|top|right" - font="SansSerif" - height="14" - layout="topleft" - left_pad="67" - name="WL12pmHash2" - top_delta="0" - width="6"> - | - </text> - <text - type="string" - length="1" - border_visible="true" - follows="left|top|right" - font="SansSerif" - height="14" - layout="topleft" - left_pad="67" - name="WL6pmHash" - top_delta="0" - width="6"> - | - </text> - <text - type="string" - length="1" - border_visible="true" - follows="left|top|right" - font="SansSerif" - height="14" - layout="topleft" - left_pad="67" - name="WL12amHash2" - top_delta="0" - width="6"> - | - </text> - - - <text - type="string" - length="1" - border_visible="true" - follows="left|top|right" - height="16" - layout="topleft" - left_delta="-300" - name="WL12am" - top="74" - width="55"> - 12am - </text> - <text - type="string" - length="1" - border_visible="true" - follows="left|top|right" - height="16" - layout="topleft" - left_pad="20" - name="WL6am" - top_delta="0" - width="55"> - 6am - </text> - <text - type="string" - length="1" - border_visible="true" - follows="left|top|right" - height="16" - layout="topleft" - left_pad="15" - name="WL12pmHash" - top_delta="0" - width="55"> - 12pm - </text> - <text - type="string" - length="1" - border_visible="true" - follows="left|top|right" - height="16" - layout="topleft" - left_pad="18" - name="WL6pm" - top_delta="0" - width="55"> - 6pm - </text> - <text - type="string" - length="1" - border_visible="true" - follows="left|top|right" - height="16" - layout="topleft" - left_pad="15" - name="WL12am2" - top_delta="0" - width="55"> - 12am - </text> - - <time - follows="left|top" - height="16" - label_width="0" - layout="topleft" - left_delta="-175" - name="WLDayTime" - top_pad="15" - value="6:00 AM" - width="75"/> - - <text - type="string" - length="1" - follows="left|top" - font="SansSerif" - height="16" - layout="topleft" - left_delta="-106" - name="WLEastAngleText" - top_pad="24" - width="200"> - East Angle - </text> - <slider - control_name="WLEastAngle" - decimal_digits="2" - follows="left|top" - height="10" - increment="0.01" - initial_value="0.0" - layout="topleft" - left_delta="10" - name="WLEastAngle" - top_pad="6" - width="200" /> - - </panel> - <panel - border="true" - bevel_style="none" - follows="left|top|right|bottom" - height="196" - label="CLOUDS" - layout="topleft" - left_delta="0" - mouse_opaque="false" - help_topic="sky_preset_clouds" - name="Clouds" - top_delta="4" - width="698"> - - <!--======== Tab Panel III. I conlumn of controls ========--> - - <text - type="string" - length="1" - follows="left|top" - font="SansSerif" - height="16" - layout="topleft" - left="40" - name="WLCloudColorText" - top="25" - width="200"> - Cloud Color - </text> - <color_swatch - can_apply_immediately="true" - follows="left|top" - height="37" - label_height="0" - layout="topleft" - left_delta="0" - name="WLCloudColor" - top_pad="6" - width="60" /> - <text - type="string" - length="1" - follows="left|top" - font="SansSerif" - height="16" - layout="topleft" - left_delta="0" - name="WLCloudColorText2" - top_pad="20" - width="200"> - Cloud XY/Density - </text> - <slider - control_name="WLCloudX" - decimal_digits="2" - follows="left|top" - height="10" - increment="0.01" - initial_value="0.5" - label="X" - layout="topleft" - left_delta="0" - top_pad="6" - name="WLCloudX" - width="200" /> - <slider - control_name="WLCloudY" - decimal_digits="2" - follows="left|top" - height="10" - increment="0.01" - initial_value="0.5" - label="Y" - layout="topleft" - left_delta="0" - top_pad="6" - name="WLCloudY" - width="200" /> - <slider - control_name="WLCloudDensity" - decimal_digits="2" - follows="left|top" - height="10" - increment="0.01" - initial_value="1.0" - label="D" - layout="topleft" - left_delta="0" - name="WLCloudDensity" - top_pad="6" - width="200" /> - - <!--======== Tab Panel III. II conlumn of controls ========--> - - <text - type="string" - length="1" - follows="left|top" - font="SansSerif" - height="16" - layout="topleft" - left_pad="55" - name="WLCloudCoverageText" - top="15" - width="200"> - Cloud Coverage - </text> - <slider - control_name="WLCloudCoverage" - decimal_digits="2" - follows="left|top" - height="10" - increment="0.01" - initial_value="0.5" - layout="topleft" - left_delta="15" - name="WLCloudCoverage" - top_pad="6" - width="200" /> - <text - type="string" - length="1" - follows="left|top" - font="SansSerif" - height="16" - layout="topleft" - left_delta="-15" - name="WLCloudScaleText" - top_pad="20" - width="200"> - Cloud Scale - </text> - <slider - control_name="WLCloudScale" - decimal_digits="2" - follows="left|top" - height="10" - increment="0.01" - initial_value="1.0" - layout="topleft" - left_delta="15" - min_val="0.01" - name="WLCloudScale" - top_pad="6" - width="200" /> - - <text - type="string" - length="1" - follows="left|top" - font="SansSerif" - height="16" - layout="topleft" - left_delta="-13" - name="WLCloudDetailText" - top_pad="20" - width="200"> - Cloud Detail (XY/Density) - </text> - <slider - control_name="WLCloudDetailX" - decimal_digits="2" - follows="left|top" - height="10" - increment="0.01" - initial_value="0.5" - label="X" - layout="topleft" - left_delta="0" - top_pad="6" - name="WLCloudDetailX" - width="200" /> - <slider - control_name="WLCloudDetailY" - decimal_digits="2" - follows="left|top" - height="10" - increment="0.01" - initial_value="0.5" - label="Y" - layout="topleft" - left_delta="0" - name="WLCloudDetailY" - top_pad="6" - width="200" /> - <slider - control_name="WLCloudDetailDensity" - decimal_digits="2" - follows="left|top" - height="10" - increment="0.01" - initial_value="1.0" - label="D" - layout="topleft" - left_delta="0" - name="WLCloudDetailDensity" - top_pad="6" - width="200" /> - - <!--======== Tab Panel III. III conlumn of controls ========--> - - <text - type="string" - length="1" - follows="left|top" - font="SansSerif" - height="16" - layout="topleft" - left_pad="55" - name="WLCloudScrollXText" - top="15" - width="150"> - Cloud Scroll X - </text> - <check_box - control_name="WLCloudLockX" - follows="left|top" - height="16" - label="Lock" - layout="topleft" - left_delta="150" - name="WLCloudLockX" - top_delta="0" - width="200" /> - <slider - control_name="WLCloudScrollX" - decimal_digits="2" - follows="left|top" - height="10" - increment="0.01" - initial_value="0.5" - layout="topleft" - left_delta="-135" - max_val="10" - min_val="-10" - name="WLCloudScrollX" - top_pad="6" - width="200" /> - <text - type="string" - length="1" - follows="left|top" - font="SansSerif" - height="16" - layout="topleft" - left_delta="-15" - name="WLCloudScrollYText" - top_pad="20" - width="150"> - Cloud Scroll Y - </text> - <check_box - control_name="WLCloudLockY" - follows="left|top" - height="16" - label="Lock" - layout="topleft" - left_delta="150" - name="WLCloudLockY" - width="200" /> - <slider - control_name="WLCloudScrollY" - decimal_digits="2" - follows="left|top" - height="10" - increment="0.01" - initial_value="0.5" - layout="topleft" - left_delta="-135" - max_val="10" - min_val="-10" - name="WLCloudScrollY" - top_pad="6" - width="200" /> - </panel> - </tab_container> -<!--======== End of Controls panel ========--> - - <check_box - follows="top|left" - height="10" - label="Make this preset my new sky setting" - layout="topleft" - left="380" - name="make_default_cb" - top_pad="30" - width="280"/> - <button - follows="bottom|right" - height="23" - label="Save" - layout="topleft" - left_pad="0" - name="save" - width="70"/> - <button - follows="bottom|right" - height="23" - label="Cancel" - layout="topleft" - left_pad="15" - name="cancel" - width="70"/> - </floater> diff --git a/indra/newview/skins/default/xui/en/floater_edit_water_preset.xml b/indra/newview/skins/default/xui/en/floater_edit_water_preset.xml deleted file mode 100644 index 905983e7fa..0000000000 --- a/indra/newview/skins/default/xui/en/floater_edit_water_preset.xml +++ /dev/null @@ -1,448 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater - legacy_header_height="18" - height="375" - layout="topleft" - name="Edit Water Preset" - help_topic="water_preset" - save_rect="true" - title="Edit Water Preset" - width="725"> - - <string name="title_new">Create a New Water Preset</string> - <string name="title_edit">Edit a Water Preset</string> - <string name="hint_new">Name your preset, adjust the controls to create it, and click "Save".</string> - <string name="hint_edit">To edit your water preset, adjust the controls and click "Save".</string> - <string name="combo_label">-Select a preset-</string> - - <text - follows="top|left|right" - height="10" - layout="topleft" - left="30" - name="hint" - top="25" - width="680"> - To edit your preset, adjust the controls then click "Save" - </text> - - <text - follows="top|left|right" - font="SansSerif" - height="10" - layout="topleft" - left="30" - name="label" - top_pad="25" - width="120"> - Preset Name: - </text> - - <combo_box - allow_text_entry="true" - follows="top|left" - layout="topleft" - left_pad="10" - max_chars="100" - name="water_preset_combo" - top_delta="-5" - width="200"/> - - <line_editor - height="20" - left_delta="0" - name="water_preset_name" - top_delta="0" - width="200" /> - - <text - follows="top|left|right" - height="40" - layout="topleft" - left_pad="10" - name="note" - top_delta="0" - width="340" - wrap="true"> - Note: if you change the name of your preset, you will be creating a new preset and the existing preset will not be changed. - </text> - - <!--======== Controls panel ========--> - <panel - border="false" - bevel_style="none" - follows="top|left" - height="230" - layout="topleft" - left="10" - name="panel_water_preset" - top="100" - width="700"> - -<!--======== I conlumn of controls ========--> - <text - follows="left|top|right" - height="10" - font="SansSerif" - layout="topleft" - left="10" - name="water_color_label" - top="5" - width="215"> - Water Fog Color - </text> - <color_swatch - can_apply_immediately="true" - follows="left|top" - height="37" - label_height="0" - layout="topleft" - left_delta="15" - name="WaterFogColor" - top_pad="8" - width="60" /> - - - <text - follows="left|top|right" - font="SansSerif" - layout="topleft" - left_delta="-15" - top_pad="10" - name="water_fog_density_label" - width="215"> - Fog Density Exponent - </text> - <slider - decimal_digits="1" - follows="left|top" - height="10" - initial_value="0" - layout="topleft" - left_delta="15" - max_val="10" - name="WaterFogDensity" - top_pad="10" - width="200"/> - - - <text - follows="left|top|right" - font="SansSerif" - layout="topleft" - left_delta="-15" - top_pad="15" - name="underwater_fog_modifier_label" - width="215"> - Underwater Fog Modifier - </text> - <slider - decimal_digits="1" - follows="left|top" - height="10" - initial_value="0" - layout="topleft" - left_delta="15" - max_val="10" - name="WaterUnderWaterFogMod" - top_pad="10" - width="200"/> - - - <text - follows="left|top|right" - font="SansSerif" - layout="topleft" - left_delta="-15" - name="BHText" - top_pad="15" - width="215"> - Big Wave Direction - </text> - <slider - control_name="WaterWave1DirX" - decimal_digits="2" - follows="left|top" - increment="0.01" - initial_value="0.7" - label="X" - layout="topleft" - max_val="4" - min_val="-4" - name="WaterWave1DirX" - top_pad="10" - width="216"/> - <slider - control_name="WaterWave1DirY" - decimal_digits="2" - follows="left|top" - increment="0.01" - initial_value="0.7" - label="Y" - layout="topleft" - max_val="4" - min_val="-4" - name="WaterWave1DirY" - top_pad="5" - width="216"/> - -<!--======== II conlumn of controls ========--> - - <text - follows="left|top|right" - font="SansSerif" - height="10" - layout="topleft" - left_pad="20" - name="BDensText" - top="5" - width="215"> - Reflection Wavelet Scale - </text> - <slider - control_name="WaterNormalScaleX" - decimal_digits="1" - follows="left|top" - initial_value="0.7" - layout="topleft" - left_delta="15" - max_val="10" - name="WaterNormalScaleX" - top_pad="10" - width="200"/> - <slider - control_name="WaterNormalScaleY" - decimal_digits="1" - follows="left|top" - initial_value="0.7" - layout="topleft" - max_val="10" - name="WaterNormalScaleY" - top_pad="6" - width="200"/> - <slider - control_name="WaterNormalScaleZ" - decimal_digits="1" - follows="left|top" - initial_value="0.7" - layout="topleft" - max_val="10" - name="WaterNormalScaleZ" - top_pad="6" - width="200"/> - - - <text - follows="left|top|right" - font="SansSerif" - layout="topleft" - left_delta="-15" - name="HDText" - top_pad="16" - width="215"> - Fresnel Scale - </text> - <slider - control_name="WaterFresnelScale" - decimal_digits="2" - follows="left|top" - height="10" - increment="0.01" - initial_value="0.7" - layout="topleft" - left_delta="15" - name="WaterFresnelScale" - top_pad="10" - width="200"/> - <text - follows="left|top|right" - font="SansSerif" - layout="topleft" - left_delta="-15" - name="FresnelOffsetText" - top_pad="15" - width="215"> - Fresnel Offset - </text> - <slider - control_name="WaterFresnelOffset" - decimal_digits="2" - follows="left" - increment="0.01" - initial_value="0.7" - layout="topleft" - left_delta="15" - name="WaterFresnelOffset" - top_pad="10" - width="200"/> - - - <text - follows="left|top|right" - font="SansSerif" - layout="topleft" - left_delta="-15" - name="BHText2" - top_pad="15" - width="215"> - Little Wave Direction - </text> - <slider - control_name="WaterWave2DirX" - decimal_digits="2" - follows="left|top" - increment="0.01" - initial_value="0.7" - label="X" - layout="topleft" - max_val="4" - min_val="-4" - name="WaterWave2DirX" - top_pad="10" - width="216" /> - <slider - control_name="WaterWave2DirY" - decimal_digits="2" - follows="left|top" - increment="0.01" - initial_value="0.7" - label="Y" - layout="topleft" - max_val="4" - min_val="-4" - name="WaterWave2DirY" - top_pad="6" - width="216" /> - -<!--======== III conlumn of contorls ========--> - - <text - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left_pad="20" - name="DensMultText" - top="5" - width="215"> - Refract Scale Above - </text> - <slider - control_name="WaterScaleAbove" - decimal_digits="2" - follows="left|top" - increment="0.01" - initial_value="0.1" - layout="topleft" - left_delta="15" - name="WaterScaleAbove" - top_pad="5" - width="200" /> - - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left_delta="-15" - name="WaterScaleBelowText" - top_pad="15" - width="215"> - Refract Scale Below - </text> - <slider - control_name="WaterScaleBelow" - decimal_digits="2" - follows="left|top" - height="10" - increment="0.01" - initial_value="0" - layout="topleft" - left_delta="15" - name="WaterScaleBelow" - top_pad="5" - width="200"/> - - <text - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left_delta="-15" - name="MaxAltText" - top_pad="15" - width="215"> - Blur Multiplier - </text> - <slider - control_name="WaterBlurMult" - follows="left|top" - height="10" - increment="0.001" - initial_value="0" - layout="topleft" - left_delta="15" - max_val="0.16" - name="WaterBlurMult" - top_pad="5" - width="200"/> - - <text - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left_delta="-15" - name="BHText3" - top_pad="15" - width="215"> - Normal Map - </text> - <texture_picker - height="80" - layout="topleft" - left_delta="15" - name="WaterNormalMap" - top_pad="5" - width="100" /> - </panel> -<!--======== End of Controls panel ========--> - - <view_border - bevel_style="none" - follows="top|left" - height="0" - layout="topleft" - left="10" - name="horiz_separator" - top_pad="5" - width="700"/> - <check_box - follows="top|left" - height="10" - label="Make this preset my new water setting" - layout="topleft" - left="275" - name="make_default_cb" - top_pad="20" - width="280"/> - <button - follows="bottom|right" - height="23" - label="Save" - layout="topleft" - left_pad="0" - name="save" - width="70"/> - <button - follows="bottom|right" - height="23" - label="Cancel" - layout="topleft" - left_pad="15" - name="cancel" - width="70"/> - - </floater> diff --git a/indra/newview/skins/default/xui/en/floater_fixedenvironment.xml b/indra/newview/skins/default/xui/en/floater_fixedenvironment.xml new file mode 100644 index 0000000000..f88618fb71 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_fixedenvironment.xml @@ -0,0 +1,159 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + can_minimize="false" + can_tear_off="false" + can_resize="true" + can_drag_on_left="false" + can_close="true" + can_dock="true" + bevel_style="in" + height="500" + layout="topleft" + name="Fixed Environment" + save_rect="true" + title="Fixed Environment" + save_dock_state="true" + save_visibility="true" + single_instance="true" + width="650"> + <layout_stack name="floater_stack" + left="5" + top="5" + right="-5" + bottom="-5" + follows="left|top|right|bottom" + orientation="vertical"> + <layout_panel name="info_panel" + auto_resize="false" + user_resize="false" + min_height="60"> + <text + follows="left|top" + top_delta="30" + left_delta="10" + width="35" + height="20" + font="SansSerif"> + Name: + </text> + <line_editor + follows="left|top" + top_delta="-2" + left_delta="45" + width="250" + name="settings_name" + max_length_chars="32" + height="20"/> + <button + height="23" + label="Load" + follows="left|top" + left_delta="260" + font="SansSerif" + top_delta="-2" + name="btn_load" + tool_tip="Load a settings from inventory" + width="96" /> + <button + height="23" + label="Import" + follows="right|top" + right="-10" + font="SansSerif" + top_delta="0" + name="btn_import" + tool_tip="Import legacy settings from disk." + width="96" /> + </layout_panel> + <layout_panel name="tab_area" + auto_resize="true" + user_resize="true" + height="11" + min_height="0" + visible="true"> + <tab_container + follows="all" + halign="left" + layout="topleft" + left="0" + name="tab_settings" + tab_position="top" + tab_width="120" + tab_padding_right="3"> + <!-- Tabs inserted here in code --> + </tab_container> + </layout_panel> + <layout_panel name="button_panel" + follows="left|top|right|bottom" + auto_resize="false" + user_resize="false" + height="40" + visible="true"> + <layout_stack + follows="bottom|left|right" + height="23" + layout="topleft" + mouse_opaque="false" + name="button_bar_ls" + left="0" + orientation="horizontal" + top="0" + width="313"> + <layout_panel + follows="bottom|left|right" + height="23" + layout="bottomleft" + left="0" + mouse_opaque="false" + name="save_btn_lp" + auto_resize="true" + width="156"> + <button + follows="bottom|left|right" + height="23" + label="Save" + left="1" + layout="topleft" + name="btn_commit" + top="0" + width="155" /> + <button + follows="bottom|right" + height="23" + name="btn_flyout" + label="" + layout="topleft" + left_pad="-20" + tab_stop="false" + top="0" + image_selected="SegmentedBtn_Right_Selected_Press" + image_unselected="SegmentedBtn_Right_Off" + image_pressed="SegmentedBtn_Right_Press" + image_pressed_selected="SegmentedBtn_Right_Selected_Press" + image_overlay="Arrow_Small_Up" + width="20"/> + </layout_panel> + <layout_panel + follows="bottom|left|right" + height="23" + layout="bottomleft" + left_pad="3" + mouse_opaque="false" + name="revert_btn_lp" + auto_resize="true" + width="147"> + <button + follows="bottom|right" + height="23" + right="-1" + label="Cancel" + layout="topleft" + name="btn_cancel" + top="0" + tool_tip="Revert to last saved version" + width="147" /> + </layout_panel> + </layout_stack> + </layout_panel> + </layout_stack> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_test_layout_stacks.xml b/indra/newview/skins/default/xui/en/floater_test_layout_stacks.xml index a04050e7eb..a3ed22f422 100644 --- a/indra/newview/skins/default/xui/en/floater_test_layout_stacks.xml +++ b/indra/newview/skins/default/xui/en/floater_test_layout_stacks.xml @@ -1,226 +1,226 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater - can_resize="true" - can_close="true" - bevel_style="in" - height="300" - layout="topleft" - min_height="40" - min_width="420" - name="Test Floater" - title="LAYOUTSTACK TESTS" - width="420"> - <layout_stack name="test_stack" - left="0" - top="0" - width="100" - height="250" - follows="left|top|bottom" - orientation="vertical"> - <layout_panel name="flex" - auto_resize="true" - user_resize="true" - bg_alpha_color="blue" - height="11" - min_height="0" - background_visible="true"> - <text follows="top|left|right" halign="center" text_color="white">flex</text> - </layout_panel> - <layout_panel name="flex" - auto_resize="true" - user_resize="true" - bg_alpha_color="blue" - height="11" - min_height="0" - visible="false" - background_visible="true"> - <text follows="top|left|right" halign="center" text_color="white">flex</text> - </layout_panel> - <layout_panel name="flex" - auto_resize="true" - user_resize="true" - bg_alpha_color="blue" - height="11" - min_height="0" - visible="true" - background_visible="true"> - <text follows="top|left|right" halign="center" text_color="white">flex</text> - </layout_panel> - <layout_panel name="flex" - auto_resize="true" - user_resize="true" - bg_alpha_color="blue" - height="11" - min_height="0" - background_visible="true"> - <text follows="top|left|right" halign="center" text_color="white">flex</text> - </layout_panel> - </layout_stack> - <layout_stack name="test_stack" - left_pad="5" - top="0" - width="100" - height="250" - follows="left|top|bottom" - orientation="vertical"> - <layout_panel name="flex" - auto_resize="true" - user_resize="true" - bg_alpha_color="blue" - height="100" - background_visible="true"> - <text follows="top|left|right" halign="center" text_color="white">flex</text> - </layout_panel> - <layout_panel name="flex" - auto_resize="true" - user_resize="true" - visible="false" - bg_alpha_color="blue" - height="100" - background_visible="true"> - <text follows="top|left|right" halign="center" text_color="white">flex</text> - </layout_panel> - <layout_panel name="fixed" - auto_resize="false" - user_resize="true" - height="50" - min_height="10" - bg_alpha_color="green" - background_visible="true"> - <text follows="top|left|right" halign="center" text_color="black">fixed</text> - </layout_panel> - <layout_panel name="fixed" + can_resize="true" + can_close="true" + bevel_style="in" + height="300" + layout="topleft" + min_height="40" + min_width="420" + name="Test Floater" + title="LAYOUTSTACK TESTS" + width="420"> + <layout_stack name="test_stack" + left="0" + top="0" + width="100" + height="250" + follows="left|top|bottom" + orientation="vertical"> + <layout_panel name="flex" + auto_resize="true" + user_resize="true" + bg_alpha_color="blue" + height="11" + min_height="0" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="white">flex</text> + </layout_panel> + <layout_panel name="flex" + auto_resize="true" + user_resize="true" + bg_alpha_color="blue" + height="11" + min_height="0" + visible="false" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="white">flex</text> + </layout_panel> + <layout_panel name="flex" + auto_resize="true" + user_resize="true" + bg_alpha_color="blue" + height="11" + min_height="0" + visible="true" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="white">flex</text> + </layout_panel> + <layout_panel name="flex" + auto_resize="true" + user_resize="true" + bg_alpha_color="blue" + height="11" + min_height="0" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="white">flex</text> + </layout_panel> + </layout_stack> + <layout_stack name="test_stack" + left_pad="5" + top="0" + width="100" + height="250" + follows="left|top|bottom" + orientation="vertical"> + <layout_panel name="flex" + auto_resize="true" + user_resize="true" + bg_alpha_color="blue" + height="100" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="white">flex</text> + </layout_panel> + <layout_panel name="flex" + auto_resize="true" + user_resize="true" + visible="false" + bg_alpha_color="blue" + height="100" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="white">flex</text> + </layout_panel> + <layout_panel name="fixed" + auto_resize="false" + user_resize="true" + height="50" + min_height="10" + bg_alpha_color="green" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="black">fixed</text> + </layout_panel> + <layout_panel name="fixed" auto_resize="false" - user_resize="true" + user_resize="true" height="50" min_height="10" bg_alpha_color="green" background_visible="true"> - <text follows="top|left|right" halign="center" text_color="black">fixed</text> - </layout_panel> - <layout_panel name="flex" - auto_resize="true" - user_resize="true" - bg_alpha_color="blue" - height="100" - background_visible="true"> - <text follows="top|left|right" halign="center" text_color="white">flex</text> - </layout_panel> - <layout_panel name="flex" - auto_resize="true" - user_resize="true" - bg_alpha_color="blue" - height="100" - background_visible="true"> - <text follows="top|left|right" halign="center" text_color="white">flex</text> - </layout_panel> - <layout_panel name="flex" - auto_resize="true" - user_resize="true" - bg_alpha_color="blue" - height="100" - background_visible="true"> - <text follows="top|left|right" halign="center" text_color="white">flex</text> - </layout_panel> - <layout_panel name="flex" - auto_resize="true" - user_resize="true" - bg_alpha_color="blue" - height="100" - visible="true" - background_visible="true"> - <text follows="top|left|right" halign="center" text_color="white">flex</text> - </layout_panel> - </layout_stack> - <layout_stack name="test_stack" - left_pad="5" - top="0" - width="100" - height="250" - follows="left|top|bottom" - orientation="vertical"> - <layout_panel name="flex" - auto_resize="true" - user_resize="true" - height="11" - bg_alpha_color="blue" - background_visible="true"> - <text follows="top|left|right" halign="center" text_color="white">flex</text> - </layout_panel> - <layout_panel name="fixed" + <text follows="top|left|right" halign="center" text_color="black">fixed</text> + </layout_panel> + <layout_panel name="flex" + auto_resize="true" + user_resize="true" + bg_alpha_color="blue" + height="100" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="white">flex</text> + </layout_panel> + <layout_panel name="flex" + auto_resize="true" + user_resize="true" + bg_alpha_color="blue" + height="100" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="white">flex</text> + </layout_panel> + <layout_panel name="flex" + auto_resize="true" + user_resize="true" + bg_alpha_color="blue" + height="100" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="white">flex</text> + </layout_panel> + <layout_panel name="flex" + auto_resize="true" + user_resize="true" + bg_alpha_color="blue" + height="100" + visible="true" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="white">flex</text> + </layout_panel> + </layout_stack> + <layout_stack name="test_stack" + left_pad="5" + top="0" + width="100" + height="250" + follows="left|top|bottom" + orientation="vertical"> + <layout_panel name="flex" + auto_resize="true" + user_resize="true" + height="11" + bg_alpha_color="blue" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="white">flex</text> + </layout_panel> + <layout_panel name="fixed" auto_resize="false" - user_resize="true" + user_resize="true" height="50" bg_alpha_color="green" background_visible="true"> - <text follows="top|left|right" halign="center" text_color="black">fixed</text> - </layout_panel> - <layout_panel name="flex" - auto_resize="true" - user_resize="true" - bg_alpha_color="blue" - height="11" - background_visible="true"> - <text follows="top|left|right" halign="center" text_color="white">flex</text> - </layout_panel> - </layout_stack> - <layout_stack name="test_stack" - left_pad="5" - top="0" - width="100" - height="250" - follows="left|top|bottom" - orientation="vertical"> - <layout_panel name="fixed" + <text follows="top|left|right" halign="center" text_color="black">fixed</text> + </layout_panel> + <layout_panel name="flex" + auto_resize="true" + user_resize="true" + bg_alpha_color="blue" + height="11" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="white">flex</text> + </layout_panel> + </layout_stack> + <layout_stack name="test_stack" + left_pad="5" + top="0" + width="100" + height="250" + follows="left|top|bottom" + orientation="vertical"> + <layout_panel name="fixed" auto_resize="false" - user_resize="true" + user_resize="true" height="50" bg_alpha_color="green" background_visible="true"> - <text follows="top|left|right" halign="center" text_color="black">fixed</text> - </layout_panel> - <layout_panel name="fixed" + <text follows="top|left|right" halign="center" text_color="black">fixed</text> + </layout_panel> + <layout_panel name="fixed" auto_resize="false" - user_resize="true" + user_resize="true" height="50" bg_alpha_color="green" background_visible="true"> - <text follows="top|left|right" halign="center" text_color="black">fixed</text> - </layout_panel> - <layout_panel name="fixed" + <text follows="top|left|right" halign="center" text_color="black">fixed</text> + </layout_panel> + <layout_panel name="fixed" auto_resize="false" - user_resize="true" + user_resize="true" height="50" bg_alpha_color="green" background_visible="true"> - <text follows="top|left|right" halign="center" text_color="black">fixed</text> - </layout_panel> - <layout_panel name="flex" - auto_resize="true" - user_resize="true" - bg_alpha_color="blue" - height="11" - min_height="0" - background_visible="true"> - <text follows="top|left|right" halign="center" text_color="white">flex</text> - </layout_panel> - <layout_panel name="flex" - auto_resize="true" - user_resize="true" - bg_alpha_color="blue" - height="11" - min_height="0" - background_visible="true"> - <text follows="top|left|right" halign="center" text_color="white">flex</text> - </layout_panel> - <layout_panel name="flex" - auto_resize="true" - user_resize="true" - bg_alpha_color="blue" - height="11" - min_height="0" - background_visible="true"> - <text follows="top|left|right" halign="center" text_color="white">flex</text> - </layout_panel> - </layout_stack> + <text follows="top|left|right" halign="center" text_color="black">fixed</text> + </layout_panel> + <layout_panel name="flex" + auto_resize="true" + user_resize="true" + bg_alpha_color="blue" + height="11" + min_height="0" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="white">flex</text> + </layout_panel> + <layout_panel name="flex" + auto_resize="true" + user_resize="true" + bg_alpha_color="blue" + height="11" + min_height="0" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="white">flex</text> + </layout_panel> + <layout_panel name="flex" + auto_resize="true" + user_resize="true" + bg_alpha_color="blue" + height="11" + min_height="0" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="white">flex</text> + </layout_panel> + </layout_stack> </floater> diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index 5b45364127..29915788f1 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -322,6 +322,35 @@ </menu_item_call> </menu> <menu + label="New Settings" + layout="topleft" + name="New Settings"> + <menu_item_call + label="New Sky" + layout="topleft" + name="New Sky"> + <menu_item_call.on_click + function="Inventory.DoCreate" + parameter="sky"/> + </menu_item_call> + <menu_item_call + label="New Water" + layout="topleft" + name="New Water"> + <menu_item_call.on_click + function="Inventory.DoCreate" + parameter="water"/> + </menu_item_call> + <menu_item_call + label="New Day Cycle" + layout="topleft" + name="New Day Cycle"> + <menu_item_call.on_click + function="Inventory.DoCreate" + parameter="daycycle"/> + </menu_item_call> + </menu> + <menu label="Use as default for" layout="topleft" name="upload_def"> diff --git a/indra/newview/skins/default/xui/en/menu_inventory_add.xml b/indra/newview/skins/default/xui/en/menu_inventory_add.xml index afeb1bf226..7c31bfe54d 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory_add.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory_add.xml @@ -245,4 +245,33 @@ parameter="eyes" /> </menu_item_call> </menu> + <menu + label="New Settings" + layout="topleft" + name="New Settings"> + <menu_item_call + label="New Sky" + layout="topleft" + name="New Sky"> + <menu_item_call.on_click + function="Inventory.DoCreate" + parameter="sky"/> + </menu_item_call> + <menu_item_call + label="New Water" + layout="topleft" + name="New Water"> + <menu_item_call.on_click + function="Inventory.DoCreate" + parameter="water"/> + </menu_item_call> + <menu_item_call + label="New Day Cycle" + layout="topleft" + name="New Day Cycle"> + <menu_item_call.on_click + function="Inventory.DoCreate" + parameter="daycycle"/> + </menu_item_call> + </menu> </menu>
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/menu_save_settings.xml b/indra/newview/skins/default/xui/en/menu_save_settings.xml new file mode 100644 index 0000000000..0d52d9b16e --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_save_settings.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + height="602" + layout="topleft" + mouse_opaque="false" + name="save_settings_menu" + width="120"> + <menu_item_call + name="save_settings" + label="Save"> + <menu_item_call.on_click + function="FlyoutCombo.Button.Action" + userdata="save"/> + </menu_item_call> + <menu_item_call + name="save_as_new_settings" + label="Save As"> + <menu_item_call.on_click + function="FlyoutCombo.Button.Action" + userdata="saveas" /> + </menu_item_call> + <menu_item_call + name="apply_local" + label="Apply Only To Myself"> + <menu_item_call.on_click + function="FlyoutCombo.Button.Action" + userdata="local" /> + </menu_item_call> + <menu_item_call + name="apply_parcel" + label="Apply Parcel"> + <menu_item_call.on_click + function="FlyoutCombo.Button.Action" + userdata="parcel" /> + </menu_item_call> + <menu_item_call + name="apply_region" + label="Apply Region"> + <menu_item_call.on_click + function="FlyoutCombo.Button.Action" + userdata="region" /> + </menu_item_call> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index dcd8f0b495..578f1c56ff 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -713,6 +713,8 @@ </menu_item_call> <menu_item_separator/> + + <!-- *LAPRAS* These menus go away. Keep till no longer needed --> <menu name="Water Presets" @@ -731,18 +733,8 @@ function="World.EnvPreset" parameter="edit_water"/> </menu_item_call> - <menu_item_call - label="Delete preset..." - name="delete_water_preset"> - <menu_item_call.on_click - function="World.EnvPreset" - parameter="delete_water"/> - <menu_item_call.on_enable - function="World.EnableEnvPreset" - parameter="delete_water"/> - </menu_item_call> </menu> - + <menu name="Sky Presets" label="Sky Presets"> @@ -760,16 +752,6 @@ function="World.EnvPreset" parameter="edit_sky"/> </menu_item_call> - <menu_item_call - label="Delete preset..." - name="delete_sky_preset"> - <menu_item_call.on_click - function="World.EnvPreset" - parameter="delete_sky"/> - <menu_item_call.on_enable - function="World.EnableEnvPreset" - parameter="delete_sky"/> - </menu_item_call> </menu> <menu @@ -789,17 +771,8 @@ function="World.EnvPreset" parameter="edit_day_cycle"/> </menu_item_call> - <menu_item_call - label="Delete preset..." - name="delete_day_preset"> - <menu_item_call.on_click - function="World.EnvPreset" - parameter="delete_day_cycle"/> - <menu_item_call.on_enable - function="World.EnableEnvPreset" - parameter="delete_day_cycle"/> - </menu_item_call> </menu> + <!-- *LAPRAS* --> </menu> diff --git a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml index 3f13cea58e..afce9f6eb5 100644 --- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml +++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml @@ -1,556 +1,556 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <!-- Side tray Outfit Edit panel --> <panel - background_visible="true" - border="false" - height="600" - follows="all" - layout="topleft" - help_topic="edit_outfit" - left="0" - min_height="350" - name="outfit_edit" - top="0" - width="320"> - <string - name="No Outfit" - value="No Outfit"/> - <string - name="unsaved_changes" - value="Unsaved Changes"/> - <string - name="now_editing" - value="Now Editing"/> - <string - name="folder_view_off" - value="Hierarchy_View_Disabled" - translate="false"/> - <string - name="folder_view_on" - value="Hierarchy_View_On" - translate="false"/> - <string - name="list_view_off" - value="List_View_Disabled" - translate="false"/> - <string - name="list_view_on" - value="List_View_On" - translate="false"/> + background_visible="true" + border="false" + height="600" + follows="all" + layout="topleft" + help_topic="edit_outfit" + left="0" + min_height="350" + name="outfit_edit" + top="0" + width="320"> + <string + name="No Outfit" + value="No Outfit"/> + <string + name="unsaved_changes" + value="Unsaved Changes"/> + <string + name="now_editing" + value="Now Editing"/> + <string + name="folder_view_off" + value="Hierarchy_View_Disabled" + translate="false"/> + <string + name="folder_view_on" + value="Hierarchy_View_On" + translate="false"/> + <string + name="list_view_off" + value="List_View_Disabled" + translate="false"/> + <string + name="list_view_on" + value="List_View_On" + translate="false"/> - <panel.string - name="not_available"> - (N\A) - </panel.string> - <panel.string - name="unknown"> - (unknown) - </panel.string> + <panel.string + name="not_available"> + (N\A) + </panel.string> + <panel.string + name="unknown"> + (unknown) + </panel.string> - <!-- Wearables filtering strings --> - <string name="Filter.All" value="All"/> - <string name="Filter.Clothes/Body" value="Clothes/Body"/> - <string name="Filter.Objects" value="Objects"/> - <string name="Filter.Clothing" value="Clothing"/> - <string name="Filter.Bodyparts" value="Body parts"/> + <!-- Wearables filtering strings --> + <string name="Filter.All" value="All"/> + <string name="Filter.Clothes/Body" value="Clothes/Body"/> + <string name="Filter.Objects" value="Objects"/> + <string name="Filter.Clothing" value="Clothing"/> + <string name="Filter.Bodyparts" value="Body parts"/> - <string - name="replace_body_part" - value="Click to replace your existing shape"/> + <string + name="replace_body_part" + value="Click to replace your existing shape"/> - <button - follows="top|left" - height="24" - image_hover_unselected="BackButton_Over" - image_pressed="BackButton_Press" - image_unselected="BackButton_Off" - layout="topleft" - name="back_btn" - left="5" - tab_stop="false" - top="1" - width="30" - use_draw_context_alpha="false" /> - <text - follows="top|left|right" - font="SansSerifHugeBold" - height="26" - layout="topleft" - left_pad="10" - name="title" - text_color="LtGray" - top="0" - value="Edit Outfit" - use_ellipses="true" - width="275" /> + <button + follows="top|left" + height="24" + image_hover_unselected="BackButton_Over" + image_pressed="BackButton_Press" + image_unselected="BackButton_Off" + layout="topleft" + name="back_btn" + left="5" + tab_stop="false" + top="1" + width="30" + use_draw_context_alpha="false" /> + <text + follows="top|left|right" + font="SansSerifHugeBold" + height="26" + layout="topleft" + left_pad="10" + name="title" + text_color="LtGray" + top="0" + value="Edit Outfit" + use_ellipses="true" + width="275" /> - <!-- "HEADER WITH ICON, STATUS TEXT AND OUTFIT NAME" --> - <panel - background_visible="true" - bg_alpha_color="DkGray2" - bevel_style="none" - follows="top|left|right" - height="40" - layout="topleft" - left="6" - name="header_panel" - top_pad="5" - width="311"> - <icon - follows="left|top" - height="31" - image_name="Shirt_Large" - left="2" - mouse_opaque="false" - name="outfit_icon" - top="2" - scale_image="true" - visible="true" - width="31" /> - <panel - bevel_style="none" - follows="top|left|right" - height="37" - layout="topleft" - left_pad="5" - name="outfit_name_and_status" - top="2" - width="270"> - <text - follows="top|left|right" - font="SansSerifSmallBold" - height="13" - layout="topleft" - name="status" - text_color="EmphasisColor" - top="2" - value="Now editing..." - use_ellipses="true" - width="245" /> - <text - follows="bottom|left|right" - font="SansSerifLargeBold" - height="18" - layout="topleft" - name="curr_outfit_name" - parse_urls="false" - text_color="LtGray" - top_pad="2" - value="[Current Outfit]" - use_ellipses="true" - width="245" /> - <loading_indicator - follows="right|top" - height="24" - layout="topleft" - right="-2" - name="edit_outfit_loading_indicator" - top="6" - width="24" /> - </panel> - </panel> + <!-- "HEADER WITH ICON, STATUS TEXT AND OUTFIT NAME" --> + <panel + background_visible="true" + bg_alpha_color="DkGray2" + bevel_style="none" + follows="top|left|right" + height="40" + layout="topleft" + left="6" + name="header_panel" + top_pad="5" + width="311"> + <icon + follows="left|top" + height="31" + image_name="Shirt_Large" + left="2" + mouse_opaque="false" + name="outfit_icon" + top="2" + scale_image="true" + visible="true" + width="31" /> + <panel + bevel_style="none" + follows="top|left|right" + height="37" + layout="topleft" + left_pad="5" + name="outfit_name_and_status" + top="2" + width="270"> + <text + follows="top|left|right" + font="SansSerifSmallBold" + height="13" + layout="topleft" + name="status" + text_color="EmphasisColor" + top="2" + value="Now editing..." + use_ellipses="true" + width="245" /> + <text + follows="bottom|left|right" + font="SansSerifLargeBold" + height="18" + layout="topleft" + name="curr_outfit_name" + parse_urls="false" + text_color="LtGray" + top_pad="2" + value="[Current Outfit]" + use_ellipses="true" + width="245" /> + <loading_indicator + follows="right|top" + height="24" + layout="topleft" + right="-2" + name="edit_outfit_loading_indicator" + top="6" + width="24" /> + </panel> + </panel> - <!-- LIST OF WEARABLES (CURRENT OUTFIT/ WEARABLES TO ADD) --> - <!-- *NOTE: border_size is used to calculate space between layout panels and also to calculate resize bar's height. + <!-- LIST OF WEARABLES (CURRENT OUTFIT/ WEARABLES TO ADD) --> + <!-- *NOTE: border_size is used to calculate space between layout panels and also to calculate resize bar's height. Required height for dragbar (icon in spec) is 10, so resizebar height should be 10 px. It is calculated as border_size + 2*UIResizeBarOverlap --> - <layout_stack - animate="true" - border_size="8" - clip="false" - default_tab_group="2" - follows="all" - height="465" - width="313" - layout="topleft" - orientation="vertical" - name="im_panels" - tab_group="1" - top_pad="5" - left="5"> - <layout_panel - layout="topleft" - height="187" - min_height="155" - name="outfit_wearables_panel" - width="313" - auto_resize="true" - user_resize="true"> + <layout_stack + animate="true" + border_size="8" + clip="false" + default_tab_group="2" + follows="all" + height="465" + width="313" + layout="topleft" + orientation="vertical" + name="im_panels" + tab_group="1" + top_pad="5" + left="5"> + <layout_panel + layout="topleft" + height="187" + min_height="155" + name="outfit_wearables_panel" + width="313" + auto_resize="true" + user_resize="true"> - <layout_stack - animate="true" - border_size="0" - follows="all" - height="185" - width="313" - orientation="vertical" - layout="topleft" - name="filter_panels" - top="0" - left="0"> - <layout_panel - auto_resize="true" - background_visible="false" - layout="topleft" - height="154" - name="add_button_and_combobox" - width="311" - visible="true"> + <layout_stack + animate="true" + border_size="0" + follows="all" + height="185" + width="313" + orientation="vertical" + layout="topleft" + name="filter_panels" + top="0" + left="0"> + <layout_panel + auto_resize="true" + background_visible="false" + layout="topleft" + height="154" + name="add_button_and_combobox" + width="311" + visible="true"> - <!-- List containing items from the COF and Base outfit --> - <panel - background_visible="false" - class="cof_wearables" - filename="panel_cof_wearables.xml" - follows="all" - height="129" - layout="topleft" - left="1" - name="cof_wearables_list" - top="0" - width="311" /> + <!-- List containing items from the COF and Base outfit --> + <panel + background_visible="false" + class="cof_wearables" + filename="panel_cof_wearables.xml" + follows="all" + height="129" + layout="topleft" + left="1" + name="cof_wearables_list" + top="0" + width="311" /> - <button - follows="left|bottom" - height="22" - image_pressed="PushButton_Press" - image_pressed_selected="PushButton_Selected_Press" - image_selected="PushButton_Selected_Press" - is_toggle="true" - label="Add More..." - layout="topleft" - left="2" - name="show_add_wearables_btn" - top_pad="2" - tool_tip="Open/Close" - width="125" /> + <button + follows="left|bottom" + height="22" + image_pressed="PushButton_Press" + image_pressed_selected="PushButton_Selected_Press" + image_selected="PushButton_Selected_Press" + is_toggle="true" + label="Add More..." + layout="topleft" + left="2" + name="show_add_wearables_btn" + top_pad="2" + tool_tip="Open/Close" + width="125" /> - <combo_box - follows="left|right|bottom" - height="22" - layout="topleft" - left_pad="5" - name="list_view_filter_combobox" - top_delta="0" - visible="false" - width="152"/> - <combo_box - follows="left|right|bottom" - height="22" - layout="topleft" - left_delta="0" - name="folder_view_filter_combobox" - top_delta="0" - visible="false" - width="152"/> + <combo_box + follows="left|right|bottom" + height="22" + layout="topleft" + left_pad="5" + name="list_view_filter_combobox" + top_delta="0" + visible="false" + width="152"/> + <combo_box + follows="left|right|bottom" + height="22" + layout="topleft" + left_delta="0" + name="folder_view_filter_combobox" + top_delta="0" + visible="false" + width="152"/> - <button - follows="bottom|right" - height="22" - image_overlay="Search_Icon" - image_pressed="PushButton_Press" - image_pressed_selected="PushButton_Selected_Press" - image_selected="PushButton_Selected_Press" - is_toggle="true" - layout="topleft" - name="filter_button" - right="-5" - top_delta="0" - visible="false" - width="20" /> - </layout_panel> + <button + follows="bottom|right" + height="22" + image_overlay="Search_Icon" + image_pressed="PushButton_Press" + image_pressed_selected="PushButton_Selected_Press" + image_selected="PushButton_Selected_Press" + is_toggle="true" + layout="topleft" + name="filter_button" + right="-5" + top_delta="0" + visible="false" + width="20" /> + </layout_panel> - <layout_panel - auto_resize="false" - background_visible="true" - bg_alpha_color="DkGray2" - height="30" - name="filter_panel" - width="311" - visible="false"> + <layout_panel + auto_resize="false" + background_visible="true" + bg_alpha_color="DkGray2" + height="30" + name="filter_panel" + width="311" + visible="false"> - <filter_editor - background_image="TextField_Search_Off" - enabled="true" - follows="left|right|top" - label="Filter Inventory Wearables" - layout="topleft" - left="5" - width="290" - height="25" - name="look_item_filter" - search_button_visible="true" - text_color="black" - visible="true"/> + <filter_editor + background_image="TextField_Search_Off" + enabled="true" + follows="left|right|top" + label="Filter Inventory Wearables" + layout="topleft" + left="5" + width="290" + height="25" + name="look_item_filter" + search_button_visible="true" + text_color="black" + visible="true"/> - </layout_panel> - </layout_stack> - </layout_panel> + </layout_panel> + </layout_stack> + </layout_panel> - <layout_panel background_visible="false" - bg_alpha_color="DkGray2" - auto_resize="true" - height="450" - min_height="80" - name="add_wearables_panel" - width="313" - tab_group="2" - user_resize="true" - visible="false"> + <layout_panel background_visible="false" + bg_alpha_color="DkGray2" + auto_resize="true" + height="450" + min_height="80" + name="add_wearables_panel" + width="313" + tab_group="2" + user_resize="true" + visible="false"> - <!-- this icon represent dragbar between layout panels. + <!-- this icon represent dragbar between layout panels. This is a workaround implemented in EXT-7255 becouse of an issue with layout stack (EXT-7471) --> - <icon follows="left|top|right" - height="10" - image_name="Dragbar" - left="0" - top_pad="-9" - width="313" /> - <inventory_panel allow_multi_select="true" - background_visible="false" - border="false" - follows="left|top|right|bottom" - height="418" - layout="topleft" - left="0" - mouse_opaque="false" - name="folder_view" - top_pad="0" - width="313" - visible="false"/> - <panel name="filtered_wearables_panel" - background_opaque="true" - background_visible="false" - layout="topleft" - follows="left|top|right|bottom" - border="false" - height="418" - left="0" - mouse_opaque="false" - width="310" - top_delta="0" - visible="true"> - <wearable_items_list color="0.107 0.107 0.107 1" - name="list_view" - allow_select="true" - layout="topleft" - follows="all" - multi_select="true" - width="313" - height="418" - left="0" - top="0"/> - </panel> - <button follows="bottom|left" - height="22" - left="2" - label="Wear Item" - layout="topleft" - name="plus_btn" - top_pad="5" - width="130" /> - </layout_panel> - </layout_stack> + <icon follows="left|top|right" + height="10" + image_name="Dragbar" + left="0" + top_pad="-9" + width="313" /> + <inventory_panel allow_multi_select="true" + background_visible="false" + border="false" + follows="left|top|right|bottom" + height="418" + layout="topleft" + left="0" + mouse_opaque="false" + name="folder_view" + top_pad="0" + width="313" + visible="false"/> + <panel name="filtered_wearables_panel" + background_opaque="true" + background_visible="false" + layout="topleft" + follows="left|top|right|bottom" + border="false" + height="418" + left="0" + mouse_opaque="false" + width="310" + top_delta="0" + visible="true"> + <wearable_items_list color="0.107 0.107 0.107 1" + name="list_view" + allow_select="true" + layout="topleft" + follows="all" + multi_select="true" + width="313" + height="418" + left="0" + top="0"/> + </panel> + <button follows="bottom|left" + height="22" + left="2" + label="Wear Item" + layout="topleft" + name="plus_btn" + top_pad="5" + width="130" /> + </layout_panel> + </layout_stack> - <!-- BUTTON BAR --> - <panel - background_visible="true" - bevel_style="none" - follows="bottom|left|right" - height="27" - layout="topleft" - left="5" - name="no_add_wearables_button_bar" - top_pad="0" - width="313"> - <menu_button - follows="bottom|left" - height="25" - image_hover_unselected="Toolbar_Left_Over" - image_overlay="OptionsMenu_Off" - image_selected="Toolbar_Left_Selected" - image_unselected="Toolbar_Left_Off" - layout="topleft" - left="0" - name="gear_menu_btn" - top="1" - width="31" /> - <icon - follows="bottom|left|right" - height="25" - image_name="Toolbar_Middle_Off" - layout="topleft" - left_pad="1" - name="dummy_right_icon" - width="250" /> - <button - follows="bottom|right" - height="25" - image_hover_unselected="Toolbar_Right_Over" - image_overlay="Shop" - image_selected="Toolbar_Right_Selected" - image_unselected="Toolbar_Right_Off" - layout="topleft" - left_pad="1" - name="shop_btn_1" - top="1" - tool_tip="Visit the SL Marketplace. You can also select something you are wearing, then click here to see more things like it" - width="31" /> - </panel> + <!-- BUTTON BAR --> + <panel + background_visible="true" + bevel_style="none" + follows="bottom|left|right" + height="27" + layout="topleft" + left="5" + name="no_add_wearables_button_bar" + top_pad="0" + width="313"> + <menu_button + follows="bottom|left" + height="25" + image_hover_unselected="Toolbar_Left_Over" + image_overlay="OptionsMenu_Off" + image_selected="Toolbar_Left_Selected" + image_unselected="Toolbar_Left_Off" + layout="topleft" + left="0" + name="gear_menu_btn" + top="1" + width="31" /> + <icon + follows="bottom|left|right" + height="25" + image_name="Toolbar_Middle_Off" + layout="topleft" + left_pad="1" + name="dummy_right_icon" + width="250" /> + <button + follows="bottom|right" + height="25" + image_hover_unselected="Toolbar_Right_Over" + image_overlay="Shop" + image_selected="Toolbar_Right_Selected" + image_unselected="Toolbar_Right_Off" + layout="topleft" + left_pad="1" + name="shop_btn_1" + top="1" + tool_tip="Visit the SL Marketplace. You can also select something you are wearing, then click here to see more things like it" + width="31" /> + </panel> - <!-- BUTTON BAR - WEARABLES ADDING MODE --> - <panel - background_visible="true" - bevel_style="none" - follows="left|right|bottom" - height="27" - layout="topleft" - left="5" - name="add_wearables_button_bar" - top_delta="0" - visible="false" - width="313"> - <menu_button - follows="bottom|left" - height="25" - image_hover_unselected="Toolbar_Left_Over" - image_overlay="OptionsMenu_Off" - image_selected="Toolbar_Left_Selected" - image_unselected="Toolbar_Left_Off" - layout="topleft" - left="0" - name="wearables_gear_menu_btn" - top="1" - width="31" /> - <button - follows="bottom|left" - height="25" - image_hover_unselected="Toolbar_Middle_Over" - image_overlay="Hierarchy_View_Disabled" - image_selected="Toolbar_Middle_Selected" - image_unselected="Toolbar_Middle_Off" - is_toggle="true" - layout="topleft" - left_pad="1" - name="folder_view_btn" - top="1" - width="31" /> - <button - follows="bottom|left" - height="25" - image_hover_unselected="Toolbar_Middle_Over" - image_overlay="List_View_On" - image_selected="Toolbar_Middle_Selected" - image_unselected="Toolbar_Middle_Off" - is_toggle="true" - layout="topleft" - left_pad="1" - name="list_view_btn" - top="1" - width="31" /> - <icon - follows="bottom|left|right" - height="25" - image_name="Toolbar_Middle_Off" - layout="topleft" - left_pad="1" - name="dummy_right_icon" - width="186" > - </icon> - <button - follows="bottom|right" - height="25" - image_hover_unselected="Toolbar_Right_Over" - image_overlay="Shop" - image_selected="Toolbar_Right_Selected" - image_unselected="Toolbar_Right_Off" - layout="topleft" - left_pad="1" - name="shop_btn_2" - top="1" - tool_tip="Visit the SL Marketplace. You can also select something you are wearing, then click here to see more things like it" - width="31" /> - </panel> + <!-- BUTTON BAR - WEARABLES ADDING MODE --> + <panel + background_visible="true" + bevel_style="none" + follows="left|right|bottom" + height="27" + layout="topleft" + left="5" + name="add_wearables_button_bar" + top_delta="0" + visible="false" + width="313"> + <menu_button + follows="bottom|left" + height="25" + image_hover_unselected="Toolbar_Left_Over" + image_overlay="OptionsMenu_Off" + image_selected="Toolbar_Left_Selected" + image_unselected="Toolbar_Left_Off" + layout="topleft" + left="0" + name="wearables_gear_menu_btn" + top="1" + width="31" /> + <button + follows="bottom|left" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="Hierarchy_View_Disabled" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + is_toggle="true" + layout="topleft" + left_pad="1" + name="folder_view_btn" + top="1" + width="31" /> + <button + follows="bottom|left" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="List_View_On" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + is_toggle="true" + layout="topleft" + left_pad="1" + name="list_view_btn" + top="1" + width="31" /> + <icon + follows="bottom|left|right" + height="25" + image_name="Toolbar_Middle_Off" + layout="topleft" + left_pad="1" + name="dummy_right_icon" + width="186" > + </icon> + <button + follows="bottom|right" + height="25" + image_hover_unselected="Toolbar_Right_Over" + image_overlay="Shop" + image_selected="Toolbar_Right_Selected" + image_unselected="Toolbar_Right_Off" + layout="topleft" + left_pad="1" + name="shop_btn_2" + top="1" + tool_tip="Visit the SL Marketplace. You can also select something you are wearing, then click here to see more things like it" + width="31" /> + </panel> - <!-- SAVE AND REVERT BUTTONS --> - <panel - follows="left|right|bottom" - height="30" - layout="topleft" - left="4" - top_pad="2" - name="save_revert_button_bar" - width="300"> - <layout_stack - follows="bottom|left|right" - height="23" - layout="topleft" - mouse_opaque="false" - name="button_bar_ls" - left="0" - orientation="horizontal" - top="0" - width="313"> - <layout_panel - follows="bottom|left|right" - height="23" - layout="bottomleft" - left="0" - mouse_opaque="false" - name="save_btn_lp" - auto_resize="true" - width="156"> - <button - follows="bottom|left|right" - height="23" - label="Save" - left="1" - layout="topleft" - name="save_btn" - top="0" - width="155" /> - <button - follows="bottom|right" - height="23" - name="save_flyout_btn" - label="" - layout="topleft" - left_pad="-20" - tab_stop="false" - top="0" - image_selected="SegmentedBtn_Right_Selected_Press" - image_unselected="SegmentedBtn_Right_Off" - image_pressed="SegmentedBtn_Right_Press" - image_pressed_selected="SegmentedBtn_Right_Selected_Press" - image_overlay="Arrow_Small_Up" - width="20"/> - </layout_panel> - <layout_panel - follows="bottom|left|right" - height="23" - layout="bottomleft" - left_pad="3" - mouse_opaque="false" - name="revert_btn_lp" - auto_resize="true" - width="147"> - <button - follows="bottom|left|right" - height="23" - left="0" - label="Undo Changes" - layout="topleft" - name="revert_btn" - top="0" - tool_tip="Revert to last saved version" - width="147" /> - </layout_panel> - </layout_stack> - </panel> + <!-- SAVE AND REVERT BUTTONS --> + <panel + follows="left|right|bottom" + height="30" + layout="topleft" + left="4" + top_pad="2" + name="save_revert_button_bar" + width="300"> + <layout_stack + follows="bottom|left|right" + height="23" + layout="topleft" + mouse_opaque="false" + name="button_bar_ls" + left="0" + orientation="horizontal" + top="0" + width="313"> + <layout_panel + follows="bottom|left|right" + height="23" + layout="bottomleft" + left="0" + mouse_opaque="false" + name="save_btn_lp" + auto_resize="true" + width="156"> + <button + follows="bottom|left|right" + height="23" + label="Save" + left="1" + layout="topleft" + name="save_btn" + top="0" + width="155" /> + <button + follows="bottom|right" + height="23" + name="save_flyout_btn" + label="" + layout="topleft" + left_pad="-20" + tab_stop="false" + top="0" + image_selected="SegmentedBtn_Right_Selected_Press" + image_unselected="SegmentedBtn_Right_Off" + image_pressed="SegmentedBtn_Right_Press" + image_pressed_selected="SegmentedBtn_Right_Selected_Press" + image_overlay="Arrow_Small_Up" + width="20"/> + </layout_panel> + <layout_panel + follows="bottom|left|right" + height="23" + layout="bottomleft" + left_pad="3" + mouse_opaque="false" + name="revert_btn_lp" + auto_resize="true" + width="147"> + <button + follows="bottom|left|right" + height="23" + left="0" + label="Undo Changes" + layout="topleft" + name="revert_btn" + top="0" + tool_tip="Revert to last saved version" + width="147" /> + </layout_panel> + </layout_stack> + </panel> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_region_environment.xml b/indra/newview/skins/default/xui/en/panel_region_environment.xml index aa38c49fae..21518338ff 100644 --- a/indra/newview/skins/default/xui/en/panel_region_environment.xml +++ b/indra/newview/skins/default/xui/en/panel_region_environment.xml @@ -1,149 +1,180 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel - border="true" - follows="top|left" - height="300" - label="Environment" - layout="topleft" - help_topic="panel_region_environment_tab" - name="panel_env_info" - width="530"> - <text - name="water_settings_title" - follows="top|left" - height="30" - layout="topleft" - left="50" - top_pad="20" - width="430" - wrap="true"> - Select the Water and Sky/Day Cycle Settings you would like all visitors to your region to see. More info - </text> - <view_border - bevel_style="none" - follows="top|left" - height="237" - layout="topleft" - left="50" - name="border" - top="60" - width="430"/> - <radio_group - follows="top|left" - height="45" - layout="topleft" - left_delta="10" - name="region_settings_radio_group" - top_delta="20" - width="200"> - <radio_item - label="Use Second Life default" - layout="topleft" - name="use_sl_default_settings"/> - <radio_item - label="Use the following settings" - layout="topleft" - name="use_my_settings" - top_pad="20"/> - </radio_group> - <panel - follows="top|left" - height="150" - layout="topleft" - left="50" - name="user_environment_settings" - top_pad="20" - width="430"> - <text - name="water_settings_title" + border="true" follows="top|left" - height="16" + height="300" + label="Environment" layout="topleft" - left="50" - top_pad="0" - width="160"> - Water Setting - </text> - <combo_box - follows="top|left" - left_pad="2" - name="water_settings_preset_combo" - top_delta="-7" - width="200"> - <combo_box.item - label="-Select a preset-" - name="item0"/> - </combo_box> - <text - name="sky_dayc_settings_title" - follows="top|left" - height="16" - layout="topleft" - left="50" - top_pad="30" - width="100"> - Sky / Day Cycle - </text> - <radio_group - layout="topleft" - left_delta="50" - name="sky_dayc_settings_radio_group" - top_pad="10" - height="50" - width="110"> - <radio_item - layout="topleft" - label="Fixed sky" - name="my_sky_settings"/> - <radio_item - layout="topleft" - label="Day cycle" - name="my_dayc_settings" - top_pad="25"/> - </radio_group> - <combo_box - follows="top|left" - left_pad="2" - name="sky_settings_preset_combo" - top_delta="-7" - width="200"> - <combo_box.item - label="-Select a preset-" - name="item0"/> - </combo_box> - <combo_box - follows="top|left" - name="dayc_settings_preset_combo" - top_delta="36" - width="200"> - <combo_box.item - label="-Select a preset-" - name="item0"/> - </combo_box> - </panel> - <button - follows="left|top" - height="23" - label="Apply" - layout="topleft" - right="-160" - name="apply_btn" - top_pad="10" - width="100" /> - <button - follows="left|top" - height="23" - label="Cancel" - layout="topleft" - left_pad="10" - name="cancel_btn" - width="100" /> - <loading_indicator - height="23" - left="50" - name="progress_indicator" - top_delta="0" - visible="false" - width="23" /> + help_topic="panel_region_environment_tab" + name="panel_env_info" + width="530"> + <layout_stack + left_offset="0" + top_offset="0" + width="420" + height="250" + follows="left|right|top|bottom" + orientation="vertical"> + <layout_panel + auto_resize="false" + user_resize="true" + bg_alpha_color="red" + min_height="130" + background_visible="false"> + <layout_stack + left_offset="5" + top_offset="5" + right_offset="-5" + follows="left|right|top|bottom" + orientation="horizontal"> + <layout_panel + border="true" + bevel_style="in" + auto_resize="false" + user_resize="false" + width="160" + background_visible="true"> + <text follows="top|left" + halign="left" + text_color="white">Environment Source</text> + <radio_group + follows="top|left" + height="45" + layout="topleft" + left_delta="10" + name="environment_select_radio_group" + bottom_delta="50" + max_width="200" + width="200"> + <radio_item + label="Default Environment" + layout="topleft" + name="use_default_setting" + height="20"/> + <radio_item + label="Custom Environment" + layout="topleft" + height="20" + name="use_custom_setting"/> + </radio_group> + <button + follows="top|right" + height="23" + label="Edit Custom" + right_offset="30" + bottom_offset="30" + width="100" + name="edit_btn"/> + + </layout_panel> + <layout_panel + border="true" + bevel_style="in" + auto_resize="false" + user_resize="true" + height="11" + width="220" + background_visible="true"> + <text follows="top|left|right" + halign="left" + text_color="white">Day Settings</text> + <text + type="string" + length="1" + follows="left|top" + height="12" + layout="topleft" + left_delta="10" + top_pad="10" + width="200"> + Day Length (hours) + </text> + <slider + can_edit_text="true" + control_name="DayLengthSLD" + decimal_digits="1" + follows="left|top" + height="20" + increment="0.5" + initial_value="4" + layout="topleft" + left_delta="0" + top_pad="6" + name="day_length_sld" + min_val="4" + max_val="178" + width="200" /> + <text + type="string" + length="1" + follows="left|top" + height="12" + layout="topleft" + left_delta="0" + top_pad="10" + width="200"> + Day Offset (hours) + </text> + <slider + can_edit_text="true" + control_name="DayOffsetSLD" + decimal_digits="1" + follows="left|top" + height="20" + increment="0.5" + initial_value="-8" + layout="topleft" + left_delta="0" + top_pad="6" + name="day_offset_sld" + min_val="-12" + max_val="12" + width="200" /> + + </layout_panel> + <layout_panel name="flex" + auto_resize="true" + user_resize="true" + visible="false" + bg_alpha_color="blue" + height="100" + background_visible="true"> + </layout_panel> + </layout_stack> + </layout_panel> + <layout_panel + auto_resize="true" + user_resize="true" + height="21" + min_height="0" + background_visible="false"> + <check_box + control_name="may_override_chk" + height="16" + label="Parcel Owners May Override" + layout="topleft" + left_offset="10" + top_offset="10" + name="allow_override_chk" + width="200" /> + <button + follows="top|left" + height="23" + label="Apply" + left_offset="160" + top_offset="60" + name="apply_btn" + width="100" /> + <button + follows="top|left" + height="23" + label="Cancel" + layout="topleft" + left_pad="10" + name="cancel_btn" + width="100" /> + + </layout_panel> + </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml b/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml new file mode 100644 index 0000000000..8317196e75 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml @@ -0,0 +1,247 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + border="true" + follows="all" + label="Atmosphere & Lighting" + layout="topleft" + left="0" + name="panel_settings_sky_atmos" + top="0"> + <layout_stack + follows="all" + layout="topleft" + left="5" + top="5" + right="-5" + bottom="-5" + orientation="vertical"> + <layout_panel + border="true" + bevel_style="in" + auto_resize="false" + user_resize="false" + visible="true" + height="75"> + + <text + follows="left|top" + height="10" + layout="topleft" + left_delta="15" + top_pad="15" + width="80"> + Ambient Color: + </text> + <color_swatch + can_apply_immediately="true" + follows="left|top" + height="37" + label_height="0" + layout="topleft" + left_delta="0" + name="ambient_light" + top_pad="5" + width="60" /> + <text + follows="left" + height="10" + layout="topleft" + left_delta="90" + top_delta="-15" + width="80"> + Blue Horizon: + </text> + <color_swatch + can_apply_immediately="true" + follows="left|top" + height="37" + label_height="0" + layout="topleft" + left_delta="0" + name="blue_horizon" + top_pad="5" + width="60" /> + <text + follows="left" + height="10" + layout="topleft" + left_delta="90" + top_delta="-15" + width="80"> + Blue Density: + </text> + <color_swatch + can_apply_immediately="true" + follows="left|top" + height="37" + label_height="0" + layout="topleft" + left_delta="0" + name="blue_density" + top_pad="5" + width="60" /> + </layout_panel> + <layout_panel + border="true" + bevel_style="in" + auto_resize="true" + user_resize="true" + visible="true"> + <layout_stack name="atmosphere1" + left="5" + top="5" + right="-5" + bottom="-5" + follows="left|top|right|bottom" + orientation="hoizontal"> + <layout_panel + border="false" + bevel_style="in" + auto_resize="true" + user_resize="true" + visible="true" + min_width="225"> + <text + follows="left|top" + height="10" + layout="topleft" + left_delta="15" + top_pad="15" + width="80"> + Haze Horizon: + </text> + <slider + decimal_digits="2" + follows="left|top" + height="10" + increment="0.01" + initial_value="0" + layout="topleft" + left_delta="5" + min_val="0" + max_val="1" + name="haze_horizon" + top_delta="20" + width="200"/> + <text + follows="left|top" + height="10" + layout="topleft" + left_delta="-5" + top_delta="25" + width="80"> + Haze Density: + </text> + <slider + decimal_digits="2" + follows="left|top" + height="10" + increment="0.01" + initial_value="0" + layout="topleft" + left_delta="5" + min_val="0" + max_val="1" + name="haze_density" + top_delta="20" + width="200"/> + <text + follows="left|top" + height="10" + layout="topleft" + left_delta="-5" + top_delta="25" + width="80"> + Scene Gamma: + </text> + <slider + decimal_digits="2" + follows="left|top" + height="10" + increment="0.01" + initial_value="0" + layout="topleft" + left_delta="5" + max_val="10" + name="scene_gamma" + top_delta="20" + width="207"/> + </layout_panel> + <layout_panel + border="false" + bevel_style="in" + auto_resize="true" + user_resize="true" + visible="true" + min_width="225"> + <text + follows="left|top" + height="10" + layout="topleft" + left_delta="15" + top_pad="15" + width="200"> + Density Multiplier: + </text> + <slider + decimal_digits="2" + follows="left|top" + height="10" + increment="0.01" + initial_value="0" + layout="topleft" + left_delta="5" + min_val="0" + max_val="0.9" + name="density_multip" + top_delta="20" + width="200"/> + <text + follows="left|top" + height="10" + layout="topleft" + left_delta="-5" + top_delta="25" + width="200"> + Distance Multiplier: + </text> + <slider + decimal_digits="2" + follows="left|top" + height="10" + increment="0.01" + initial_value="0" + layout="topleft" + left_delta="5" + min_val="0" + max_val="100" + name="distance_multip" + top_delta="20" + width="214"/> + <text + follows="left|top" + height="10" + layout="topleft" + left_delta="-5" + top_delta="25" + width="200"> + Maximum Altitude: + </text> + <slider + decimal_digits="1" + follows="left|top" + height="10" + increment="0.01" + initial_value="0" + layout="topleft" + left_delta="5" + min_val="0" + max_val="4000" + name="max_alt" + top_delta="20" + width="214"/> + </layout_panel> + </layout_stack> + </layout_panel> + </layout_stack> +</panel>
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/panel_settings_sky_clouds.xml b/indra/newview/skins/default/xui/en/panel_settings_sky_clouds.xml new file mode 100644 index 0000000000..9bd931f9fb --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_settings_sky_clouds.xml @@ -0,0 +1,266 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + border="true" + follows="all" + label="Clouds" + layout="topleft" + left="0" + help_topic="land_general_tab" + name="panel_settings_sky_clouds" + top="0"> + <layout_stack + follows="all" + layout="topleft" + left="5" + top="5" + right="-5" + bottom="-5" + orientation="hoizontal"> + <layout_panel + border="true" + bevel_style="in" + auto_resize="true" + user_resize="true" + visible="true" + height="75"> + <text + follows="left|top" + height="10" + layout="topleft" + left_delta="15" + top_pad="15" + width="80"> + Cloud Color: + </text> + <color_swatch + can_apply_immediately="true" + follows="left|top" + height="37" + label_height="0" + layout="topleft" + left_delta="0" + name="cloud_color" + top_pad="5" + width="60" /> + <text + follows="left|top" + height="10" + layout="topleft" + left_delta="0" + top_delta="47" + width="200"> + Cloud Coverage: + </text> + <slider + decimal_digits="2" + follows="left|top" + height="10" + increment="0.01" + initial_value="0" + layout="topleft" + left_delta="5" + min_val="0" + max_val="1" + name="cloud_coverage" + top_delta="20" + width="214"/> + <text + follows="left|top" + height="10" + layout="topleft" + left_delta="-5" + top_delta="25" + width="200"> + Cloud Scale: + </text> + <slider + decimal_digits="2" + follows="left|top" + height="10" + increment="0.01" + initial_value="0" + layout="topleft" + left_delta="5" + min_val="0" + max_val="1" + name="cloud_scale" + top_delta="20" + width="214"/> + <text + follows="left|top" + height="10" + layout="topleft" + left_delta="-5" + top_delta="25" + width="200"> + Cloud Scroll: + </text> + <panel + follows="left|top" + border="true" + bg_alpha_color="red" + background_visible="true" + width="100" + height="100" + left_delta="5" + top_delta="21"> + <text> + placeholder + </text> + <slider + decimal_digits="1" + follows="left|top" + increment="0.01" + initial_value="0" + layout="topleft" + label="X:" + left_delta="10" + max_val="10" + min_val="-10" + name="cloud_scroll_x" + top_pad="5" + width="100"/> + <slider + decimal_digits="1" + follows="left|top" + increment="0.01" + initial_value="0" + layout="topleft" + label="Y:" + left_delta="0" + max_val="10" + min_val="-10" + name="cloud_scroll_y" + top_pad="5" + orientation="vertical" + height="70"/> + </panel> + <text + follows="left|top" + height="10" + layout="topleft" + left_delta="115" + top_delta="-20" + width="200"> + Cloud Image: + </text> + <texture_picker + height="100" + layout="topleft" + left_delta="5" + name="cloud_map" + top_pad="10" + width="100"/> + </layout_panel> + <layout_panel + border="true" + bevel_style="in" + auto_resize="true" + user_resize="true" + visible="true" + height="75"> + <text + follows="left|top" + height="10" + layout="topleft" + left_delta="15" + top_pad="15" + width="200"> + Cloud Density: + </text> + <slider + label="X" + decimal_digits="2" + follows="left|top" + height="10" + increment="0.01" + initial_value="0" + layout="topleft" + left_delta="5" + min_val="0" + max_val="1" + name="cloud_density_x" + top_delta="20" + width="200"/> + <slider + label="Y" + decimal_digits="2" + follows="left|top" + height="10" + increment="0.01" + initial_value="0" + layout="topleft" + left_delta="0" + min_val="0" + max_val="1" + name="cloud_density_y" + top_delta="20" + width="200"/> + <slider + label="D" + decimal_digits="2" + follows="left|top" + height="10" + increment="0.01" + initial_value="0" + layout="topleft" + left_delta="0" + min_val="0" + max_val="1" + name="cloud_density_d" + top_delta="20" + width="200"/> + <text + follows="left|top" + height="10" + layout="topleft" + left_delta="-5" + top_delta="35" + width="200"> + Cloud Detail: + </text> + <slider + label="X" + decimal_digits="2" + follows="left|top" + height="10" + increment="0.01" + initial_value="0" + layout="topleft" + left_delta="5" + min_val="0" + max_val="1" + name="cloud_detail_x" + top_delta="20" + width="200"/> + <slider + label="Y" + decimal_digits="2" + follows="left|top" + height="10" + increment="0.01" + initial_value="0" + layout="topleft" + left_delta="0" + min_val="0" + max_val="1" + name="cloud_detail_y" + top_delta="20" + width="200"/> + <slider + label="D" + decimal_digits="2" + follows="left|top" + height="10" + increment="0.01" + initial_value="0" + layout="topleft" + left_delta="0" + min_val="0" + max_val="1" + name="cloud_detail_d" + top_delta="20" + width="200"/> + </layout_panel> + </layout_stack> +</panel>
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/panel_settings_sky_sunmoon.xml b/indra/newview/skins/default/xui/en/panel_settings_sky_sunmoon.xml new file mode 100644 index 0000000000..9e5df59daf --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_settings_sky_sunmoon.xml @@ -0,0 +1,238 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + border="true" + follows="all" + label="Sun & Moon" + layout="topleft" + left="0" + name="panel_settings_sky_hbodies" + top="0"> + <layout_stack + follows="all" + layout="topleft" + left="5" + top="5" + right="-5" + bottom="-5" + orientation="hoizontal"> + <layout_panel + border="true" + bevel_style="in" + auto_resize="true" + user_resize="true" + visible="true" + height="75"> + <text + follows="left|top" + height="10" + layout="topleft" + left_delta="15" + top_pad="15" + width="80"> + Sun Color: + </text> + <color_swatch + can_apply_immediately="true" + follows="left|top" + height="37" + label_height="0" + layout="topleft" + left_delta="0" + name="sun_moon_color" + top_pad="5" + width="60" /> + <text + follows="left|top" + height="10" + layout="topleft" + left_delta="0" + top_delta="57" + width="200"> + Glow Focus: + </text> + <slider + decimal_digits="2" + follows="left|top" + height="10" + increment="0.01" + initial_value="0" + layout="topleft" + left_delta="5" + min_val="0" + max_val="0.5" + name="glow_focus" + top_delta="20" + width="200"/> + <text + follows="left|top" + height="10" + layout="topleft" + left_delta="-5" + top_delta="20" + width="200"> + Glow Size: + </text> + <slider + decimal_digits="2" + follows="left|top" + height="10" + increment="0.01" + initial_value="0" + layout="topleft" + left_delta="5" + min_val="1" + max_val="1.99" + name="glow_size" + top_delta="20" + width="200"/> + <text + follows="left|top" + height="10" + layout="topleft" + left_delta="-5" + top_delta="30" + width="200"> + Star Brightness: + </text> + <slider + decimal_digits="2" + follows="left|top" + height="10" + increment="0.01" + initial_value="0" + layout="topleft" + left_delta="5" + min_val="0" + max_val="2" + name="star_brightness" + top_delta="20" + width="200"/> + </layout_panel> + <layout_panel + border="false" + bevel_style="in" + auto_resize="true" + user_resize="true" + visible="true" + height="75"> + <layout_stack + left="5" + top="5" + right="-5" + bottom="-5" + follows="left|top|right|bottom" + orientation="vertical"> + <layout_panel + border="true" + bevel_style="in" + auto_resize="true" + user_resize="true" + visible="true" + height="75"> + <text + follows="left|top" + height="10" + layout="topleft" + left_delta="15" + top_pad="15" + font="SansSerifBold" + width="80"> + Sun + </text> + <text + follows="left|top" + height="10" + layout="topleft" + left_delta="10" + top_delta="30" + width="100"> + Position: + </text> + <joystick_quat + follows="left|top" + height="78" + layout="topleft" + left_delta="0" + top_delta="20" + name="sun_rotation" + quadrant="left" + sound_flags="3" + visible="true" + tool_tip="Move sun in sky" + width="78" /> <!-- Should be 126x126 --> + <text + follows="left|top" + height="10" + layout="topleft" + left_delta="100" + top_delta="-20" + width="200"> + Image: + </text> + <texture_picker + height="100" + layout="topleft" + left_delta="5" + name="sun_image" + top_pad="10" + width="100"/> + </layout_panel> + <layout_panel + border="true" + bevel_style="in" + auto_resize="true" + user_resize="true" + visible="true" + height="75"> + <text + follows="left|top" + height="10" + layout="topleft" + left_delta="15" + top_pad="15" + font="SansSerifBold" + width="80"> + Moon + </text> + <text + follows="left|top" + height="10" + layout="topleft" + left_delta="10" + top_delta="30" + width="100"> + Position: + </text> + <joystick_quat + follows="left|top" + height="78" + layout="topleft" + left_delta="0" + top_delta="20" + name="moon_rotation" + quadrant="left" + sound_flags="3" + visible="true" + tool_tip="Move sun in sky" + width="78" /> <!-- Should be 126x126 --> + <text + follows="left|top" + height="10" + layout="topleft" + left_delta="100" + top_delta="-20" + width="200"> + Image: + </text> + <texture_picker + height="100" + layout="topleft" + left_delta="5" + name="moon_image" + top_pad="10" + width="100"/> + </layout_panel> + </layout_stack> + </layout_panel> + </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_settings_water.xml b/indra/newview/skins/default/xui/en/panel_settings_water.xml new file mode 100644 index 0000000000..59184b0f95 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_settings_water.xml @@ -0,0 +1,409 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + border="true" + follows="all" + label="Water" + layout="topleft" + left="0" + help_topic="land_general_tab" + name="panel_settings_water" + top="0"> + <layout_stack name="water_stack1" + follows="all" + layout="topleft" + left="5" + top="5" + right="-5" + bottom="-5" + orientation="vertical"> + <layout_panel + border="true" + bevel_style="in" + auto_resize="false" + user_resize="false" + visible="true" + height="105"> + <text + follows="left|top" + height="20" + font="SansSerif" + layout="topleft" + left="5" + top="5" + width="215"> + Water Fog: + </text> + <text + follows="left|top" + height="10" + layout="left|top" + left_delta="15" + top_delta="0" + width="60"> + Color: + </text> + <color_swatch + can_apply_immediately="true" + follows="left|top" + height="37" + label_height="0" + layout="topleft" + left_delta="0" + name="water_fog_color" + top_pad="5" + width="60" /> + <text + follows="left|top" + height="10" + top_delta="-15" + left_delta="80" + width="200"> + Density Exponent: + </text> + <slider + decimal_digits="1" + follows="left|top|right" + height="10" + increment="0.01" + initial_value="0" + layout="top" + left_delta="15" + max_val="10" + name="water_fog_density" + top_delta="5" + width="200"/> + <text + follows="left|top" + height="10" + top_delta="25" + left_delta="-15" + width="200"> + Underwater Modifier:</text> + <slider + decimal_digits="1" + follows="left|top|right" + height="10" + increment="0.01" + initial_value="0" + layout="top" + left_delta="15" + max_val="10" + name="water_underwater_mod" + top_delta="20" + width="200"/> + </layout_panel> + <layout_panel + auto_resize="true" + user_resize="true" + visible="true"> + <layout_stack name="water_stack2" + left="5" + top="5" + right="-5" + bottom="-5" + follows="left|top|right|bottom" + orientation="horizontal"> + <layout_panel + border="true" + bevel_style="in" + auto_resize="true" + user_resize="true" + visible="true" + min_width="375" + width="50"> + <text + follows="left|top" + height="20" + font="SansSerif" + layout="topleft" + left="5" + top="5" + width="215"> + Waves: + </text> + <text + follows="left|top|right" + height="16" + layout="topleft" + left="15" + top_delta="20" + width="215"> + Normal Map + </text> + <texture_picker + height="100" + layout="topleft" + left_delta="0" + name="water_normal_map" + top_pad="5" + width="100"/> + + <text + follows="left|top" + height="16" + layout="topleft" + top_delta="-20" + left_delta="120"> + Large Wave Speed + </text> + <panel + follows="left|top" + border="true" + bg_alpha_color="red" + background_visible="true" + width="100" + height="100" + left_delta="0" + top_delta="21"> + <text> + placeholder + </text> + <slider + decimal_digits="1" + follows="left|top" + increment="0.01" + initial_value="0" + layout="topleft" + label="X:" + left_delta="10" + max_val="4" + min_val="-4" + name="water_wave1_x" + top_pad="5" + width="100"/> + <slider + decimal_digits="1" + follows="left|top" + increment="0.01" + initial_value="0" + layout="topleft" + label="Y:" + left_delta="0" + max_val="4" + min_val="-4" + name="water_wave1_y" + top_pad="5" + orientation="vertical" + height="70"/> + </panel> + <text + follows="left|top" + height="16" + layout="topleft" + top_delta="-20" + left_delta="120"> + Small Wave Speed + </text> + <panel + follows="left|top" + border="true" + bg_alpha_color="red" + background_visible="true" + width="100" + height="100" + left_delta="0" + top_delta="21" + > + <text> + placeholder + </text> + <slider + decimal_digits="1" + follows="left|top" + increment="0.01" + initial_value="0" + layout="topleft" + label="X:" + left_delta="10" + max_val="4" + min_val="-4" + name="water_wave2_x" + top_pad="5" + width="100"/> + <slider + decimal_digits="1" + follows="left|top" + increment="0.01" + initial_value="0" + layout="topleft" + label="Y:" + left_delta="0" + max_val="4" + min_val="-4" + name="water_wave2_y" + top_pad="5" + orientation="vertical" + height="70"/> + </panel> + + <text + follows="left|top|right" + height="16" + layout="topleft" + left="15" + top_pad="10" + width="215"> + Reflection Wavelet Scale + </text> + <slider + decimal_digits="1" + follows="left|top" + increment="0.01" + initial_value="0.7" + layout="topleft" + label="X:" + left_delta="10" + max_val="10" + name="water_normal_scale_x" + top_pad="5" + width="150"/> + <slider + decimal_digits="1" + follows="left|top" + increment="0.01" + initial_value="0.7" + layout="topleft" + max_val="10" + name="water_normal_scale_y" + top_pad="6" + label="Y:" + width="150"/> + <slider + decimal_digits="1" + follows="left|top" + increment="0.01" + initial_value="0.7" + layout="topleft" + max_val="10" + name="water_normal_scale_z" + top_pad="6" + label="Z:" + width="150"/> + + <text + follows="left|top|right" + height="16" + layout="topleft" + left_delta="175" + top_delta="-52" + width="150"> + Fresnel Scale: + </text> + <slider + decimal_digits="2" + follows="left|top" + height="10" + increment="0.01" + initial_value="0.7" + layout="topleft" + left_delta="5" + name="water_fresnel_scale" + top_pad="5" + width="150"/> + <text + follows="left|top|right" + layout="topleft" + left_delta="-5" + name="FresnelOffsetText" + top_pad="10" + width="150"> + Fresnel Offset: + </text> + <slider + decimal_digits="2" + follows="left|top|right" + increment="0.01" + initial_value="0.7" + layout="topleft" + left_delta="5" + name="water_fresnel_offset" + top_pad="5" + width="150"/> + </layout_panel> + <layout_panel + border="true" + bevel_style="in" + auto_resize="true" + user_resize="true" + width="50" + visible="true"> + <text + follows="left|top" + height="20" + font="SansSerif" + layout="topleft" + left="5" + top="5" + width="215"> + Refraction And Blur: + </text> + <text + follows="left|top|right" + height="16" + layout="topleft" + top_delta="25" + left_delta="5" + width="215"> + Refraction Scale (Above) + </text> + <slider + control_name="water_scale_above" + decimal_digits="2" + follows="left|top" + increment="0.01" + initial_value="0.1" + layout="topleft" + left_delta="5" + name="water_scale_above" + top_pad="5" + width="200" /> + <text + type="string" + length="1" + follows="left|top|right" + height="16" + layout="topleft" + left_delta="-5" + top_pad="15" + width="215"> + Refraction Scale (Below) + </text> + <slider + control_name="water_scale_below" + decimal_digits="2" + follows="left|top" + height="10" + increment="0.01" + initial_value="0" + layout="topleft" + left_delta="5" + name="water_scale_below" + top_pad="5" + width="200"/> + <text + follows="left|top|right" + font="SansSerif" + height="16" + layout="topleft" + left_delta="-5" + top_pad="5" + width="215"> + Blur Multiplier + </text> + <slider + control_name="water_blur_multip" + follows="left|top" + height="10" + increment="0.001" + initial_value="0" + layout="topleft" + left_delta="5" + max_val="0.16" + name="water_blur_multip" + top_pad="5" + width="200"/> + </layout_panel> + </layout_stack> + </layout_panel> + </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 0a220e68fd..7b6c580e7f 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -3849,6 +3849,11 @@ Abuse Report</string> <string name="Female - Shrug">Female - Shrug</string> <string name="Female - Stick tougue out">Female - Stick tongue out</string> <string name="Female - Wow">Female - Wow</string> + <!-- settings --> + <string name="New Daycycle">New Daycycle</string> + <string name="New Water">New Water</string> + <string name="New Sky">New Sky</string> + <string name="/bow">/bow</string> <string name="/clap">/clap</string> diff --git a/indra/newview/skins/default/xui/en/widgets/joystick_quat.xml b/indra/newview/skins/default/xui/en/widgets/joystick_quat.xml new file mode 100644 index 0000000000..a190da3909 --- /dev/null +++ b/indra/newview/skins/default/xui/en/widgets/joystick_quat.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<joystick_rotate + image_selected="Cam_Rotate_In" + image_unselected="Cam_Rotate_Out" + scale_image="false" + mouse_opaque="false" + held_down_delay.seconds="0"/> diff --git a/indra/newview/skins/default/xui/en/widgets/joystick_rotate.xml b/indra/newview/skins/default/xui/en/widgets/joystick_rotate.xml index a190da3909..cbf721b346 100644 --- a/indra/newview/skins/default/xui/en/widgets/joystick_rotate.xml +++ b/indra/newview/skins/default/xui/en/widgets/joystick_rotate.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<joystick_rotate +<joystick_quat image_selected="Cam_Rotate_In" image_unselected="Cam_Rotate_Out" - scale_image="false" + scale_image="true" mouse_opaque="false" held_down_delay.seconds="0"/> diff --git a/indra/newview/skins/default/xui/es/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/es/floater_delete_env_preset.xml deleted file mode 100644 index 5e7df8530e..0000000000 --- a/indra/newview/skins/default/xui/es/floater_delete_env_preset.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<floater name="Delete Env Preset" title="ELIMINAR EL ENV PREDEFINIDO"> - <string name="title_water"> - Eliminar el agua predefinida - </string> - <string name="title_sky"> - Eliminar cielo predefinido - </string> - <string name="title_day_cycle"> - Eliminar ciclo del día - </string> - <string name="label_water"> - Predefinido: - </string> - <string name="label_sky"> - Predefinido: - </string> - <string name="label_day_cycle"> - Ciclo del día: - </string> - <string name="msg_confirm_deletion"> - ¿Estás seguro de que quieres eliminar el valor predefinido seleccionado? - </string> - <string name="msg_sky_is_referenced"> - No se puede quitar un valor predefinido al que se hace referencia en otro u otros ciclos del día. - </string> - <string name="combo_label"> - -Selecciona un valor predefinido- - </string> - <text name="label"> - Predefinido: - </text> - <button label="Borrar" name="delete"/> - <button label="Cancelar" name="cancel"/> -</floater> diff --git a/indra/newview/skins/default/xui/es/menu_viewer.xml b/indra/newview/skins/default/xui/es/menu_viewer.xml index dec4a5082d..a9bdb8ef7d 100644 --- a/indra/newview/skins/default/xui/es/menu_viewer.xml +++ b/indra/newview/skins/default/xui/es/menu_viewer.xml @@ -89,17 +89,14 @@ <menu label="Agua predefinida" name="Water Presets"> <menu_item_call label="Nuevo predefinido..." name="new_water_preset"/> <menu_item_call label="Editar predefinido..." name="edit_water_preset"/> - <menu_item_call label="Eliminar predefinido..." name="delete_water_preset"/> </menu> <menu label="Cielos predefinidos" name="Sky Presets"> <menu_item_call label="Nuevo predefinido..." name="new_sky_preset"/> <menu_item_call label="Editar predefinido..." name="edit_sky_preset"/> - <menu_item_call label="Eliminar predefinido..." name="delete_sky_preset"/> </menu> <menu label="Días predefinidos" name="Day Presets"> <menu_item_call label="Nuevo predefinido..." name="new_day_preset"/> <menu_item_call label="Editar predefinido..." name="edit_day_preset"/> - <menu_item_call label="Eliminar predefinido..." name="delete_day_preset"/> </menu> </menu> </menu> diff --git a/indra/newview/skins/default/xui/fr/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/fr/floater_delete_env_preset.xml deleted file mode 100644 index 035bdbe5f3..0000000000 --- a/indra/newview/skins/default/xui/fr/floater_delete_env_preset.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<floater name="Delete Env Preset" title="SUPPRIMER PRÉRÉGLAGE ENV."> - <string name="title_water"> - Supprimer un préréglage de l'eau - </string> - <string name="title_sky"> - Supprimer un préréglage du ciel - </string> - <string name="title_day_cycle"> - Supprimer un cycle du jour - </string> - <string name="label_water"> - Préréglage : - </string> - <string name="label_sky"> - Préréglage : - </string> - <string name="label_day_cycle"> - Cycle du jour : - </string> - <string name="msg_confirm_deletion"> - Voulez-vous vraiment supprimer le préréglage sélectionné ? - </string> - <string name="msg_sky_is_referenced"> - Impossible de supprimer un préréglage référencé dans un ou plusieurs cycles du jour. - </string> - <string name="combo_label"> - -Effectuer une sélection- - </string> - <text name="label"> - Préréglage : - </text> - <button label="Supprimer" name="delete"/> - <button label="Annuler" name="cancel"/> -</floater> diff --git a/indra/newview/skins/default/xui/fr/menu_viewer.xml b/indra/newview/skins/default/xui/fr/menu_viewer.xml index 06697ae13a..c9aa74d08b 100644 --- a/indra/newview/skins/default/xui/fr/menu_viewer.xml +++ b/indra/newview/skins/default/xui/fr/menu_viewer.xml @@ -89,17 +89,14 @@ <menu label="Préréglages de l'eau" name="Water Presets"> <menu_item_call label="Nouveau préréglage..." name="new_water_preset"/> <menu_item_call label="Modifier un préréglage..." name="edit_water_preset"/> - <menu_item_call label="Supprimer un préréglage..." name="delete_water_preset"/> </menu> <menu label="Préréglages du ciel" name="Sky Presets"> <menu_item_call label="Nouveau préréglage..." name="new_sky_preset"/> <menu_item_call label="Modifier un préréglage..." name="edit_sky_preset"/> - <menu_item_call label="Supprimer un préréglage..." name="delete_sky_preset"/> </menu> <menu label="Préréglages du jour" name="Day Presets"> <menu_item_call label="Nouveau préréglage..." name="new_day_preset"/> <menu_item_call label="Modifier un préréglage..." name="edit_day_preset"/> - <menu_item_call label="Supprimer un préréglage..." name="delete_day_preset"/> </menu> </menu> </menu> diff --git a/indra/newview/skins/default/xui/it/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/it/floater_delete_env_preset.xml deleted file mode 100644 index 71071825af..0000000000 --- a/indra/newview/skins/default/xui/it/floater_delete_env_preset.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<floater name="Delete Env Preset" title="CANCELLA PREDEFINITO AMB"> - <string name="title_water"> - Cancella valore predefinito acqua - </string> - <string name="title_sky"> - Cancella valore predefinito cielo - </string> - <string name="title_day_cycle"> - Cancella ciclo giornata - </string> - <string name="label_water"> - Valori predefiniti: - </string> - <string name="label_sky"> - Valori predefiniti: - </string> - <string name="label_day_cycle"> - Ciclo giornata: - </string> - <string name="msg_confirm_deletion"> - Sei sicuro di volere eliminare il valore predefinito selezionato? - </string> - <string name="msg_sky_is_referenced"> - Impossibile rimuovere un valore predefinito che viene utilizzato in uno o più cicli di giornata. - </string> - <string name="combo_label"> - -Seleziona un valore predefinito- - </string> - <text name="label"> - Valori predefiniti: - </text> - <button label="Elimina" name="delete"/> - <button label="Annulla" name="cancel"/> -</floater> diff --git a/indra/newview/skins/default/xui/it/menu_viewer.xml b/indra/newview/skins/default/xui/it/menu_viewer.xml index 1f6a09deaa..7ca60d5c62 100644 --- a/indra/newview/skins/default/xui/it/menu_viewer.xml +++ b/indra/newview/skins/default/xui/it/menu_viewer.xml @@ -89,17 +89,14 @@ <menu label="Valori predefiniti acqua" name="Water Presets"> <menu_item_call label="Nuovo valore predefinito..." name="new_water_preset"/> <menu_item_call label="Modifica valore predefinito..." name="edit_water_preset"/> - <menu_item_call label="Cancella valore predefinito..." name="delete_water_preset"/> </menu> <menu label="Valori predefiniti cielo" name="Sky Presets"> <menu_item_call label="Nuovo valore predefinito..." name="new_sky_preset"/> <menu_item_call label="Modifica valore predefinito..." name="edit_sky_preset"/> - <menu_item_call label="Cancella valore predefinito..." name="delete_sky_preset"/> </menu> <menu label="Valori predefiniti giorno" name="Day Presets"> <menu_item_call label="Nuovo valore predefinito..." name="new_day_preset"/> <menu_item_call label="Modifica valore predefinito..." name="edit_day_preset"/> - <menu_item_call label="Cancella valore predefinito..." name="delete_day_preset"/> </menu> </menu> </menu> diff --git a/indra/newview/skins/default/xui/ja/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/ja/floater_delete_env_preset.xml deleted file mode 100644 index eb39d1b336..0000000000 --- a/indra/newview/skins/default/xui/ja/floater_delete_env_preset.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<floater name="Delete Env Preset" title="環境の事前設定を削除"> - <string name="title_water"> - 水の事前設定を削除 - </string> - <string name="title_sky"> - 空の事前設定を削除 - </string> - <string name="title_day_cycle"> - デイサイクルを削除 - </string> - <string name="label_water"> - 事前設定: - </string> - <string name="label_sky"> - 事前設定: - </string> - <string name="label_day_cycle"> - デイサイクル: - </string> - <string name="msg_confirm_deletion"> - 選択された事前設定を削除しますか? - </string> - <string name="msg_sky_is_referenced"> - デイサイクルの参照先として使われている事前設定は削除できません。 - </string> - <string name="combo_label"> - - 事前設定を選択 - - </string> - <text name="label"> - 事前設定: - </text> - <button label="削除" name="delete"/> - <button label="取り消し" name="cancel"/> -</floater> diff --git a/indra/newview/skins/default/xui/ja/menu_viewer.xml b/indra/newview/skins/default/xui/ja/menu_viewer.xml index 18a0bfce49..4948f5a824 100644 --- a/indra/newview/skins/default/xui/ja/menu_viewer.xml +++ b/indra/newview/skins/default/xui/ja/menu_viewer.xml @@ -89,17 +89,14 @@ <menu label="水の事前設定" name="Water Presets"> <menu_item_call label="新しい事前設定..." name="new_water_preset"/> <menu_item_call label="事前設定を編集..." name="edit_water_preset"/> - <menu_item_call label="事前設定を削除..." name="delete_water_preset"/> </menu> <menu label="空の事前設定" name="Sky Presets"> <menu_item_call label="新しい事前設定..." name="new_sky_preset"/> <menu_item_call label="事前設定を編集..." name="edit_sky_preset"/> - <menu_item_call label="事前設定を削除..." name="delete_sky_preset"/> </menu> <menu label="デイの事前設定" name="Day Presets"> <menu_item_call label="新しい事前設定..." name="new_day_preset"/> <menu_item_call label="事前設定を編集..." name="edit_day_preset"/> - <menu_item_call label="事前設定を削除..." name="delete_day_preset"/> </menu> </menu> </menu> diff --git a/indra/newview/skins/default/xui/pl/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/pl/floater_delete_env_preset.xml deleted file mode 100644 index fc750715c6..0000000000 --- a/indra/newview/skins/default/xui/pl/floater_delete_env_preset.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<floater name="Delete Env Preset" title="USUŃ UST. OTOCZENIA"> - <string name="title_water"> - Usuń Ustawienie wody - </string> - <string name="title_sky"> - Usuń Ustawienie nieba - </string> - <string name="title_day_cycle"> - Usuń cykl dnia - </string> - <string name="label_water"> - Wybierz: - </string> - <string name="label_sky"> - Wybierz: - </string> - <string name="label_day_cycle"> - Cykl dnia: - </string> - <string name="msg_confirm_deletion"> - Masz absolutną pewność, że chcesz usunąć wybrane Ustawienie? - </string> - <string name="msg_sky_is_referenced"> - Nie można usunąć Ustawienia odwołującego się do jakiegoś cyklu dnia. - </string> - <string name="combo_label"> - -Wybierz Ustawienie- - </string> - <text name="label"> - Wybierz: - </text> - <button label="Usuń" name="delete" /> - <button label="Anuluj" name="cancel" /> -</floater> diff --git a/indra/newview/skins/default/xui/pl/menu_viewer.xml b/indra/newview/skins/default/xui/pl/menu_viewer.xml index e6ad1faee6..5190723660 100644 --- a/indra/newview/skins/default/xui/pl/menu_viewer.xml +++ b/indra/newview/skins/default/xui/pl/menu_viewer.xml @@ -84,17 +84,14 @@ <menu name="Water Presets" label="Ustawienia wody"> <menu_item_call label="Nowe Ustawienie..." name="new_water_preset" /> <menu_item_call label="Edytuj Ustawienie..." name="edit_water_preset" /> - <menu_item_call label="Usuń Ustawienie..." name="delete_water_preset" /> </menu> <menu name="Sky Presets" label="Ustawienia nieba"> <menu_item_call label="Nowe Ustawienie..." name="new_sky_preset" /> <menu_item_call label="Edytuj Ustawienie..." name="edit_sky_preset" /> - <menu_item_call label="Usuń Ustawienie..." name="delete_sky_preset" /> </menu> <menu name="Day Presets" label="Ustawienia pory dnia"> <menu_item_call label="Nowe Ustawienie..." name="new_day_preset" /> <menu_item_call label="Edytuj Ustawienie..." name="edit_day_preset" /> - <menu_item_call label="Usuń Ustawienie..." name="delete_day_preset" /> </menu> </menu> </menu> diff --git a/indra/newview/skins/default/xui/pt/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/pt/floater_delete_env_preset.xml deleted file mode 100644 index a8b5d8f67d..0000000000 --- a/indra/newview/skins/default/xui/pt/floater_delete_env_preset.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<floater name="Delete Env Preset" title="EXCLUIR CONF AMBIENTE"> - <string name="title_water"> - Excluir pré-configuração da água - </string> - <string name="title_sky"> - Excluir pré-configuração de céu - </string> - <string name="title_day_cycle"> - Excluir pré-configuração dos dias - </string> - <string name="label_water"> - Pré-configuração: - </string> - <string name="label_sky"> - Pré-configuração: - </string> - <string name="label_day_cycle"> - Ciclo dia: - </string> - <string name="msg_confirm_deletion"> - Tem certeza de que quer excluir esta pré-configuração? - </string> - <string name="msg_sky_is_referenced"> - Impossível excluir pré-configuração utilizada por um ou mais ciclos de dia . - </string> - <string name="combo_label"> - -Selecione uma pré-configuração- - </string> - <text name="label"> - Pré-configuração: - </text> - <button label="Excluir" name="delete"/> - <button label="Cancelar" name="cancel"/> -</floater> diff --git a/indra/newview/skins/default/xui/pt/menu_viewer.xml b/indra/newview/skins/default/xui/pt/menu_viewer.xml index a5d0c33969..0798c2be5a 100644 --- a/indra/newview/skins/default/xui/pt/menu_viewer.xml +++ b/indra/newview/skins/default/xui/pt/menu_viewer.xml @@ -89,17 +89,14 @@ <menu label="Predefinições da água" name="Water Presets"> <menu_item_call label="Nova predefinição..." name="new_water_preset"/> <menu_item_call label="Editar predefinição..." name="edit_water_preset"/> - <menu_item_call label="Excluir predefinição..." name="delete_water_preset"/> </menu> <menu label="Predefinições de céu" name="Sky Presets"> <menu_item_call label="Nova predefinição..." name="new_sky_preset"/> <menu_item_call label="Editar predefinição..." name="edit_sky_preset"/> - <menu_item_call label="Excluir predefinição..." name="delete_sky_preset"/> </menu> <menu label="Predefinições do dia" name="Day Presets"> <menu_item_call label="Nova predefinição..." name="new_day_preset"/> <menu_item_call label="Editar predefinição..." name="edit_day_preset"/> - <menu_item_call label="Excluir predefinição..." name="delete_day_preset"/> </menu> </menu> </menu> diff --git a/indra/newview/skins/default/xui/ru/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/ru/floater_delete_env_preset.xml deleted file mode 100644 index 3303a4f4c1..0000000000 --- a/indra/newview/skins/default/xui/ru/floater_delete_env_preset.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<floater name="Delete Env Preset" title="УДАЛЕНИЕ НАСТРОЙКИ СРЕДЫ"> - <string name="title_water"> - Удалить настройку воды - </string> - <string name="title_sky"> - Удалить настройку неба - </string> - <string name="title_day_cycle"> - Удалить суточный цикл - </string> - <string name="label_water"> - Настройка: - </string> - <string name="label_sky"> - Настройка: - </string> - <string name="label_day_cycle"> - Суточный цикл: - </string> - <string name="msg_confirm_deletion"> - Действительно удалить выбранную настройку? - </string> - <string name="msg_sky_is_referenced"> - Нельзя удалить настройку, которая используется в суточных циклах. - </string> - <string name="combo_label"> - -Выбор настройки- - </string> - <text name="label"> - Настройка: - </text> - <button label="Удалить" name="delete"/> - <button label="Отмена" name="cancel"/> -</floater> diff --git a/indra/newview/skins/default/xui/ru/menu_viewer.xml b/indra/newview/skins/default/xui/ru/menu_viewer.xml index 8a13197657..014b825f72 100644 --- a/indra/newview/skins/default/xui/ru/menu_viewer.xml +++ b/indra/newview/skins/default/xui/ru/menu_viewer.xml @@ -87,17 +87,14 @@ <menu label="Настройки воды" name="Water Presets"> <menu_item_call label="Создать настройку..." name="new_water_preset"/> <menu_item_call label="Изменить настройку..." name="edit_water_preset"/> - <menu_item_call label="Удалить настройку..." name="delete_water_preset"/> </menu> <menu label="Настройки неба" name="Sky Presets"> <menu_item_call label="Создать настройку..." name="new_sky_preset"/> <menu_item_call label="Изменить настройку..." name="edit_sky_preset"/> - <menu_item_call label="Удалить настройку..." name="delete_sky_preset"/> </menu> <menu label="Суточные настройки" name="Day Presets"> <menu_item_call label="Создать настройку..." name="new_day_preset"/> <menu_item_call label="Изменить настройку..." name="edit_day_preset"/> - <menu_item_call label="Удалить настройку..." name="delete_day_preset"/> </menu> </menu> </menu> diff --git a/indra/newview/skins/default/xui/tr/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/tr/floater_delete_env_preset.xml deleted file mode 100644 index 915770f727..0000000000 --- a/indra/newview/skins/default/xui/tr/floater_delete_env_preset.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<floater name="Delete Env Preset" title="ORTAM ÖN AYARINI SİL"> - <string name="title_water"> - Su Ön Ayarını Sil - </string> - <string name="title_sky"> - Gökyüzü Ön Ayarını Sil - </string> - <string name="title_day_cycle"> - Gün Döngüsünü Sil - </string> - <string name="label_water"> - Ön Ayar: - </string> - <string name="label_sky"> - Ön Ayar: - </string> - <string name="label_day_cycle"> - Gün döngüsü: - </string> - <string name="msg_confirm_deletion"> - Seçili ön ayarı silmek istediğinize emin misiniz? - </string> - <string name="msg_sky_is_referenced"> - Bazı gün döngüleri tarafından başvurulan bir ön ayar kaldırılamaz. - </string> - <string name="combo_label"> - -Bir ön ayar seçin- - </string> - <text name="label"> - Ön Ayar: - </text> - <button label="Sil" name="delete"/> - <button label="İptal" name="cancel"/> -</floater> diff --git a/indra/newview/skins/default/xui/tr/menu_viewer.xml b/indra/newview/skins/default/xui/tr/menu_viewer.xml index bc2f08db42..ad5b5380e4 100644 --- a/indra/newview/skins/default/xui/tr/menu_viewer.xml +++ b/indra/newview/skins/default/xui/tr/menu_viewer.xml @@ -87,17 +87,14 @@ <menu label="Su Ön Ayarları" name="Water Presets"> <menu_item_call label="Yeni ön ayar..." name="new_water_preset"/> <menu_item_call label="Ön ayarı düzenle..." name="edit_water_preset"/> - <menu_item_call label="Ön ayarı sil..." name="delete_water_preset"/> </menu> <menu label="Gökyüzü Ön Ayarları" name="Sky Presets"> <menu_item_call label="Yeni ön ayar..." name="new_sky_preset"/> <menu_item_call label="Ön ayarı düzenle..." name="edit_sky_preset"/> - <menu_item_call label="Ön ayarı sil..." name="delete_sky_preset"/> </menu> <menu label="Gün Ön Ayarları" name="Day Presets"> <menu_item_call label="Yeni ön ayar..." name="new_day_preset"/> <menu_item_call label="Ön ayarı düzenle..." name="edit_day_preset"/> - <menu_item_call label="Ön ayarı sil..." name="delete_day_preset"/> </menu> </menu> </menu> diff --git a/indra/newview/skins/default/xui/zh/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/zh/floater_delete_env_preset.xml deleted file mode 100644 index 4aafb31952..0000000000 --- a/indra/newview/skins/default/xui/zh/floater_delete_env_preset.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<floater name="Delete Env Preset" title="刪除環境自訂配置"> - <string name="title_water"> - 刪除水的自訂配置 - </string> - <string name="title_sky"> - 刪除天空自訂配置 - </string> - <string name="title_day_cycle"> - 刪除日循環 - </string> - <string name="label_water"> - 自訂配置: - </string> - <string name="label_sky"> - 自訂配置: - </string> - <string name="label_day_cycle"> - 日循環: - </string> - <string name="msg_confirm_deletion"> - 確定要刪除所選自訂配置? - </string> - <string name="msg_sky_is_referenced"> - 無法刪除日循環有所指涉的自訂配置。 - </string> - <string name="combo_label"> - -選擇一個自訂配置- - </string> - <text name="label"> - 自訂配置: - </text> - <button label="刪除" name="delete"/> - <button label="取消" name="cancel"/> -</floater> diff --git a/indra/newview/skins/default/xui/zh/menu_viewer.xml b/indra/newview/skins/default/xui/zh/menu_viewer.xml index 58deb5a139..e4507d9214 100644 --- a/indra/newview/skins/default/xui/zh/menu_viewer.xml +++ b/indra/newview/skins/default/xui/zh/menu_viewer.xml @@ -87,17 +87,14 @@ <menu label="水的自訂配置" name="Water Presets"> <menu_item_call label="新的自訂配置…" name="new_water_preset"/> <menu_item_call label="編輯自訂配置…" name="edit_water_preset"/> - <menu_item_call label="刪除自訂配置…" name="delete_water_preset"/> </menu> <menu label="天空自訂配置" name="Sky Presets"> <menu_item_call label="新的自訂配置…" name="new_sky_preset"/> <menu_item_call label="編輯自訂配置…" name="edit_sky_preset"/> - <menu_item_call label="刪除自訂配置…" name="delete_sky_preset"/> </menu> <menu label="日的自訂配置" name="Day Presets"> <menu_item_call label="新的自訂配置…" name="new_day_preset"/> <menu_item_call label="編輯自訂配置…" name="edit_day_preset"/> - <menu_item_call label="刪除自訂配置…" name="delete_day_preset"/> </menu> </menu> </menu> 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<LLSD>{}(data_s1) == boost::hash<LLSD>{}(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<LLSD>{}(data_r1) != boost::hash<LLSD>{}(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<LLSD>{}(data_a1) == boost::hash<LLSD>{}(data_a2)); + + data_a2.append(LLSDArray(1)(2)); + + ensure("hash: changing the array changes the hash.", boost::hash<LLSD>{}(data_a1) != boost::hash<LLSD>{}(data_a2)); + + data_a1.append(LLSDArray(1)(2)); + ensure("hash: identical arrays produce identical results with nested arrays", boost::hash<LLSD>{}(data_a1) == boost::hash<LLSD>{}(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<LLSD>{}(data_m1) == boost::hash<LLSD>{}(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<LLSD>{}(data_m1) != boost::hash<LLSD>{}(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<LLSD>{}(data_m1) != boost::hash<LLSD>{}(data_m4)); + + } + } + } |