summaryrefslogtreecommitdiff
path: root/indra/llinventory/llsettingssky.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llinventory/llsettingssky.cpp')
-rw-r--r--indra/llinventory/llsettingssky.cpp1775
1 files changed, 1775 insertions, 0 deletions
diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp
new file mode 100644
index 0000000000..9bbeb00efe
--- /dev/null
+++ b/indra/llinventory/llsettingssky.cpp
@@ -0,0 +1,1775 @@
+/**
+* @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 LLUUID IMG_BLOOM1("3c59f7fe-9dc8-47f9-8aaf-a9dd1fbc3bef");
+ const LLUUID IMG_RAINBOW("11b4c57c-56b3-04ed-1f82-2004363882e4");
+ const LLUUID IMG_HALO("12149143-f599-91a7-77ac-b52a3c0f59cd");
+}
+
+namespace {
+ LLQuaternion convert_azimuth_and_altitude_to_quat(F32 azimuth, F32 altitude)
+ {
+ F32 sinTheta = sin(azimuth);
+ F32 cosTheta = cos(azimuth);
+ F32 sinPhi = sin(altitude);
+ F32 cosPhi = cos(altitude);
+
+ LLVector3 dir;
+ // +x right, +z up, +y at...
+ dir.mV[0] = cosTheta * cosPhi;
+ dir.mV[1] = sinTheta * cosPhi;
+ dir.mV[2] = sinPhi;
+
+ LLVector3 axis = LLVector3::x_axis % dir;
+ axis.normalize();
+
+ F32 angle = acos(LLVector3::x_axis * dir);
+
+ LLQuaternion quat;
+ quat.setAngleAxis(angle, axis);
+
+ return quat;
+ }
+}
+
+static LLTrace::BlockTimerStatHandle FTM_BLEND_SKYVALUES("Blending Sky Environment");
+static LLTrace::BlockTimerStatHandle FTM_RECALCULATE_SKYVALUES("Recalculate Sky");
+static LLTrace::BlockTimerStatHandle FTM_RECALCULATE_BODIES("Recalculate Heavenly Bodies");
+static LLTrace::BlockTimerStatHandle FTM_RECALCULATE_LIGHTING("Recalculate Lighting");
+
+//=========================================================================
+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_RAINBOW_TEXTUREID("rainbow_id");
+const std::string LLSettingsSky::SETTING_HALO_TEXTUREID("halo_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_CLOUD_VARIANCE("cloud_variance");
+
+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_SCALE("moon_scale");
+const std::string LLSettingsSky::SETTING_MOON_TEXTUREID("moon_id");
+const std::string LLSettingsSky::SETTING_MOON_BRIGHTNESS("moon_brightness");
+
+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_SCALE("sun_scale");
+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 std::string LLSettingsSky::SETTING_SKY_MOISTURE_LEVEL("moisture_level");
+const std::string LLSettingsSky::SETTING_SKY_DROPLET_RADIUS("droplet_radius");
+const std::string LLSettingsSky::SETTING_SKY_ICE_LEVEL("ice_level");
+
+const LLUUID LLSettingsSky::DEFAULT_ASSET_ID("3ae23978-ac82-bcf3-a9cb-ba6e52dcb9ad");
+
+static const LLUUID DEFAULT_SUN_ID("32bfbcea-24b1-fb9d-1ef9-48a28a63730f"); // dataserver
+static const LLUUID DEFAULT_MOON_ID("d07f6eed-b96a-47cd-b51d-400ad4a1c428"); // dataserver
+static const LLUUID DEFAULT_CLOUD_ID("1dc1368f-e8fe-f02d-a08d-9d9f11c1af6b");
+
+const std::string LLSettingsSky::SETTING_LEGACY_HAZE("legacy_haze");
+
+const F32 LLSettingsSky::DOME_OFFSET(0.96f);
+const F32 LLSettingsSky::DOME_RADIUS(15000.f);
+
+namespace
+{
+
+LLSettingsSky::validation_list_t legacyHazeValidationList()
+{
+ static LLSettingsBase::validation_list_t legacyHazeValidation;
+ if (legacyHazeValidation.empty())
+ {
+ legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_AMBIENT, false, LLSD::TypeArray,
+ boost::bind(&LLSettingsBase::Validator::verifyVectorMinMax, _1,
+ LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
+ LLSD(LLSDArray(3.0f)(3.0f)(3.0f)("*")))));
+ legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_BLUE_DENSITY, false, LLSD::TypeArray,
+ boost::bind(&LLSettingsBase::Validator::verifyVectorMinMax, _1,
+ LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
+ LLSD(LLSDArray(3.0f)(3.0f)(3.0f)("*")))));
+ legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_BLUE_HORIZON, false, LLSD::TypeArray,
+ boost::bind(&LLSettingsBase::Validator::verifyVectorMinMax, _1,
+ LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
+ LLSD(LLSDArray(3.0f)(3.0f)(3.0f)("*")))));
+ legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_HAZE_DENSITY, false, LLSD::TypeReal,
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(5.0f)))));
+ legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_HAZE_HORIZON, false, LLSD::TypeReal,
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(5.0f)))));
+ legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_MULTIPLIER, false, LLSD::TypeReal,
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0001f)(2.0f)))));
+ legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DISTANCE_MULTIPLIER, false, LLSD::TypeReal,
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0001f)(1000.0f)))));
+ }
+ return legacyHazeValidation;
+}
+
+LLSettingsSky::validation_list_t rayleighValidationList()
+{
+ static LLSettingsBase::validation_list_t rayleighValidation;
+ if (rayleighValidation.empty())
+ {
+ rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH, false, 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, false, 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, false, 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, false, 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, false, 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, false, 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, false, 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, false, 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, false, 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, false, 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, false, 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, false, 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, false, 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, false, 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, false, LLSD::TypeReal,
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+
+ mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_MIE_ANISOTROPY_FACTOR, false, LLSD::TypeReal,
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+ }
+ return mieValidation;
+}
+
+bool validateLegacyHaze(LLSD &value)
+{
+ LLSettingsSky::validation_list_t legacyHazeValidations = legacyHazeValidationList();
+ llassert(value.type() == LLSD::TypeMap);
+ LLSD result = LLSettingsBase::settingValidation(value, legacyHazeValidations);
+ if (result["errors"].size() > 0)
+ {
+ LL_WARNS("SETTINGS") << "Legacy Haze Config Validation errors: " << result["errors"] << LL_ENDL;
+ return false;
+ }
+ if (result["warnings"].size() > 0)
+ {
+ LL_WARNS("SETTINGS") << "Legacy Haze Config Validation warnings: " << result["warnings"] << LL_ENDL;
+ return false;
+ }
+ return true;
+}
+
+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::TypeMap)
+ {
+ if (!validateRayleighLayers(layerConfig))
+ {
+ allGood = false;
+ }
+ }
+ else if (layerConfig.type() == LLSD::TypeArray)
+ {
+ return validateRayleighLayers(layerConfig);
+ }
+ else
+ {
+ return LLSettingsBase::settingValidation(value, rayleighValidations);
+ }
+ }
+ return allGood;
+ }
+ llassert(value.type() == LLSD::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::TypeMap)
+ {
+ if (!validateAbsorptionLayers(layerConfig))
+ {
+ allGood = false;
+ }
+ }
+ else if (layerConfig.type() == LLSD::TypeArray)
+ {
+ return validateAbsorptionLayers(layerConfig);
+ }
+ else
+ {
+ return LLSettingsBase::settingValidation(value, absorptionValidations);
+ }
+ }
+ return allGood;
+ }
+ llassert(value.type() == LLSD::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::TypeMap)
+ {
+ if (!validateMieLayers(layerConfig))
+ {
+ allGood = false;
+ }
+ }
+ else if (layerConfig.type() == LLSD::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["warnings"] << LL_ENDL;
+ return false;
+ }
+ return true;
+}
+
+}
+
+//=========================================================================
+LLSettingsSky::LLSettingsSky(const LLSD &data) :
+ LLSettingsBase(data),
+ mNextSunTextureId(),
+ mNextMoonTextureId(),
+ mNextCloudTextureId(),
+ mNextBloomTextureId(),
+ mNextRainbowTextureId(),
+ mNextHaloTextureId()
+{
+}
+
+LLSettingsSky::LLSettingsSky():
+ LLSettingsBase(),
+ mNextSunTextureId(),
+ mNextMoonTextureId(),
+ mNextCloudTextureId(),
+ mNextBloomTextureId(),
+ mNextRainbowTextureId(),
+ mNextHaloTextureId()
+{
+}
+
+void LLSettingsSky::replaceSettings(LLSD settings)
+{
+ LLSettingsBase::replaceSettings(settings);
+ mNextSunTextureId.setNull();
+ mNextMoonTextureId.setNull();
+ mNextCloudTextureId.setNull();
+ mNextBloomTextureId.setNull();
+ mNextRainbowTextureId.setNull();
+ mNextHaloTextureId.setNull();
+}
+
+void LLSettingsSky::replaceWithSky(LLSettingsSky::ptr_t pother)
+{
+ replaceWith(pother);
+
+ mNextSunTextureId = pother->mNextSunTextureId;
+ mNextMoonTextureId = pother->mNextMoonTextureId;
+ mNextCloudTextureId = pother->mNextCloudTextureId;
+ mNextBloomTextureId = pother->mNextBloomTextureId;
+ mNextRainbowTextureId = pother->mNextRainbowTextureId;
+ mNextHaloTextureId = pother->mNextHaloTextureId;
+}
+
+void LLSettingsSky::blend(const LLSettingsBase::ptr_t &end, F64 blendf)
+{
+ llassert(getSettingsType() == end->getSettingsType());
+
+ LLSettingsSky::ptr_t other = PTR_NAMESPACE::dynamic_pointer_cast<LLSettingsSky>(end);
+ if (other)
+ {
+ if (other->mSettings.has(SETTING_LEGACY_HAZE))
+ {
+ if (!mSettings.has(SETTING_LEGACY_HAZE) || !mSettings[SETTING_LEGACY_HAZE].has(SETTING_AMBIENT))
+ {
+ // Special case since SETTING_AMBIENT is both in outer and legacy maps, we prioritize legacy one
+ // see getAmbientColor(), we are about to replaceSettings(), so we are free to set it
+ setAmbientColor(getAmbientColor());
+ }
+ }
+ else
+ {
+ if (mSettings.has(SETTING_LEGACY_HAZE) && mSettings[SETTING_LEGACY_HAZE].has(SETTING_AMBIENT))
+ {
+ // Special case due to ambient's duality
+ // We need to match 'other's' structure for interpolation.
+ // We are free to change mSettings, since we are about to reset it
+ mSettings[SETTING_AMBIENT] = getAmbientColor().getValue();
+ mSettings[SETTING_LEGACY_HAZE].erase(SETTING_AMBIENT);
+ }
+ }
+
+ LLUUID cloud_noise_id = getCloudNoiseTextureId();
+ LLUUID cloud_noise_id_next = other->getCloudNoiseTextureId();
+ F64 cloud_shadow = 0;
+ if (!cloud_noise_id.isNull() && cloud_noise_id_next.isNull())
+ {
+ // If there is no cloud texture in destination, reduce coverage to imitate disappearance
+ // See LLDrawPoolWLSky::renderSkyClouds... we don't blend present texture with null
+ // Note: Probably can be done by shader
+ cloud_shadow = lerp(mSettings[SETTING_CLOUD_SHADOW].asReal(), (F64)0.f, blendf);
+ cloud_noise_id_next = cloud_noise_id;
+ }
+ else if (cloud_noise_id.isNull() && !cloud_noise_id_next.isNull())
+ {
+ // Source has no cloud texture, reduce initial coverage to imitate appearance
+ // use same texture as destination
+ cloud_shadow = lerp((F64)0.f, other->mSettings[SETTING_CLOUD_SHADOW].asReal(), blendf);
+ setCloudNoiseTextureId(cloud_noise_id_next);
+ }
+ else
+ {
+ cloud_shadow = lerp(mSettings[SETTING_CLOUD_SHADOW].asReal(), other->mSettings[SETTING_CLOUD_SHADOW].asReal(), blendf);
+ }
+
+ LLSD blenddata = interpolateSDMap(mSettings, other->mSettings, other->getParameterMap(), blendf);
+ blenddata[SETTING_CLOUD_SHADOW] = LLSD::Real(cloud_shadow);
+ replaceSettings(blenddata);
+ mNextSunTextureId = other->getSunTextureId();
+ mNextMoonTextureId = other->getMoonTextureId();
+ mNextCloudTextureId = cloud_noise_id_next;
+ mNextBloomTextureId = other->getBloomTextureId();
+ mNextRainbowTextureId = other->getRainbowTextureId();
+ mNextHaloTextureId = other->getHaloTextureId();
+ }
+ else
+ {
+ LL_WARNS("SETTINGS") << "Could not cast end settings to sky. No blend performed." << LL_ENDL;
+ }
+
+ setBlendFactor(blendf);
+}
+
+LLSettingsSky::stringset_t LLSettingsSky::getSkipInterpolateKeys() const
+{
+ static stringset_t skipSet;
+
+ if (skipSet.empty())
+ {
+ skipSet = LLSettingsBase::getSkipInterpolateKeys();
+ skipSet.insert(SETTING_RAYLEIGH_CONFIG);
+ skipSet.insert(SETTING_MIE_CONFIG);
+ skipSet.insert(SETTING_ABSORPTION_CONFIG);
+ skipSet.insert(SETTING_CLOUD_SHADOW);
+ }
+
+ return skipSet;
+}
+
+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]]]]]]]]]]
+ validation.push_back(Validator(SETTING_BLOOM_TEXTUREID, true, LLSD::TypeUUID));
+ validation.push_back(Validator(SETTING_RAINBOW_TEXTUREID, false, LLSD::TypeUUID));
+ validation.push_back(Validator(SETTING_HALO_TEXTUREID, false, 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.0f)(1.0f)(3.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.0f)(1.0f)(1.0f)("*")))));
+ validation.push_back(Validator(SETTING_CLOUD_SCALE, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.001f)(3.0f)))));
+ validation.push_back(Validator(SETTING_CLOUD_SCROLL_RATE, true, LLSD::TypeArray,
+ boost::bind(&Validator::verifyVectorMinMax, _1,
+ LLSD(LLSDArray(-50.0f)(-50.0f)),
+ LLSD(LLSDArray(50.0f)(50.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_CLOUD_VARIANCE, false, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+
+ validation.push_back(Validator(SETTING_DOME_OFFSET, false, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+ validation.push_back(Validator(SETTING_DOME_RADIUS, false, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(1000.0f)(2000.0f)))));
+ validation.push_back(Validator(SETTING_GAMMA, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(20.0f)))));
+ validation.push_back(Validator(SETTING_GLOW, true, LLSD::TypeArray,
+ boost::bind(&Validator::verifyVectorMinMax, _1,
+ LLSD(LLSDArray(0.2f)("*")(-10.0f)("*")),
+ LLSD(LLSDArray(40.0f)("*")(10.0f)("*")))));
+
+ validation.push_back(Validator(SETTING_MAX_Y, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(10000.0f)))));
+ validation.push_back(Validator(SETTING_MOON_ROTATION, true, LLSD::TypeArray, &Validator::verifyQuaternionNormal));
+ validation.push_back(Validator(SETTING_MOON_SCALE, false, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.25f)(20.0f))), LLSD::Real(1.0)));
+ validation.push_back(Validator(SETTING_MOON_TEXTUREID, false, LLSD::TypeUUID));
+ validation.push_back(Validator(SETTING_MOON_BRIGHTNESS, false, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+
+ validation.push_back(Validator(SETTING_STAR_BRIGHTNESS, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(500.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_SCALE, false, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.25f)(20.0f))), LLSD::Real(1.0)));
+ 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_SKY_MOISTURE_LEVEL, false, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+
+ validation.push_back(Validator(SETTING_SKY_DROPLET_RADIUS, false, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(5.0f)(1000.0f)))));
+
+ validation.push_back(Validator(SETTING_SKY_ICE_LEVEL, false, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+
+ 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));
+ validation.push_back(Validator(SETTING_LEGACY_HAZE, false, LLSD::TypeMap, &validateLegacyHaze));
+ }
+ return validation;
+}
+
+LLSD LLSettingsSky::createDensityProfileLayer(
+ F32 width,
+ F32 exponential_term,
+ F32 exponential_scale_factor,
+ F32 linear_term,
+ F32 constant_term,
+ F32 aniso_factor)
+{
+ LLSD dflt_layer;
+ dflt_layer[SETTING_DENSITY_PROFILE_WIDTH] = width; // 0 -> the entire atmosphere
+ dflt_layer[SETTING_DENSITY_PROFILE_EXP_TERM] = exponential_term;
+ dflt_layer[SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR] = exponential_scale_factor;
+ dflt_layer[SETTING_DENSITY_PROFILE_LINEAR_TERM] = linear_term;
+ dflt_layer[SETTING_DENSITY_PROFILE_CONSTANT_TERM] = constant_term;
+
+ if (aniso_factor != 0.0f)
+ {
+ dflt_layer[SETTING_MIE_ANISOTROPY_FACTOR] = aniso_factor;
+ }
+
+ return dflt_layer;
+}
+
+LLSD LLSettingsSky::createSingleLayerDensityProfile(
+ F32 width,
+ F32 exponential_term,
+ F32 exponential_scale_factor,
+ F32 linear_term,
+ F32 constant_term,
+ F32 aniso_factor)
+{
+ LLSD dflt;
+ LLSD dflt_layer = createDensityProfileLayer(width, exponential_term, exponential_scale_factor, linear_term, constant_term, aniso_factor);
+ dflt.append(dflt_layer);
+ return dflt;
+}
+
+LLSD LLSettingsSky::rayleighConfigDefault()
+{
+ return createSingleLayerDensityProfile(0.0f, 1.0f, -1.0f / 8000.0f, 0.0f, 0.0f);
+}
+
+LLSD LLSettingsSky::absorptionConfigDefault()
+{
+// absorption (ozone) has two linear ramping zones
+ LLSD dflt_absorption_layer_a = createDensityProfileLayer(25000.0f, 0.0f, 0.0f, -1.0f / 25000.0f, -2.0f / 3.0f);
+ LLSD dflt_absorption_layer_b = createDensityProfileLayer(0.0f, 0.0f, 0.0f, -1.0f / 15000.0f, 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 = createSingleLayerDensityProfile(0.0f, 1.0f, -1.0f / 1200.0f, 0.0f, 0.0f, 0.8f);
+ return dflt_mie;
+}
+
+LLSD LLSettingsSky::defaults(const LLSettingsBase::TrackPosition& position)
+{
+ static LLSD dfltsetting;
+
+ if (dfltsetting.size() == 0)
+ {
+ LLQuaternion sunquat;
+ LLQuaternion moonquat;
+
+ F32 azimuth = (F_PI * position) + (80.0f * DEG_TO_RAD);
+ F32 altitude = (F_PI * position);
+
+ // give the sun and moon slightly different tracks through the sky
+ // instead of positioning them at opposite poles from each other...
+ sunquat = convert_azimuth_and_altitude_to_quat(altitude, azimuth);
+ moonquat = convert_azimuth_and_altitude_to_quat(altitude + (F_PI * 0.125f), azimuth + (F_PI * 0.125f));
+
+ // Magic constants copied form dfltsetting.xml
+ 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(0.0f)(0.0f);
+ dfltsetting[SETTING_CLOUD_SHADOW] = LLSD::Real(0.2699);
+ dfltsetting[SETTING_CLOUD_VARIANCE] = LLSD::Real(0.0);
+
+ 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_MAX_Y] = LLSD::Real(1605);
+ dfltsetting[SETTING_MOON_ROTATION] = moonquat.getValue();
+ dfltsetting[SETTING_MOON_BRIGHTNESS] = LLSD::Real(0.5f);
+
+ dfltsetting[SETTING_STAR_BRIGHTNESS] = LLSD::Real(250.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] = GetDefaultBloomTextureId();
+ dfltsetting[SETTING_CLOUD_TEXTUREID] = GetDefaultCloudNoiseTextureId();
+ dfltsetting[SETTING_MOON_TEXTUREID] = GetDefaultMoonTextureId();
+ dfltsetting[SETTING_SUN_TEXTUREID] = GetDefaultSunTextureId();
+ dfltsetting[SETTING_RAINBOW_TEXTUREID] = GetDefaultRainbowTextureId();
+ dfltsetting[SETTING_HALO_TEXTUREID] = GetDefaultHaloTextureId();
+
+ 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.00045f;
+
+ dfltsetting[SETTING_SKY_MOISTURE_LEVEL] = 0.0f;
+ dfltsetting[SETTING_SKY_DROPLET_RADIUS] = 800.0f;
+ dfltsetting[SETTING_SKY_ICE_LEVEL] = 0.0f;
+
+ dfltsetting[SETTING_RAYLEIGH_CONFIG] = rayleighConfigDefault();
+ dfltsetting[SETTING_MIE_CONFIG] = mieConfigDefault();
+ dfltsetting[SETTING_ABSORPTION_CONFIG] = absorptionConfigDefault();
+ }
+
+ return dfltsetting;
+}
+
+LLSD LLSettingsSky::translateLegacyHazeSettings(const LLSD& legacy)
+{
+ LLSD legacyhazesettings;
+
+// AdvancedAtmospherics TODO
+// These need to be translated into density profile info in the new settings format...
+// LEGACY_ATMOSPHERICS
+ if (legacy.has(SETTING_AMBIENT))
+ {
+ legacyhazesettings[SETTING_AMBIENT] = LLColor3(legacy[SETTING_AMBIENT]).getValue();
+ }
+ if (legacy.has(SETTING_BLUE_DENSITY))
+ {
+ legacyhazesettings[SETTING_BLUE_DENSITY] = LLColor3(legacy[SETTING_BLUE_DENSITY]).getValue();
+ }
+ if (legacy.has(SETTING_BLUE_HORIZON))
+ {
+ legacyhazesettings[SETTING_BLUE_HORIZON] = LLColor3(legacy[SETTING_BLUE_HORIZON]).getValue();
+ }
+ if (legacy.has(SETTING_DENSITY_MULTIPLIER))
+ {
+ legacyhazesettings[SETTING_DENSITY_MULTIPLIER] = LLSD::Real(legacy[SETTING_DENSITY_MULTIPLIER][0].asReal());
+ }
+ if (legacy.has(SETTING_DISTANCE_MULTIPLIER))
+ {
+ legacyhazesettings[SETTING_DISTANCE_MULTIPLIER] = LLSD::Real(legacy[SETTING_DISTANCE_MULTIPLIER][0].asReal());
+ }
+ if (legacy.has(SETTING_HAZE_DENSITY))
+ {
+ legacyhazesettings[SETTING_HAZE_DENSITY] = LLSD::Real(legacy[SETTING_HAZE_DENSITY][0].asReal());
+ }
+ if (legacy.has(SETTING_HAZE_HORIZON))
+ {
+ legacyhazesettings[SETTING_HAZE_HORIZON] = LLSD::Real(legacy[SETTING_HAZE_HORIZON][0].asReal());
+ }
+
+ return legacyhazesettings;
+}
+
+LLSD LLSettingsSky::translateLegacySettings(const LLSD& legacy)
+{
+ bool converted_something(false);
+ LLSD newsettings(defaults());
+
+ // Move legacy haze parameters to an inner map
+ // allowing backward compat and simple conversion to legacy format
+ LLSD legacyhazesettings;
+ legacyhazesettings = translateLegacyHazeSettings(legacy);
+ if (legacyhazesettings.size() > 0)
+ {
+ newsettings[SETTING_LEGACY_HAZE] = legacyhazesettings;
+ converted_something |= true;
+ }
+
+ if (legacy.has(SETTING_CLOUD_COLOR))
+ {
+ newsettings[SETTING_CLOUD_COLOR] = LLColor3(legacy[SETTING_CLOUD_COLOR]).getValue();
+ converted_something |= true;
+ }
+ if (legacy.has(SETTING_CLOUD_POS_DENSITY1))
+ {
+ newsettings[SETTING_CLOUD_POS_DENSITY1] = LLColor3(legacy[SETTING_CLOUD_POS_DENSITY1]).getValue();
+ converted_something |= true;
+ }
+ if (legacy.has(SETTING_CLOUD_POS_DENSITY2))
+ {
+ newsettings[SETTING_CLOUD_POS_DENSITY2] = LLColor3(legacy[SETTING_CLOUD_POS_DENSITY2]).getValue();
+ converted_something |= true;
+ }
+ if (legacy.has(SETTING_CLOUD_SCALE))
+ {
+ newsettings[SETTING_CLOUD_SCALE] = LLSD::Real(legacy[SETTING_CLOUD_SCALE][0].asReal());
+ converted_something |= true;
+ }
+ if (legacy.has(SETTING_CLOUD_SCROLL_RATE))
+ {
+ LLVector2 cloud_scroll(legacy[SETTING_CLOUD_SCROLL_RATE]);
+
+ cloud_scroll -= LLVector2(10, 10);
+ 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();
+ converted_something |= true;
+ }
+ if (legacy.has(SETTING_CLOUD_SHADOW))
+ {
+ newsettings[SETTING_CLOUD_SHADOW] = LLSD::Real(legacy[SETTING_CLOUD_SHADOW][0].asReal());
+ converted_something |= true;
+ }
+
+
+ if (legacy.has(SETTING_GAMMA))
+ {
+ newsettings[SETTING_GAMMA] = legacy[SETTING_GAMMA][0].asReal();
+ converted_something |= true;
+ }
+ if (legacy.has(SETTING_GLOW))
+ {
+ newsettings[SETTING_GLOW] = LLColor3(legacy[SETTING_GLOW]).getValue();
+ converted_something |= true;
+ }
+
+ if (legacy.has(SETTING_MAX_Y))
+ {
+ newsettings[SETTING_MAX_Y] = LLSD::Real(legacy[SETTING_MAX_Y][0].asReal());
+ converted_something |= true;
+ }
+ if (legacy.has(SETTING_STAR_BRIGHTNESS))
+ {
+ newsettings[SETTING_STAR_BRIGHTNESS] = LLSD::Real(legacy[SETTING_STAR_BRIGHTNESS].asReal() * 250.0f);
+ converted_something |= true;
+ }
+ if (legacy.has(SETTING_SUNLIGHT_COLOR))
+ {
+ newsettings[SETTING_SUNLIGHT_COLOR] = LLColor4(legacy[SETTING_SUNLIGHT_COLOR]).getValue();
+ converted_something |= true;
+ }
+
+ if (legacy.has(SETTING_PLANET_RADIUS))
+ {
+ newsettings[SETTING_PLANET_RADIUS] = LLSD::Real(legacy[SETTING_PLANET_RADIUS].asReal());
+ converted_something |= true;
+ }
+
+ if (legacy.has(SETTING_SKY_BOTTOM_RADIUS))
+ {
+ newsettings[SETTING_SKY_BOTTOM_RADIUS] = LLSD::Real(legacy[SETTING_SKY_BOTTOM_RADIUS].asReal());
+ converted_something |= true;
+ }
+
+ if (legacy.has(SETTING_SKY_TOP_RADIUS))
+ {
+ newsettings[SETTING_SKY_TOP_RADIUS] = LLSD::Real(legacy[SETTING_SKY_TOP_RADIUS].asReal());
+ converted_something |= true;
+ }
+
+ if (legacy.has(SETTING_SUN_ARC_RADIANS))
+ {
+ newsettings[SETTING_SUN_ARC_RADIANS] = LLSD::Real(legacy[SETTING_SUN_ARC_RADIANS].asReal());
+ converted_something |= true;
+ }
+
+ if (legacy.has(SETTING_LEGACY_EAST_ANGLE) && legacy.has(SETTING_LEGACY_SUN_ANGLE))
+ {
+ // get counter-clockwise radian angle from clockwise legacy WL east angle...
+ F32 azimuth = -legacy[SETTING_LEGACY_EAST_ANGLE].asReal();
+ F32 altitude = legacy[SETTING_LEGACY_SUN_ANGLE].asReal();
+
+ LLQuaternion sunquat = convert_azimuth_and_altitude_to_quat(azimuth, altitude);
+ // original WL moon dir was diametrically opposed to the sun dir
+ LLQuaternion moonquat = convert_azimuth_and_altitude_to_quat(azimuth + F_PI, -altitude);
+
+ newsettings[SETTING_SUN_ROTATION] = sunquat.getValue();
+ newsettings[SETTING_MOON_ROTATION] = moonquat.getValue();
+ converted_something |= true;
+ }
+
+ if (!converted_something)
+ return LLSD();
+
+ return newsettings;
+}
+
+void LLSettingsSky::updateSettings()
+{
+ LL_RECORD_BLOCK_TIME(FTM_RECALCULATE_SKYVALUES);
+
+ // base class clears dirty flag so as to not trigger recursive update
+ LLSettingsBase::updateSettings();
+
+ // NOTE: these functions are designed to do nothing unless a dirty bit has been set
+ // so if you add new settings that are referenced by these update functions,
+ // you'll need to insure that your setter updates the dirty bits as well
+ calculateHeavenlyBodyPositions();
+ calculateLightSettings();
+}
+
+F32 LLSettingsSky::getSunMoonGlowFactor() const
+{
+ return getIsSunUp() ? 1.0f :
+ getIsMoonUp() ? getMoonBrightness() * 0.25 : 0.0f;
+}
+
+bool LLSettingsSky::getIsSunUp() const
+{
+ LLVector3 sunDir = getSunDirection();
+ return sunDir.mV[2] >= 0.0f;
+}
+
+bool LLSettingsSky::getIsMoonUp() const
+{
+ LLVector3 moonDir = getMoonDirection();
+ return moonDir.mV[2] >= 0.0f;
+}
+
+void LLSettingsSky::calculateHeavenlyBodyPositions() const
+{
+ LLQuaternion sunq = getSunRotation();
+ LLQuaternion moonq = getMoonRotation();
+
+ mSunDirection = LLVector3::x_axis * sunq;
+ mMoonDirection = LLVector3::x_axis * moonq;
+
+ mSunDirection.normalize();
+ mMoonDirection.normalize();
+
+ if (mSunDirection.lengthSquared() < 0.01f)
+ LL_WARNS("SETTINGS") << "Zero length sun direction. Wailing and gnashing of teeth may follow... or not." << LL_ENDL;
+ if (mMoonDirection.lengthSquared() < 0.01f)
+ LL_WARNS("SETTINGS") << "Zero length moon direction. Wailing and gnashing of teeth may follow... or not." << LL_ENDL;
+}
+
+LLVector3 LLSettingsSky::getLightDirection() const
+{
+ update();
+
+ // is the normal from the sun or the moon
+ if (getIsSunUp())
+ {
+ return mSunDirection;
+ }
+ else if (getIsMoonUp())
+ {
+ return mMoonDirection;
+ }
+
+ return -LLVector3::z_axis;
+}
+
+LLColor3 LLSettingsSky::getLightDiffuse() const
+{
+ update();
+
+ // is the normal from the sun or the moon
+ if (getIsSunUp())
+ {
+ return getSunDiffuse();
+ }
+ else if (getIsMoonUp())
+ {
+ return getMoonDiffuse();
+ }
+
+ return LLColor3::white;
+}
+
+LLColor3 LLSettingsSky::getColor(const std::string& key, const LLColor3& default_value) const
+{
+ if (mSettings.has(SETTING_LEGACY_HAZE) && mSettings[SETTING_LEGACY_HAZE].has(key))
+ {
+ return LLColor3(mSettings[SETTING_LEGACY_HAZE][key]);
+ }
+ if (mSettings.has(key))
+ {
+ return LLColor3(mSettings[key]);
+ }
+ return default_value;
+}
+
+F32 LLSettingsSky::getFloat(const std::string& key, F32 default_value) const
+{
+ if (mSettings.has(SETTING_LEGACY_HAZE) && mSettings[SETTING_LEGACY_HAZE].has(key))
+ {
+ return mSettings[SETTING_LEGACY_HAZE][key].asReal();
+ }
+ if (mSettings.has(key))
+ {
+ return mSettings[key].asReal();
+ }
+ return default_value;
+}
+
+LLColor3 LLSettingsSky::getAmbientColor() const
+{
+ return getColor(SETTING_AMBIENT, LLColor3(0.25f, 0.25f, 0.25f));
+}
+
+LLColor3 LLSettingsSky::getAmbientColorClamped() const
+{
+ LLColor3 ambient = getAmbientColor();
+
+ F32 max_color = llmax(ambient.mV[0], ambient.mV[1], ambient.mV[2]);
+ if (max_color > 1.0f)
+ {
+ ambient *= 1.0f/max_color;
+ }
+
+ return ambient;
+}
+
+LLColor3 LLSettingsSky::getBlueDensity() const
+{
+ return getColor(SETTING_BLUE_DENSITY, LLColor3(0.2447f, 0.4487f, 0.7599f));
+}
+
+LLColor3 LLSettingsSky::getBlueHorizon() const
+{
+ return getColor(SETTING_BLUE_HORIZON, LLColor3(0.4954f, 0.4954f, 0.6399f));
+}
+
+F32 LLSettingsSky::getHazeDensity() const
+{
+ return getFloat(SETTING_HAZE_DENSITY, 0.7f);
+}
+
+F32 LLSettingsSky::getHazeHorizon() const
+{
+ return getFloat(SETTING_HAZE_HORIZON, 0.19f);
+}
+
+F32 LLSettingsSky::getDensityMultiplier() const
+{
+ return getFloat(SETTING_DENSITY_MULTIPLIER, 0.0001f);
+}
+
+F32 LLSettingsSky::getDistanceMultiplier() const
+{
+ return getFloat(SETTING_DISTANCE_MULTIPLIER, 0.8f);
+}
+
+void LLSettingsSky::setPlanetRadius(F32 radius)
+{
+ mSettings[SETTING_PLANET_RADIUS] = radius;
+}
+
+void LLSettingsSky::setSkyBottomRadius(F32 radius)
+{
+ mSettings[SETTING_SKY_BOTTOM_RADIUS] = radius;
+}
+
+void LLSettingsSky::setSkyTopRadius(F32 radius)
+{
+ mSettings[SETTING_SKY_TOP_RADIUS] = radius;
+}
+
+void LLSettingsSky::setSunArcRadians(F32 radians)
+{
+ mSettings[SETTING_SUN_ARC_RADIANS] = radians;
+}
+
+void LLSettingsSky::setMieAnisotropy(F32 aniso_factor)
+{
+ getMieConfig()[SETTING_MIE_ANISOTROPY_FACTOR] = aniso_factor;
+}
+
+void LLSettingsSky::setSkyMoistureLevel(F32 moisture_level)
+{
+ setValue(SETTING_SKY_MOISTURE_LEVEL, moisture_level);
+}
+
+void LLSettingsSky::setSkyDropletRadius(F32 radius)
+{
+ setValue(SETTING_SKY_DROPLET_RADIUS,radius);
+}
+
+void LLSettingsSky::setSkyIceLevel(F32 ice_level)
+{
+ setValue(SETTING_SKY_ICE_LEVEL, ice_level);
+}
+
+void LLSettingsSky::setAmbientColor(const LLColor3 &val)
+{
+ mSettings[SETTING_LEGACY_HAZE][SETTING_AMBIENT] = val.getValue();
+ setDirtyFlag(true);
+}
+
+void LLSettingsSky::setBlueDensity(const LLColor3 &val)
+{
+ mSettings[SETTING_LEGACY_HAZE][SETTING_BLUE_DENSITY] = val.getValue();
+ setDirtyFlag(true);
+}
+
+void LLSettingsSky::setBlueHorizon(const LLColor3 &val)
+{
+ mSettings[SETTING_LEGACY_HAZE][SETTING_BLUE_HORIZON] = val.getValue();
+ setDirtyFlag(true);
+}
+
+void LLSettingsSky::setDensityMultiplier(F32 val)
+{
+ mSettings[SETTING_LEGACY_HAZE][SETTING_DENSITY_MULTIPLIER] = val;
+ setDirtyFlag(true);
+}
+
+void LLSettingsSky::setDistanceMultiplier(F32 val)
+{
+ mSettings[SETTING_LEGACY_HAZE][SETTING_DISTANCE_MULTIPLIER] = val;
+ setDirtyFlag(true);
+}
+
+void LLSettingsSky::setHazeDensity(F32 val)
+{
+ mSettings[SETTING_LEGACY_HAZE][SETTING_HAZE_DENSITY] = val;
+ setDirtyFlag(true);
+}
+
+void LLSettingsSky::setHazeHorizon(F32 val)
+{
+ mSettings[SETTING_LEGACY_HAZE][SETTING_HAZE_HORIZON] = val;
+ setDirtyFlag(true);
+}
+
+// Get total from rayleigh and mie density values for normalization
+LLColor3 LLSettingsSky::getTotalDensity() const
+{
+ LLColor3 blue_density = getBlueDensity();
+ F32 haze_density = getHazeDensity();
+ LLColor3 total_density = blue_density + smear(haze_density);
+ return total_density;
+}
+
+// Sunlight attenuation effect (hue and brightness) due to atmosphere
+// this is used later for sunlight modulation at various altitudes
+LLColor3 LLSettingsSky::getLightAttenuation(F32 distance) const
+{
+ F32 density_multiplier = getDensityMultiplier();
+ LLColor3 blue_density = getBlueDensity();
+ F32 haze_density = getHazeDensity();
+ // Approximate line integral over requested distance
+ LLColor3 light_atten = (blue_density * 1.0 + smear(haze_density * 0.25f)) * density_multiplier * distance;
+ return light_atten;
+}
+
+LLColor3 LLSettingsSky::getLightTransmittance(F32 distance) const
+{
+ LLColor3 total_density = getTotalDensity();
+ F32 density_multiplier = getDensityMultiplier();
+ // Transparency (-> density) from Beer's law
+ LLColor3 transmittance = componentExp(total_density * -(density_multiplier * distance));
+ return transmittance;
+}
+
+// performs soft scale clip and gamma correction ala the shader implementation
+// scales colors down to 0 - 1 range preserving relative ratios
+LLColor3 LLSettingsSky::gammaCorrect(const LLColor3& in) const
+{
+ F32 gamma = getGamma();
+
+ LLColor3 v(in);
+ // scale down to 0 to 1 range preserving relative ratio (aka homegenize)
+ F32 max_color = llmax(llmax(in.mV[0], in.mV[1]), in.mV[2]);
+ if (max_color > 1.0f)
+ {
+ v *= 1.0f / max_color;
+ }
+
+ LLColor3 color = in * 2.0f;
+ color = smear(1.f) - componentSaturate(color); // clamping after mul seems wrong, but prevents negative colors...
+ componentPow(color, gamma);
+ color = smear(1.f) - color;
+ return color;
+}
+
+LLVector3 LLSettingsSky::getSunDirection() const
+{
+ update();
+ return mSunDirection;
+}
+
+LLVector3 LLSettingsSky::getMoonDirection() const
+{
+ update();
+ return mMoonDirection;
+}
+
+LLColor4 LLSettingsSky::getMoonAmbient() const
+{
+ update();
+ return mMoonAmbient;
+}
+
+LLColor3 LLSettingsSky::getMoonDiffuse() const
+{
+ update();
+ return mMoonDiffuse;
+}
+
+LLColor4 LLSettingsSky::getSunAmbient() const
+{
+ update();
+ return mSunAmbient;
+}
+
+LLColor3 LLSettingsSky::getSunDiffuse() const
+{
+ update();
+ return mSunDiffuse;
+}
+
+LLColor4 LLSettingsSky::getHazeColor() const
+{
+ update();
+ return mHazeColor;
+}
+
+LLColor4 LLSettingsSky::getTotalAmbient() const
+{
+ update();
+ return mTotalAmbient;
+}
+
+LLColor3 LLSettingsSky::getMoonlightColor() const
+{
+ F32 moon_brightness = getIsMoonUp() ? getMoonBrightness() : 0.001f;
+ LLColor3 moonlight_a(0.9, 0.9, 1.32);
+ LLColor3 moonlight_b(0.66, 0.66, 2.0);
+ LLColor3 moonlight = lerp(moonlight_b, moonlight_a, moon_brightness);
+ return moonlight;
+}
+
+void LLSettingsSky::clampColor(LLColor3& color, F32 gamma, F32 scale) const
+{
+ F32 max_color = llmax(color.mV[0], color.mV[1], color.mV[2]);
+ if (max_color > scale)
+ {
+ color *= scale/max_color;
+ }
+ LLColor3 linear(color);
+ linear *= 1.0 / scale;
+ linear = smear(1.0f) - linear;
+ linear = componentPow(linear, gamma);
+ linear *= scale;
+ color = linear;
+}
+
+void LLSettingsSky::calculateLightSettings() const
+{
+ // Initialize temp variables
+ LLColor3 sunlight = getSunlightColor();
+ LLColor3 ambient = getAmbientColor();
+
+ 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
+ F32 max_y = getMaxY();
+ LLColor3 light_atten = getLightAttenuation(max_y);
+ LLColor3 light_transmittance = getLightTransmittance(max_y);
+
+ // and vary_sunlight will work properly with moon light
+ const F32 LIMIT = FLT_EPSILON * 8.0f;
+
+ F32 lighty = fabs(lightnorm[2]);
+ if(lighty >= LIMIT)
+ {
+ lighty = 1.f / lighty;
+ }
+ lighty = llmax(LIMIT, lighty);
+ componentMultBy(sunlight, componentExp((light_atten * -1.f) * lighty));
+ componentMultBy(sunlight, light_transmittance);
+
+ //F32 max_color = llmax(sunlight.mV[0], sunlight.mV[1], sunlight.mV[2]);
+ //if (max_color > 1.0f)
+ //{
+ // sunlight *= 1.0f/max_color;
+ //}
+
+ //increase ambient when there are more clouds
+ LLColor3 tmpAmbient = ambient + (smear(1.f) - ambient) * cloud_shadow * 0.5;
+ componentMultBy(tmpAmbient, light_transmittance);
+
+ //tmpAmbient = LLColor3::clamp(tmpAmbient, getGamma(), 1.0f);
+ //max_color = llmax(tmpAmbient.mV[0], tmpAmbient.mV[1], tmpAmbient.mV[2]);
+ //if (max_color > 1.0f)
+ //{
+ // tmpAmbient *= 1.0f/max_color;
+ //}
+
+ //brightness of surface both sunlight and ambient
+ mSunDiffuse = sunlight;
+ mSunAmbient = tmpAmbient;
+ F32 haze_horizon = getHazeHorizon();
+
+ sunlight *= 1.0 - cloud_shadow;
+ sunlight += tmpAmbient;
+
+ mHazeColor = getBlueHorizon() * getBlueDensity() * sunlight;
+ mHazeColor += LLColor4(haze_horizon, haze_horizon, haze_horizon, haze_horizon) * getHazeDensity() * sunlight;
+
+ F32 moon_brightness = getIsMoonUp() ? getMoonBrightness() : 0.001f;
+
+ LLColor3 moonlight = getMoonlightColor();
+ LLColor3 moonlight_b(0.66, 0.66, 1.2); // scotopic ambient value
+
+ componentMultBy(moonlight, componentExp((light_atten * -1.f) * lighty));
+ //clampColor(moonlight, getGamma(), 1.0f);
+
+ mMoonDiffuse = componentMult(moonlight, light_transmittance) * moon_brightness;
+ mMoonAmbient = componentMult(moonlight_b, light_transmittance) * 0.0125f;
+
+ mTotalAmbient = mSunAmbient;
+}
+
+LLUUID LLSettingsSky::GetDefaultAssetId()
+{
+ return DEFAULT_ASSET_ID;
+}
+
+LLUUID LLSettingsSky::GetDefaultSunTextureId()
+{
+ return LLUUID::null;
+}
+
+
+LLUUID LLSettingsSky::GetBlankSunTextureId()
+{
+ return DEFAULT_SUN_ID;
+}
+
+LLUUID LLSettingsSky::GetDefaultMoonTextureId()
+{
+ return DEFAULT_MOON_ID;
+}
+
+LLUUID LLSettingsSky::GetDefaultCloudNoiseTextureId()
+{
+ return DEFAULT_CLOUD_ID;
+}
+
+LLUUID LLSettingsSky::GetDefaultBloomTextureId()
+{
+ return IMG_BLOOM1;
+}
+
+LLUUID LLSettingsSky::GetDefaultRainbowTextureId()
+{
+ return IMG_RAINBOW;
+}
+
+LLUUID LLSettingsSky::GetDefaultHaloTextureId()
+{
+ return IMG_HALO;
+}
+
+F32 LLSettingsSky::getPlanetRadius() const
+{
+ return mSettings[SETTING_PLANET_RADIUS].asReal();
+}
+
+F32 LLSettingsSky::getSkyMoistureLevel() const
+{
+ return mSettings[SETTING_SKY_MOISTURE_LEVEL].asReal();
+}
+
+F32 LLSettingsSky::getSkyDropletRadius() const
+{
+ return mSettings[SETTING_SKY_DROPLET_RADIUS].asReal();
+}
+
+F32 LLSettingsSky::getSkyIceLevel() const
+{
+ return mSettings[SETTING_SKY_ICE_LEVEL].asReal();
+}
+
+F32 LLSettingsSky::getSkyBottomRadius() const
+{
+ return mSettings[SETTING_SKY_BOTTOM_RADIUS].asReal();
+}
+
+F32 LLSettingsSky::getSkyTopRadius() const
+{
+ return mSettings[SETTING_SKY_TOP_RADIUS].asReal();
+}
+
+F32 LLSettingsSky::getSunArcRadians() const
+{
+ return mSettings[SETTING_SUN_ARC_RADIANS].asReal();
+}
+
+F32 LLSettingsSky::getMieAnisotropy() const
+{
+ return getMieConfig()[SETTING_MIE_ANISOTROPY_FACTOR].asReal();
+}
+
+LLSD LLSettingsSky::getRayleighConfig() const
+{
+ LLSD copy = *(mSettings[SETTING_RAYLEIGH_CONFIG].beginArray());
+ return copy;
+}
+
+LLSD LLSettingsSky::getMieConfig() const
+{
+ LLSD copy = *(mSettings[SETTING_MIE_CONFIG].beginArray());
+ return copy;
+}
+
+LLSD LLSettingsSky::getAbsorptionConfig() const
+{
+ LLSD copy = *(mSettings[SETTING_ABSORPTION_CONFIG].beginArray());
+ return copy;
+}
+
+LLSD LLSettingsSky::getRayleighConfigs() const
+{
+ return mSettings[SETTING_RAYLEIGH_CONFIG];
+}
+
+LLSD LLSettingsSky::getMieConfigs() const
+{
+ return mSettings[SETTING_MIE_CONFIG];
+}
+
+LLSD LLSettingsSky::getAbsorptionConfigs() const
+{
+ return mSettings[SETTING_ABSORPTION_CONFIG];
+}
+
+void LLSettingsSky::setRayleighConfigs(const LLSD& rayleighConfig)
+{
+ mSettings[SETTING_RAYLEIGH_CONFIG] = rayleighConfig;
+}
+
+void LLSettingsSky::setMieConfigs(const LLSD& mieConfig)
+{
+ mSettings[SETTING_MIE_CONFIG] = mieConfig;
+}
+
+void LLSettingsSky::setAbsorptionConfigs(const LLSD& absorptionConfig)
+{
+ mSettings[SETTING_ABSORPTION_CONFIG] = absorptionConfig;
+}
+
+LLUUID LLSettingsSky::getBloomTextureId() const
+{
+ return mSettings[SETTING_BLOOM_TEXTUREID].asUUID();
+}
+
+LLUUID LLSettingsSky::getRainbowTextureId() const
+{
+ return mSettings[SETTING_RAINBOW_TEXTUREID].asUUID();
+}
+
+LLUUID LLSettingsSky::getHaloTextureId() const
+{
+ return mSettings[SETTING_HALO_TEXTUREID].asUUID();
+}
+
+//---------------------------------------------------------------------
+LLColor3 LLSettingsSky::getCloudColor() const
+{
+ return LLColor3(mSettings[SETTING_CLOUD_COLOR]);
+}
+
+void LLSettingsSky::setCloudColor(const LLColor3 &val)
+{
+ setValue(SETTING_CLOUD_COLOR, val);
+}
+
+LLUUID LLSettingsSky::getCloudNoiseTextureId() const
+{
+ return mSettings[SETTING_CLOUD_TEXTUREID].asUUID();
+}
+
+void LLSettingsSky::setCloudNoiseTextureId(const LLUUID &id)
+{
+ setValue(SETTING_CLOUD_TEXTUREID, id);
+}
+
+LLColor3 LLSettingsSky::getCloudPosDensity1() const
+{
+ return LLColor3(mSettings[SETTING_CLOUD_POS_DENSITY1]);
+}
+
+void LLSettingsSky::setCloudPosDensity1(const LLColor3 &val)
+{
+ setValue(SETTING_CLOUD_POS_DENSITY1, val);
+}
+
+LLColor3 LLSettingsSky::getCloudPosDensity2() const
+{
+ return LLColor3(mSettings[SETTING_CLOUD_POS_DENSITY2]);
+}
+
+void LLSettingsSky::setCloudPosDensity2(const LLColor3 &val)
+{
+ setValue(SETTING_CLOUD_POS_DENSITY2, val);
+}
+
+F32 LLSettingsSky::getCloudScale() const
+{
+ return mSettings[SETTING_CLOUD_SCALE].asReal();
+}
+
+void LLSettingsSky::setCloudScale(F32 val)
+{
+ setValue(SETTING_CLOUD_SCALE, val);
+}
+
+LLVector2 LLSettingsSky::getCloudScrollRate() const
+{
+ return LLVector2(mSettings[SETTING_CLOUD_SCROLL_RATE]);
+}
+
+void LLSettingsSky::setCloudScrollRate(const LLVector2 &val)
+{
+ setValue(SETTING_CLOUD_SCROLL_RATE, val);
+}
+
+void LLSettingsSky::setCloudScrollRateX(F32 val)
+{
+ mSettings[SETTING_CLOUD_SCROLL_RATE][0] = val;
+ setDirtyFlag(true);
+}
+
+void LLSettingsSky::setCloudScrollRateY(F32 val)
+{
+ mSettings[SETTING_CLOUD_SCROLL_RATE][1] = val;
+ setDirtyFlag(true);
+}
+
+F32 LLSettingsSky::getCloudShadow() const
+{
+ return mSettings[SETTING_CLOUD_SHADOW].asReal();
+}
+
+void LLSettingsSky::setCloudShadow(F32 val)
+{
+ setValue(SETTING_CLOUD_SHADOW, val);
+}
+
+F32 LLSettingsSky::getCloudVariance() const
+{
+ return mSettings[SETTING_CLOUD_VARIANCE].asReal();
+}
+
+void LLSettingsSky::setCloudVariance(F32 val)
+{
+ setValue(SETTING_CLOUD_VARIANCE, val);
+}
+
+F32 LLSettingsSky::getDomeOffset() const
+{
+ //return mSettings[SETTING_DOME_OFFSET].asReal();
+ return DOME_OFFSET;
+}
+
+F32 LLSettingsSky::getDomeRadius() const
+{
+ //return mSettings[SETTING_DOME_RADIUS].asReal();
+ return DOME_RADIUS;
+}
+
+F32 LLSettingsSky::getGamma() const
+{
+ return mSettings[SETTING_GAMMA].asReal();
+}
+
+void LLSettingsSky::setGamma(F32 val)
+{
+ mSettings[SETTING_GAMMA] = LLSD::Real(val);
+ setDirtyFlag(true);
+}
+
+LLColor3 LLSettingsSky::getGlow() const
+{
+ return LLColor3(mSettings[SETTING_GLOW]);
+}
+
+void LLSettingsSky::setGlow(const LLColor3 &val)
+{
+ setValue(SETTING_GLOW, val);
+}
+
+F32 LLSettingsSky::getMaxY() const
+{
+ return mSettings[SETTING_MAX_Y].asReal();
+}
+
+void LLSettingsSky::setMaxY(F32 val)
+{
+ setValue(SETTING_MAX_Y, val);
+}
+
+LLQuaternion LLSettingsSky::getMoonRotation() const
+{
+ return LLQuaternion(mSettings[SETTING_MOON_ROTATION]);
+}
+
+void LLSettingsSky::setMoonRotation(const LLQuaternion &val)
+{
+ setValue(SETTING_MOON_ROTATION, val);
+}
+
+F32 LLSettingsSky::getMoonScale() const
+{
+ return mSettings[SETTING_MOON_SCALE].asReal();
+}
+
+void LLSettingsSky::setMoonScale(F32 val)
+{
+ setValue(SETTING_MOON_SCALE, val);
+}
+
+LLUUID LLSettingsSky::getMoonTextureId() const
+{
+ return mSettings[SETTING_MOON_TEXTUREID].asUUID();
+}
+
+void LLSettingsSky::setMoonTextureId(LLUUID id)
+{
+ setValue(SETTING_MOON_TEXTUREID, id);
+}
+
+F32 LLSettingsSky::getMoonBrightness() const
+{
+ return mSettings[SETTING_MOON_BRIGHTNESS].asReal();
+}
+
+void LLSettingsSky::setMoonBrightness(F32 brightness_factor)
+{
+ setValue(SETTING_MOON_BRIGHTNESS, brightness_factor);
+}
+
+F32 LLSettingsSky::getStarBrightness() const
+{
+ return mSettings[SETTING_STAR_BRIGHTNESS].asReal();
+}
+
+void LLSettingsSky::setStarBrightness(F32 val)
+{
+ setValue(SETTING_STAR_BRIGHTNESS, val);
+}
+
+LLColor3 LLSettingsSky::getSunlightColor() const
+{
+ return LLColor3(mSettings[SETTING_SUNLIGHT_COLOR]);
+}
+
+LLColor3 LLSettingsSky::getSunlightColorClamped() const
+{
+ LLColor3 sunlight = getSunlightColor();
+ //clampColor(sunlight, getGamma(), 3.0f);
+
+ F32 max_color = llmax(sunlight.mV[0], sunlight.mV[1], sunlight.mV[2]);
+ if (max_color > 1.0f)
+ {
+ sunlight *= 1.0f/max_color;
+ }
+
+ return sunlight;
+}
+
+void LLSettingsSky::setSunlightColor(const LLColor3 &val)
+{
+ setValue(SETTING_SUNLIGHT_COLOR, val);
+}
+
+LLQuaternion LLSettingsSky::getSunRotation() const
+{
+ return LLQuaternion(mSettings[SETTING_SUN_ROTATION]);
+}
+
+void LLSettingsSky::setSunRotation(const LLQuaternion &val)
+{
+ setValue(SETTING_SUN_ROTATION, val);
+}
+
+
+F32 LLSettingsSky::getSunScale() const
+{
+ return mSettings[SETTING_SUN_SCALE].asReal();
+}
+
+void LLSettingsSky::setSunScale(F32 val)
+{
+ setValue(SETTING_SUN_SCALE, val);
+}
+
+LLUUID LLSettingsSky::getSunTextureId() const
+{
+ return mSettings[SETTING_SUN_TEXTUREID].asUUID();
+}
+
+void LLSettingsSky::setSunTextureId(LLUUID id)
+{
+ setValue(SETTING_SUN_TEXTUREID, id);
+}
+
+LLUUID LLSettingsSky::getNextSunTextureId() const
+{
+ return mNextSunTextureId;
+}
+
+LLUUID LLSettingsSky::getNextMoonTextureId() const
+{
+ return mNextMoonTextureId;
+}
+
+LLUUID LLSettingsSky::getNextCloudNoiseTextureId() const
+{
+ return mNextCloudTextureId;
+}
+
+LLUUID LLSettingsSky::getNextBloomTextureId() const
+{
+ return mNextBloomTextureId;
+}
+