/indra/newview/llenvmanager.cpp
C++ | 678 lines | 493 code | 114 blank | 71 comment | 45 complexity | bc5820634dc5a28f8a383e00ba3da9f2 MD5 | raw file
Possible License(s): LGPL-2.1
- /**
- * @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"
- std::string LLEnvPrefs::getWaterPresetName() const
- {
- if (mWaterPresetName.empty())
- {
- llwarns << "Water preset name is empty" << llendl;
- }
- return mWaterPresetName;
- }
- std::string LLEnvPrefs::getSkyPresetName() const
- {
- if (mSkyPresetName.empty())
- {
- llwarns << "Sky preset name is empty" << llendl;
- }
- return mSkyPresetName;
- }
- std::string LLEnvPrefs::getDayCycleName() const
- {
- if (mDayCycleName.empty())
- {
- llwarns << "Day cycle name is empty" << llendl;
- }
- 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;
- // Set default environment settings.
- mUserPrefs.mUseRegionSettings = true;
- mUserPrefs.mUseDayCycle = true;
- mUserPrefs.mWaterPresetName = "Default";
- mUserPrefs.mSkyPresetName = "Default";
- mUserPrefs.mDayCycleName = "Default";
- }
- 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))
- {
- llwarns << "No sky preset named " << name << llendl;
- 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))
- {
- llwarns << "No day cycle named " << name << llendl;
- 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())
- {
- llwarns << "Empty water preset name passed" << llendl;
- return;
- }
- mUserPrefs.setUseWaterPreset(name);
- saveUserPrefs();
- updateManagersFromPrefs(false);
- }
- void LLEnvManagerNew::setUseSkyPreset(const std::string& name)
- {
- // *TODO: make sure the preset exists.
- if (name.empty())
- {
- llwarns << "Empty sky preset name passed" << llendl;
- return;
- }
- mUserPrefs.setUseSkyPreset(name);
- saveUserPrefs();
- updateManagersFromPrefs(false);
- }
- void LLEnvManagerNew::setUseDayCycle(const std::string& name)
- {
- if (!LLDayCycleManager::instance().presetExists(name))
- {
- llwarns << "Invalid day cycle name passed" << llendl;
- 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");
- mUserPrefs.mUseRegionSettings = gSavedSettings.getBOOL("UseEnvironmentFromRegion");
- mUserPrefs.mUseDayCycle = gSavedSettings.getBOOL("UseDayCycle");
- }
- 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()
- {
- 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::setRegionChangeCallback(const region_change_signal_t::slot_type& cb)
- {
- return mRegionChangeSignal.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::onRegionCrossing()
- {
- LL_DEBUGS("Windlight") << "Crossed region" << LL_ENDL;
- onRegionChange(true);
- }
- void LLEnvManagerNew::onTeleport()
- {
- LL_DEBUGS("Windlight") << "Teleported" << LL_ENDL;
- onRegionChange(false);
- }
- 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") << "Caching 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();
- // 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();
- }
- 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))
- {
- llwarns << "No water preset named " << water << ", falling back to defaults" << llendl;
- 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)
- {
- // 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;
- }
- // *TODO: Support fixed sky from region.
- // Otherwise apply region day cycle.
- LL_DEBUGS("Windlight") << "Applying region sky" << LL_ENDL;
- 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(bool interpolate)
- {
- // 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)
- {
- return;
- }
- // Clear locally modified region settings.
- mNewRegionPrefs.clear();
- // *TODO: clear environment settings of the previous region?
- // Request environment settings of the new region.
- LL_DEBUGS("Windlight") << "New viewer region: " << region_uuid << LL_ENDL;
- mCurRegionUUID = region_uuid;
- mInterpNextChangeMessage = interpolate;
- requestRegionSettings();
- // Let interested parties know agent region has been changed.
- mRegionChangeSignal();
- }