diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 0cb1ef990..8945b0058 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -85,7 +85,9 @@ set(viewer_SOURCE_FILES floaterao.cpp floatervoicelicense.cpp cofmgr.cpp - ascentdaycyclemanager.cpp + lldaycyclemanager.cpp + llenvmanager.cpp + llwlhandlers.cpp ascentfloatercontactgroups.cpp ascentkeyword.cpp ascentprefschat.cpp @@ -563,7 +565,9 @@ set(viewer_HEADER_FILES floaterao.h floatervoicelicense.h cofmgr.h - ascentdaycyclemanager.h + lldaycyclemanager.h + llenvmanager.h + llwlhandlers.h ascentfloatercontactgroups.h ascentkeyword.h ascentprefschat.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 4865bc22a..ad15efe6e 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9,6 +9,108 @@ settings_rlv.xml + WaterPresetName + + Comment + Water preset to use. May be superseded by region settings + Persist + 1 + Type + String + Value + Default + + SkyPresetName + + Comment + Sky preset to use. May be superseded by region settings + Persist + 1 + Type + String + Value + Default + + DayCycleName + + Comment + Day Cycle to use. May be superseded by region settings + Persist + 1 + Type + String + Value + Default + + UseEnvironmentFromRegion + + Comment + Choose whether to use the region's environment settings, or override them with the local settings. + Persist + 1 + Type + Boolean + Value + 1 + + UseEnvironmentFromRegionAlways + + Comment + Choose whether to always use the region's environment settings when they are available + or to allow the manual selections to remain unchanging. + Persist + 1 + Type + Boolean + Value + 1 + + UseDayCycle + + Comment + Whether to use use a day cycle or a fixed sky. + Persist + 1 + Type + Boolean + Value + 1 + + PhoenixInterpolateParcelWL + + Comment + PhoenixInterpolateParcelWL + Persist + 1 + Type + Boolean + Value + 1 + + PhoenixInterpolateSky + + Comment + PhoenixInterpolateSky + Persist + 1 + Type + Boolean + Value + 1 + + PhoenixInterpolateWater + + Comment + PhoenixInterpolateWater + Persist + 1 + Type + Boolean + Value + 1 + + + SGTextFadeDistance Comment diff --git a/indra/newview/ascentdaycyclemanager.cpp b/indra/newview/ascentdaycyclemanager.cpp deleted file mode 100644 index 159d486d5..000000000 --- a/indra/newview/ascentdaycyclemanager.cpp +++ /dev/null @@ -1,373 +0,0 @@ -/** - * @file ascentdaycyclemanager.cpp - * @Author Duncan Garrett - * Manager for Windlight Daycycles so we can actually save more than one - * - * Created August 27 2010 - * - * ALL SOURCE CODE IS PROVIDED "AS IS." THE CREATOR MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * k ilu bye - */ - -#include "llviewerprecompiledheaders.h" - -#include "ascentdaycyclemanager.h" - -#include "pipeline.h" -#include "llsky.h" - -#include "lldiriterator.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 "llwldaycycle.h" -#include "llfloaterwindlight.h" -#include "llfloaterdaycycle.h" -#include "llfloaterenvsettings.h" - -#include "curl/curl.h" - -AscentDayCycleManager * AscentDayCycleManager::sInstance = NULL; - -AscentDayCycleManager::AscentDayCycleManager() -{ -} - -AscentDayCycleManager::~AscentDayCycleManager() -{ -} - -void AscentDayCycleManager::loadPresets(const std::string& file_name) -{ - std::string path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/days", "")); - LL_INFOS2("AppInit", "Shaders") << "Loading Default Day Cycle preset from " << path_name << LL_ENDL; - - bool found = true; - LLDirIterator app_settings_iter(path_name, "*.xml"); - while(found) - { - std::string name; - found = app_settings_iter.next(name); - if(found) - { - - name=name.erase(name.length()-4); - - // bugfix for SL-46920: preventing filenames that break stuff. - char * curl_str = curl_unescape(name.c_str(), name.size()); - std::string unescaped_name(curl_str); - curl_free(curl_str); - curl_str = NULL; - - LL_DEBUGS2("AppInit", "Shaders") << "name: " << name << LL_ENDL; - loadPreset(unescaped_name,FALSE); - } - } - - // And repeat for user presets, note the user presets will modify any system presets already loaded - - std::string path_name2(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/days", "")); - LL_INFOS2("AppInit", "Shaders") << "Loading User Daycycle preset from " << path_name2 << LL_ENDL; - - found = true; - LLDirIterator user_settings_iter(path_name2, "*.xml"); - while(found) - { - std::string name; - found = user_settings_iter.next(name); - if(found) - { - name=name.erase(name.length()-4); - - // bugfix for SL-46920: preventing filenames that break stuff. - char * curl_str = curl_unescape(name.c_str(), name.size()); - std::string unescaped_name(curl_str); - curl_free(curl_str); - curl_str = NULL; - - LL_DEBUGS2("AppInit", "Shaders") << "name: " << name << LL_ENDL; - loadPreset(unescaped_name,FALSE); - } - } - -} - -void AscentDayCycleManager::savePresets(const std::string & fileName) -{ - //Nobody currently calls me, but if they did, then its reasonable to write the data out to the user's folder - //and not over the RO system wide version. - - LLSD paramsData(LLSD::emptyMap()); - - std::string pathName(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight", fileName)); - - /*for(std::map::iterator mIt = mParamList.begin(); - mIt != mParamList.end(); - ++mIt) - { - paramsData[mIt->first] = mIt->second.getAll(); - }*/ - - llofstream presetsXML(pathName); - - LLPointer formatter = new LLSDXMLFormatter(); - - formatter->format(paramsData, presetsXML, LLSDFormatter::OPTIONS_PRETTY); - - presetsXML.close(); -} - -void AscentDayCycleManager::loadPreset(const std::string & name,bool propagate) -{ - - // bugfix for SL-46920: preventing filenames that break stuff. - std::string escaped_filename = LLWeb::curlEscape(name); - - escaped_filename += ".xml"; - - std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/days", escaped_filename)); - llinfos << "Loading Day Cycle preset from " << pathName << llendl; - - llifstream presetsXML; - presetsXML.open(pathName.c_str()); - - // That failed, try loading from the users area instead. - if(!presetsXML) - { - pathName=gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/days", escaped_filename); - llinfos << "Loading User Day Cycle preset from " << pathName << llendl; - presetsXML.open(pathName.c_str()); - } - - if (presetsXML) - { - LLSD paramsData(LLSD::emptyMap()); - - LLPointer parser = new LLSDXMLParser(); - - parser->parse(presetsXML, paramsData, LLSDSerialize::SIZE_UNLIMITED); - - std::map::iterator mIt = mParamList.find(name); - if(mIt == mParamList.end()) - { - addParamSet(name, paramsData); - } - else - { - setParamSet(name, paramsData); - } - presetsXML.close(); - } - else - { - llwarns << "Can't find " << name << llendl; - return; - } - - -} - -void AscentDayCycleManager::savePreset(const std::string & name) -{ - // bugfix for SL-46920: preventing filenames that break stuff. - std::string escaped_filename = LLWeb::curlEscape(name); - - escaped_filename += ".xml"; - - // make an empty llsd - LLSD paramsData(LLSD::emptyMap()); - std::string pathName(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/days", escaped_filename)); - - // fill it with LLSD windlight params - //paramsData = mParamList[name].getAll(); - - // write to file - llofstream presetsXML(pathName); - LLPointer formatter = new LLSDXMLFormatter(); - formatter->format(paramsData, presetsXML, LLSDFormatter::OPTIONS_PRETTY); - presetsXML.close(); -} - -static LLFastTimer::DeclareTimer FTM_UPDATE_WLPARAM("Ascent WLMenu Sync"); -void AscentDayCycleManager::update(LLViewerCamera * cam) -{ - LLFastTimer ftm(FTM_UPDATE_WLPARAM); - - // sync menus if they exist - if(LLFloaterWindLight::isOpen()) - { - LLFloaterWindLight::instance()->syncMenu(); - } - if(LLFloaterDayCycle::isOpen()) - { - LLFloaterDayCycle::instance()->syncMenu(); - } - if(LLFloaterEnvSettings::isOpen()) - { - LLFloaterEnvSettings::instance()->syncMenu(); - } - - stop_glerror(); -} - -// static -void AscentDayCycleManager::initClass(void) -{ - instance(); -} - -// static -void AscentDayCycleManager::cleanupClass() -{ - delete sInstance; - sInstance = NULL; -} - -void AscentDayCycleManager::resetAnimator(F32 curTime, bool run) -{ - mAnimator.setTrack(mDay.mTimeMap, mDay.mDayRate, - curTime, run); - - return; -} -bool AscentDayCycleManager::addParamSet(const std::string& name, LLWLDayCycle& param) -{ - // add a new one if not one there already - std::map::iterator mIt = mParamList.find(name); - if(mIt == mParamList.end()) - { - mParamList[name] = param; - return true; - } - - return false; -} - -BOOL AscentDayCycleManager::addParamSet(const std::string& name, LLSD const & param) -{ - // add a new one if not one there already - std::map::const_iterator finder = mParamList.find(name); - if(finder == mParamList.end()) - { - mParamList[name].mName = name; - return TRUE; - } - else - { - return FALSE; - } -} - -bool AscentDayCycleManager::getParamSet(const std::string& name, LLWLDayCycle& param) -{ - // find it and set it - std::map::iterator mIt = mParamList.find(name); - if(mIt != mParamList.end()) - { - param = mParamList[name]; - param.mName = name; - return true; - } - - return false; -} - -bool AscentDayCycleManager::setParamSet(const std::string& name, LLWLDayCycle& param) -{ - mParamList[name] = param; - - return true; -} - -bool AscentDayCycleManager::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; - } - - return true; -} - -bool AscentDayCycleManager::removeParamSet(const std::string& name, bool delete_from_disk) -{ - // remove from param list - std::map::iterator mIt = mParamList.find(name); - if(mIt != mParamList.end()) - { - mParamList.erase(mIt); - } - - F32 key; - - // remove all references - bool stat = true; - do - { - // get it - stat = mDay.getKey(name, key); - if(stat == false) - { - break; - } - - // and remove - stat = mDay.removeKey(key); - - } while(stat == true); - - if(delete_from_disk) - { - std::string path_name(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/days", "")); - - // use full curl escaped name - std::string escaped_name = LLWeb::curlEscape(name); - - gDirUtilp->deleteFilesInDir(path_name, escaped_name + ".xml"); - } - - return true; -} - - -// static -AscentDayCycleManager * AscentDayCycleManager::instance() -{ - if(NULL == sInstance) - { - sInstance = new AscentDayCycleManager(); - - sInstance->loadPresets(LLStringUtil::null); - - // load the day - sInstance->mDay.loadDayCycle(gSavedSettings.getString("AscentActiveDayCycle")); - - // *HACK - sets cloud scrolling to what we want... fix this better in the future - sInstance->getParamSet("Default", sInstance->mCurParams); - - // set it to noon - sInstance->resetAnimator(0.5, true); - - // but use linden time sets it to what the estate is - sInstance->mAnimator.mUseLindenTime = true; - } - - return sInstance; -} diff --git a/indra/newview/ascentdaycyclemanager.h b/indra/newview/ascentdaycyclemanager.h deleted file mode 100644 index 6c84901c9..000000000 --- a/indra/newview/ascentdaycyclemanager.h +++ /dev/null @@ -1,109 +0,0 @@ -/** - * @file ascentdaycyclemanager.h - * @Author Duncan Garrett - * Manager for Windlight Daycycles so we can actually save more than one - * - * Created October 04 2010 - * - * ALL SOURCE CODE IS PROVIDED "AS IS." THE CREATOR MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * k ilu bye - */ - -#ifndef ASCENT_DAYCYCLEMANAGER_H -#define ASCENT_DAYCYCLEMANAGER_H - -#include -#include -#include "llwldaycycle.h" -#include "llwlanimator.h" -#include "llwldaycycle.h" -#include "llviewercamera.h" - -/// WindLight parameter manager class - what controls all the wind light shaders -class AscentDayCycleManager -{ -public: - - AscentDayCycleManager(); - ~AscentDayCycleManager(); - - /// load a preset file - void loadPresets(const std::string & fileName); - - /// save the preset file - void savePresets(const std::string & fileName); - - /// load an individual preset into the sky - void loadPreset(const std::string & name,bool propogate=true); - - /// save the parameter presets to file - void savePreset(const std::string & name); - - /// 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); - - - /// Perform global initialization for this class. - static void initClass(void); - - // Cleanup of global data that's only inited once per class. - static void cleanupClass(); - - /// add a param to the list - bool addParamSet(const std::string& name, LLWLDayCycle& 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, LLWLDayCycle& param); - - /// set the param in the list with a new param - bool setParamSet(const std::string& name, LLWLDayCycle& 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); - - // singleton pattern implementation - static AscentDayCycleManager * instance(); - -public: - - // helper variables - LLWLAnimator mAnimator; - - - // list of params and how they're cycled for days - LLWLDayCycle mDay; - - LLWLDayCycle mCurParams; - - /// Sun Delta Terrain tweak variables. - F32 mSunDeltaYaw; - - // list of all the day cycles, listed by name - std::map mParamList; - - -private: - // our parameter manager singleton instance - static AscentDayCycleManager * sInstance; - -}; - -#endif diff --git a/indra/newview/lldaycyclemanager.cpp b/indra/newview/lldaycyclemanager.cpp new file mode 100644 index 000000000..dffeb2346 --- /dev/null +++ b/indra/newview/lldaycyclemanager.cpp @@ -0,0 +1,232 @@ +/** + * @file lldaycyclemanager.cpp + * @brief Implementation for the LLDayCycleManager class. + * + * $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 "llweb.h" +#include "llwlparamset.h" +#include "llwlparammanager.h" +#include "lldaycyclemanager.h" +#include "lldiriterator.h" + +void LLDayCycleManager::getPresetNames(preset_name_list_t& names) const +{ + names.clear(); + + for (dc_map_t::const_iterator it = mDayCycleMap.begin(); it != mDayCycleMap.end(); ++it) + { + names.push_back(it->first); + } +} + +void LLDayCycleManager::getPresetNames(preset_name_list_t& user, preset_name_list_t& sys) const +{ + user.clear(); + sys.clear(); + + for (dc_map_t::const_iterator it = mDayCycleMap.begin(); it != mDayCycleMap.end(); ++it) + { + const std::string& name = it->first; + + if (isSystemPreset(name)) + { + sys.push_back(name); + } + else + { + user.push_back(name); + } + } +} + +void LLDayCycleManager::getUserPresetNames(preset_name_list_t& user) const +{ + preset_name_list_t sys; // unused + getPresetNames(user, sys); +} + +bool LLDayCycleManager::getPreset(const std::string name, LLWLDayCycle& day_cycle) const +{ + dc_map_t::const_iterator it = mDayCycleMap.find(name); + if (it == mDayCycleMap.end()) + { + return false; + } + + day_cycle = it->second; + return true; +} + +bool LLDayCycleManager::getPreset(const std::string name, LLSD& day_cycle) const +{ + LLWLDayCycle dc; + if (!getPreset(name, dc)) + { + return false; + } + + day_cycle = dc.asLLSD(); + return true; +} + +bool LLDayCycleManager::presetExists(const std::string name) const +{ + LLWLDayCycle dummy; + return getPreset(name, dummy); +} + +bool LLDayCycleManager::isSystemPreset(const std::string& name) const +{ + return gDirUtilp->fileExists(getSysDir() + LLWeb::curlEscape(name) + ".xml"); +} + +bool LLDayCycleManager::savePreset(const std::string& name, const LLSD& data) +{ + // Save given preset. + LLWLDayCycle day; + day.loadDayCycle(data, LLEnvKey::SCOPE_LOCAL); + day.save(getUserDir() + LLWeb::curlEscape(name) + ".xml"); + + // Add it to our map. + addPreset(name, data); + mModifySignal(); + return true; +} + +bool LLDayCycleManager::deletePreset(const std::string& name) +{ + // Remove it from the map. + dc_map_t::iterator it = mDayCycleMap.find(name); + if (it == mDayCycleMap.end()) + { + LL_WARNS("Windlight") << "No day cycle named " << name << LL_ENDL; + return false; + } + mDayCycleMap.erase(it); + + // Remove from the filesystem. + std::string filename = LLWeb::curlEscape(name) + ".xml"; + if (gDirUtilp->fileExists(getUserDir() + filename)) + { + gDirUtilp->deleteFilesInDir(getUserDir(), filename); + } + + // Signal interested parties. + mModifySignal(); + return true; +} + +bool LLDayCycleManager::isSkyPresetReferenced(const std::string& preset_name) const +{ + // We're traversing local day cycles, they can only reference local skies. + LLWLParamKey key(preset_name, LLEnvKey::SCOPE_LOCAL); + + for (dc_map_t::const_iterator it = mDayCycleMap.begin(); it != mDayCycleMap.end(); ++it) + { + if (it->second.hasReferencesTo(key)) + { + return true; + } + } + + return false; +} + +boost::signals2::connection LLDayCycleManager::setModifyCallback(const modify_signal_t::slot_type& cb) +{ + return mModifySignal.connect(cb); +} + +// virtual +void LLDayCycleManager::initSingleton() +{ + LL_DEBUGS("Windlight") << "Loading all day cycles" << LL_ENDL; + loadAllPresets(); +} + +void LLDayCycleManager::loadAllPresets() +{ + mDayCycleMap.clear(); + + // First, load system (coming out of the box) day cycles. + loadPresets(getSysDir()); + + // Then load user presets. Note that user day cycles will modify any system ones already loaded. + loadPresets(getUserDir()); +} + +void LLDayCycleManager::loadPresets(const std::string& dir) +{ + LLDirIterator dir_iter(dir, "*.xml"); + + while (1) + { + std::string file; + if (!dir_iter.next(file)) break; // no more files + loadPreset(dir + file); + } +} + +bool LLDayCycleManager::loadPreset(const std::string& path) +{ + LLSD data = LLWLDayCycle::loadDayCycleFromPath(path); + if (data.isUndefined()) + { + llwarns << "Error loading day cycle from " << path << llendl; + return false; + } + + std::string name(gDirUtilp->getBaseFileName(LLURI::unescape(path), /*strip_exten = */ true)); + addPreset(name, data); + + return true; +} + +bool LLDayCycleManager::addPreset(const std::string& name, const LLSD& data) +{ + if (name.empty()) + { + llassert(name.empty()); + return false; + } + + LLWLDayCycle day; + day.loadDayCycle(data, LLEnvKey::SCOPE_LOCAL); + mDayCycleMap[name] = day; + return true; +} + +// static +std::string LLDayCycleManager::getSysDir() +{ + return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/days", ""); +} + +// static +std::string LLDayCycleManager::getUserDir() +{ + return gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS , "windlight/days", ""); +} diff --git a/indra/newview/lldaycyclemanager.h b/indra/newview/lldaycyclemanager.h new file mode 100644 index 000000000..3d2144960 --- /dev/null +++ b/indra/newview/lldaycyclemanager.h @@ -0,0 +1,84 @@ +/** + * @file lldaycyclemanager.h + * @brief Implementation for the LLDayCycleManager class. + * + * $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_LLDAYCYCLEMANAGER_H +#define LL_LLDAYCYCLEMANAGER_H + +#include +#include + +#include "llwldaycycle.h" +#include "llwlparammanager.h" + +/** + * WindLight day cycles manager class + * + * Provides interface for accessing, loading and saving day cycles. + */ +class LLDayCycleManager : public LLSingleton +{ + LOG_CLASS(LLDayCycleManager); + +public: + typedef std::list preset_name_list_t; + + typedef std::map dc_map_t; + typedef boost::signals2::signal 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, LLSD& day_cycle) const; + bool presetExists(const std::string name) const; + bool isSystemPreset(const std::string& name) const; + bool savePreset(const std::string& name, const LLSD& data); + bool deletePreset(const std::string& name); + + /// @return true if there is a day cycle that refers to the sky preset. + bool isSkyPresetReferenced(const std::string& preset_name) const; + + /// Emitted when a preset gets added or deleted. + boost::signals2::connection setModifyCallback(const modify_signal_t::slot_type& cb); + +private: + friend class LLSingleton; + /*virtual*/ void initSingleton(); + + void loadAllPresets(); + void loadPresets(const std::string& dir); + bool loadPreset(const std::string& path); + bool addPreset(const std::string& name, const LLSD& data); + + static std::string getSysDir(); + static std::string getUserDir(); + + dc_map_t mDayCycleMap; + modify_signal_t mModifySignal; +}; + +#endif // LL_LLDAYCYCLEMANAGER_H diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 438e40524..0776bf772 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -116,7 +116,7 @@ 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 = LLWaterParamManager::getInstance()->getFogColor(); sWaterFogColor.mV[3] = 0; } @@ -563,7 +563,7 @@ void LLDrawPoolWater::shade() //bind normal map S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP); - LLWaterParamManager * param_mgr = &LLWaterParamManager::instance(); + LLWaterParamManager * param_mgr = LLWaterParamManager::getInstance(); // change mWaterNormp if needed if (mWaterNormp->getID() != param_mgr->getNormalMapID()) diff --git a/indra/newview/llenvmanager.cpp b/indra/newview/llenvmanager.cpp new file mode 100644 index 000000000..3f60c957b --- /dev/null +++ b/indra/newview/llenvmanager.cpp @@ -0,0 +1,697 @@ +/** + * @file llenvmanager.cpp + * @brief Implementation of classes managing WindLight and water settings. + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/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 "kcwlinterface.h" +#include "rlvhandler.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::getInstance(); + 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::getInstance()->mCurParams.setAll(params); + return true; +} + +bool LLEnvManagerNew::useSkyPreset(const std::string& name, bool interpolate /*= false*/) +{ + LLWLParamManager* sky_mgr = LLWLParamManager::getInstance(); + 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(), interpolate); + return true; +} + +bool LLEnvManagerNew::useSkyParams(const LLSD& params) +{ + LL_DEBUGS("Windlight") << "Displaying sky params" << LL_ENDL; + LLWLParamManager::getInstance()->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::getInstance()->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::getInstance()->applyDayCycleParams(params, scope); +} + +void LLEnvManagerNew::setUseRegionSettings(bool val, bool interpolate /*= false*/) +{ + mUserPrefs.setUseRegionSettings(val); + saveUserPrefs(); + updateManagersFromPrefs(interpolate); +} + +void LLEnvManagerNew::setUseWaterPreset(const std::string& name, bool interpolate /*= false*/) +{ + // *TODO: make sure the preset exists. + if (name.empty()) + { + llwarns << "Empty water preset name passed" << llendl; + return; + } + + mUserPrefs.setUseWaterPreset(name); + saveUserPrefs(); + updateManagersFromPrefs(interpolate); +} + +void LLEnvManagerNew::setUseSkyPreset(const std::string& name, bool interpolate /*= false*/) +{ + // *TODO: make sure the preset exists. + if (name.empty()) + { + llwarns << "Empty sky preset name passed" << llendl; + return; + } + + mUserPrefs.setUseSkyPreset(name); + saveUserPrefs(); + updateManagersFromPrefs(interpolate); +} + +void LLEnvManagerNew::setUseDayCycle(const std::string& name, bool interpolate /*= false*/) +{ + if (!LLDayCycleManager::instance().presetExists(name)) + { + llwarns << "Invalid day cycle name passed" << llendl; + return; + } + + mUserPrefs.setUseDayCycle(name); + saveUserPrefs(); + updateManagersFromPrefs(interpolate); +} + +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::getInstance()->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::getInstance()->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::getInstance()->refreshRegionPresets(); + + // Use the region settings if parcel settings didnt override it already -KC + if (true /*KCWindlightInterface::instance().haveParcelOverride(new_settings)*/) + { + // If using server settings, update managers. + if (getUseRegionSettings()) + { + updateManagersFromPrefs(mInterpNextChangeMessage); + } + //bit of a hacky override since I've repurposed many of the settings and methods here -KC + //NOTE* It might not be a good idea to do this if under RLV_BHVR_SETENV -KC + else if (gSavedSettings.getBOOL("UseEnvironmentFromRegionAlways") + && !(rlv_handler_t::isEnabled() && gRlvHandler.hasBehaviour(RLV_BHVR_SETENV))) + { + setUseRegionSettings(true, 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 interpolate /*= false*/) +{ + 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(), interpolate); + } + } + + // If something went wrong, fall back to defaults. + if (!success) + { + // *TODO: fix user prefs + useDefaultSky(); + } +} + +void LLEnvManagerNew::updateWaterFromPrefs(bool interpolate) +{ + LLWaterParamManager* water_mgr = LLWaterParamManager::getInstance(); + 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(interpolate); +} + +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(); +} diff --git a/indra/newview/llenvmanager.h b/indra/newview/llenvmanager.h new file mode 100644 index 000000000..ad7550aff --- /dev/null +++ b/indra/newview/llenvmanager.h @@ -0,0 +1,286 @@ +/** + * @file llenvmanager.h + * @brief Declaration of classes managing WindLight and water settings. + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLENVMANAGER_H +#define LL_LLENVMANAGER_H + +#include "llmemory.h" +#include "llsd.h" +#include + +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; +}; + +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: + | + */ +class LLEnvManagerNew : public LLSingleton +{ + LOG_CLASS(LLEnvManagerNew); +public: + typedef boost::signals2::signal prefs_change_signal_t; + typedef boost::signals2::signal region_settings_change_signal_t; + typedef boost::signals2::signal region_change_signal_t; + typedef boost::signals2::signal region_settings_applied_signal_t; + + LLEnvManagerNew(); + + // 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 interpolate = false); + 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, bool interpolate = false); + void setUseWaterPreset(const std::string& name, bool interpolate = false); + void setUseSkyPreset(const std::string& name, bool interpolate = false); + void setUseDayCycle(const std::string& name, bool interpolate = false); + 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 setRegionChangeCallback(const region_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 onRegionCrossing(); + void onTeleport(); + void onRegionSettingsResponse(const LLSD& content); + void onRegionSettingsApplyResponse(bool ok); + +private: + friend class LLSingleton; + /*virtual*/ void initSingleton(); + + void loadUserPrefs(); + void saveUserPrefs(); + + void updateSkyFromPrefs(bool interpolate = false); + void updateWaterFromPrefs(bool interpolate); + void updateManagersFromPrefs(bool interpolate); + +public: + bool useRegionSky(); + bool useRegionWater(); + +private: + bool useDefaultSky(); + bool useDefaultWater(); + + void onRegionChange(bool interpolate); + + /// 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_change_signal_t mRegionChangeSignal; + + /// 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/llfloaterdaycycle.cpp b/indra/newview/llfloaterdaycycle.cpp index 02ea83fb2..12e26dbe6 100644 --- a/indra/newview/llfloaterdaycycle.cpp +++ b/indra/newview/llfloaterdaycycle.cpp @@ -37,12 +37,9 @@ #include "pipeline.h" #include "llsky.h" -#include "llboost.h" #include "llsliderctrl.h" #include "llmultislider.h" #include "llmultisliderctrl.h" -#include "llnotifications.h" -#include "llnotificationsutil.h" #include "llspinctrl.h" #include "llcheckboxctrl.h" #include "lluictrlfactory.h" @@ -57,16 +54,12 @@ #include "llviewerwindow.h" #include "llwlparamset.h" -#include "llwldaycycle.h" #include "llwlparammanager.h" -#include "ascentdaycyclemanager.h" //Ascent Addition #include "llpostprocess.h" #include "llfloaterwindlight.h" LLFloaterDayCycle* LLFloaterDayCycle::sDayCycle = NULL; - -std::set LLFloaterDayCycle::sDefaultPresets; std::map LLFloaterDayCycle::sSliderToKey; const F32 LLFloaterDayCycle::sHoursPerDay = 24.0f; @@ -79,11 +72,12 @@ LLFloaterDayCycle::LLFloaterDayCycle() : LLFloater(std::string("Day Cycle Floate if(keyCombo != NULL) { - std::map::const_iterator mIt = - LLWLParamManager::getInstance()->getPresets().begin(); - for(; mIt != LLWLParamManager::getInstance()->getPresets().end(); mIt++) + LLWLParamManager::preset_name_list_t local_presets; + LLWLParamManager::getInstance()->getLocalPresetNames(local_presets); + + for (LLWLParamManager::preset_name_list_t::const_iterator it = local_presets.begin(); it != local_presets.end(); ++it) { - keyCombo->add(std::string(mIt->first)); + keyCombo->add(*it); } // set defaults on combo boxes @@ -95,37 +89,6 @@ LLFloaterDayCycle::LLFloaterDayCycle() : LLFloater(std::string("Day Cycle Floate sldr->addSlider(); - // add the combo boxes - LLComboBox* comboBox = getChild("DayCyclePresetsCombo"); - - if(comboBox != NULL) { - - std::map::iterator mIt = - AscentDayCycleManager::instance()->mParamList.begin(); - for(; mIt != AscentDayCycleManager::instance()->mParamList.end(); mIt++) - { - comboBox->add(mIt->first); - } - - // entry for when we're in estate time - comboBox->add(LLStringUtil::null); - - // set defaults on combo boxes - comboBox->selectByValue(LLSD("Default")); - } - - // add the list of presets - std::string def_days = getString("DaycycleDefaultNames"); - - // no editing or deleting of the blank string - sDefaultPresets.insert(""); - boost_tokenizer tokens(def_days, boost::char_separator(":")); - for (boost_tokenizer::iterator token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter) - { - std::string tok(*token_iter); - //sDefaultPresets.insert(tok); - } - // load it up initCallbacks(); } @@ -168,15 +131,6 @@ void LLFloaterDayCycle::initCallbacks(void) childSetAction("WLLoadDayCycle", onLoadDayCycle, NULL); childSetAction("WLSaveDayCycle", onSaveDayCycle, NULL); - LLComboBox* comboBox = getChild("DayCyclePresetsCombo"); - - //childSetAction("WLLoadPreset", onLoadPreset, comboBox); - childSetAction("DayCycleNewPreset", onNewPreset, comboBox); - childSetAction("DayCycleSavePreset", onSavePreset, comboBox); - childSetAction("DayCycleDeletePreset", onDeletePreset, comboBox); - - comboBox->setCommitCallback(onChangePresetName); - childSetAction("WLAddKey", onAddKey, NULL); childSetAction("WLDeleteKey", onDeleteKey, NULL); } @@ -209,7 +163,7 @@ void LLFloaterDayCycle::syncMenu() secSpin->setValue(sec); // turn off Use Estate Time button if it's already being used - if( LLWLParamManager::getInstance()->mAnimator.mUseLindenTime == true) + if( LLWLParamManager::getInstance()->mAnimator.getUseLindenTime()) { LLFloaterDayCycle::sDayCycle->childDisable("WLUseLindenTime"); } @@ -228,11 +182,11 @@ void LLFloaterDayCycle::syncSliderTrack() sSliderToKey.clear(); // add sliders - std::map::iterator mIt = + std::map::iterator mIt = LLWLParamManager::getInstance()->mDay.mTimeMap.begin(); - for(; mIt != LLWLParamManager::getInstance()->mDay.mTimeMap.end(); mIt++) + for(; mIt != LLWLParamManager::getInstance()->mDay.mTimeMap.end(); mIt++) { - addSliderKey(mIt->first * sHoursPerDay, mIt->second); + addSliderKey(mIt->first * sHoursPerDay, mIt->second.name); } } @@ -260,7 +214,7 @@ void LLFloaterDayCycle::syncTrack() std::map::iterator mIt = sSliderToKey.begin(); for(; mIt != sSliderToKey.end(); mIt++) { - LLWLParamManager::getInstance()->mDay.addKey(mIt->second.time / sHoursPerDay, + LLWLParamManager::getInstance()->mDay.addKey(mIt->second.time / sHoursPerDay, mIt->second.presetName); } @@ -315,216 +269,6 @@ void LLFloaterDayCycle::onClose(bool app_quitting) } } -void LLFloaterDayCycle::onNewPreset(void* userData) -{ - LLNotificationsUtil::add("NewDaycyclePreset", LLSD(), LLSD(), newPromptCallback); -} - -void LLFloaterDayCycle::onSavePreset(void* userData) -{ - // get the name - LLComboBox* comboBox = sDayCycle->getChild( - "DayCyclePresetsCombo"); - - // don't save the empty name - if(comboBox->getSelectedItemLabel() == "") - { - return; - } - - // check to see if it's a default and shouldn't be overwritten - std::set::iterator sIt = sDefaultPresets.find( - comboBox->getSelectedItemLabel()); - if(sIt != sDefaultPresets.end() && !gSavedSettings.getBOOL("SkyEditPresets")) - { - LLNotificationsUtil::add("WLNoEditDefault"); - return; - } - - LLWLParamManager::getInstance()->mCurParams.mName = - comboBox->getSelectedItemLabel(); - - LLNotificationsUtil::add("WLSavePresetAlert", LLSD(), LLSD(), saveAlertCallback); -} - -bool LLFloaterDayCycle::saveAlertCallback(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - // if they choose save, do it. Otherwise, don't do anything - if(option == 0) - { - LLComboBox* combo_box = sDayCycle->getChild("DayCyclePresetsCombo"); - // comment this back in to save to file - LLWLParamManager::getInstance()->mDay.saveDayCycle(combo_box->getSelectedValue().asString()); - } - return false; -} - -void LLFloaterDayCycle::onDeletePreset(void* userData) -{ - LLComboBox* combo_box = sDayCycle->getChild( - "DayCyclePresetsCombo"); - - if(combo_box->getSelectedValue().asString() == "") - { - return; - } - - LLSD args; - args["SKY"] = combo_box->getSelectedValue().asString(); - LLNotificationsUtil::add("WLDeletePresetAlert", args, LLSD(), - boost::bind(&LLFloaterDayCycle::deleteAlertCallback, sDayCycle, _1, _2)); -} - -bool LLFloaterDayCycle::deleteAlertCallback(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - - // if they choose delete, do it. Otherwise, don't do anything - if(option == 0) - { - LLComboBox* combo_box = getChild( - "DayCyclePresetsCombo"); - LLFloaterDayCycle* day_cycle = NULL; - LLComboBox* key_combo = NULL; - LLMultiSliderCtrl* mult_sldr = NULL; - - if(LLFloaterDayCycle::isOpen()) - { - day_cycle = LLFloaterDayCycle::instance(); - key_combo = day_cycle->getChild( - "WLKeyPresets"); - mult_sldr = day_cycle->getChild("WLDayCycleKeys"); - } - - std::string name(combo_box->getSelectedValue().asString()); - - // check to see if it's a default and shouldn't be deleted - std::set::iterator sIt = sDefaultPresets.find(name); - if(sIt != sDefaultPresets.end()) - { - LLNotificationsUtil::add("WLNoEditDefault"); - return false; - } - - AscentDayCycleManager::instance()->removeParamSet(name, true); - - // remove and choose another - S32 new_index = combo_box->getCurrentIndex(); - - combo_box->remove(name); - if(key_combo != NULL) - { - key_combo->remove(name); - - // remove from slider, as well - day_cycle->deletePreset(name); - } - - // pick the previously selected index after delete - if(new_index > 0) - { - new_index--; - } - - if(combo_box->getItemCount() > 0) - { - combo_box->setCurrentByIndex(new_index); - } - } - return false; -} - -bool LLFloaterDayCycle::newPromptCallback(const LLSD& notification, const LLSD& response) -{ - std::string text = response["message"].asString(); - S32 option = LLNotification::getSelectedOption(notification, response); - - if(text == "") - { - return false; - } - - if(option == 0) { - LLComboBox* comboBox = sDayCycle->getChild( - "DayCyclePresetsCombo"); - - LLFloaterDayCycle* sDayCycle = NULL; - LLComboBox* keyCombo = NULL; - if(LLFloaterDayCycle::isOpen()) - { - sDayCycle = LLFloaterDayCycle::instance(); - keyCombo = sDayCycle->getChild( - "WLKeyPresets"); - } - - // add the current parameters to the list - // see if it's there first - std::map::iterator mIt = - AscentDayCycleManager::instance()->mParamList.find(text); - - // if not there, add a new one - if(mIt == AscentDayCycleManager::instance()->mParamList.end()) - { - AscentDayCycleManager::instance()->addParamSet(text, - AscentDayCycleManager::instance()->mCurParams); - comboBox->add(text); - comboBox->sortByName(); - - // add a blank to the bottom - comboBox->selectFirstItem(); - if(comboBox->getSimple() == "") - { - comboBox->remove(0); - } - comboBox->add(LLStringUtil::null); - - comboBox->setSelectedByValue(text, true); - if(LLFloaterDayCycle::isOpen()) - { - keyCombo->add(text); - keyCombo->sortByName(); - } - LLWLParamManager::getInstance()->mDay.saveDayCycle(text); - - // otherwise, send a message to the user - } - else - { - LLNotificationsUtil::add("ExistsSkyPresetAlert"); - } - } - return false; -} - -void LLFloaterDayCycle::onChangePresetName(LLUICtrl* ctrl, void * userData) -{ - - LLComboBox * combo_box = static_cast(ctrl); - - if(combo_box->getSimple() == "") - { - return; - } - - LLWLParamManager::getInstance()->mDay.loadDayCycle(combo_box->getSelectedValue().asString()); - gSavedSettings.setString("AscentActiveDayCycle", combo_box->getSelectedValue().asString()); - // sync it all up - syncSliderTrack(); - syncMenu(); - - // set the param manager's track to the new one - LLMultiSliderCtrl* tSldr; - tSldr = sDayCycle->getChild( - "WLTimeSlider"); - LLWLParamManager::getInstance()->resetAnimator( - tSldr->getCurSliderValue() / sHoursPerDay, false); - - // and draw it - LLWLParamManager::getInstance()->mAnimator.update( - LLWLParamManager::getInstance()->mCurParams); -} - void LLFloaterDayCycle::onRunAnimSky(void* userData) { // if no keys, do nothing @@ -541,7 +285,7 @@ void LLFloaterDayCycle::onRunAnimSky(void* userData) tSldr = sDayCycle->getChild("WLTimeSlider"); // turn off linden time - LLWLParamManager::getInstance()->mAnimator.mUseLindenTime = false; + //LLWLParamManager::getInstance()->mAnimator.mUseLindenTime = false; // set the param manager's track to the new one LLWLParamManager::getInstance()->resetAnimator( @@ -558,23 +302,22 @@ void LLFloaterDayCycle::onStopAnimSky(void* userData) } // turn off animation and using linden time - LLWLParamManager::getInstance()->mAnimator.mIsRunning = false; - LLWLParamManager::getInstance()->mAnimator.mUseLindenTime = false; + LLWLParamManager::getInstance()->mAnimator.deactivate(); } void LLFloaterDayCycle::onUseLindenTime(void* userData) { - LLFloaterDayCycle* dc = LLFloaterDayCycle::instance(); - LLComboBox* box = dc->getChild("DayCyclePresetsCombo"); + LLFloaterWindLight* wl = LLFloaterWindLight::instance(); + LLComboBox* box = wl->getChild("WLPresetsCombo"); box->selectByValue(""); - LLWLParamManager::getInstance()->mAnimator.mIsRunning = true; - LLWLParamManager::getInstance()->mAnimator.mUseLindenTime = true; + LLWLParamManager::getInstance()->mAnimator.activate(LLWLAnimator::TIME_LINDEN); + LLEnvManagerNew::instance().setUseDayCycle(LLEnvManagerNew::instance().getDayCycleName()); } void LLFloaterDayCycle::onLoadDayCycle(void* userData) { - //LLWLParamManager::getInstance()->mDay.loadDayCycle("Default.xml"); + LLWLParamManager::getInstance()->mDay.loadDayCycleFromFile("Default.xml"); // sync it all up syncSliderTrack(); @@ -594,7 +337,7 @@ void LLFloaterDayCycle::onLoadDayCycle(void* userData) void LLFloaterDayCycle::onSaveDayCycle(void* userData) { - //LLWLParamManager::getInstance()->mDay.saveDayCycle("Default.xml"); + LLWLParamManager::getInstance()->mDay.saveDayCycle("Default.xml"); } @@ -608,8 +351,7 @@ void LLFloaterDayCycle::onTimeSliderMoved(LLUICtrl* ctrl, void* userData) // set the value, turn off animation LLWLParamManager::getInstance()->mAnimator.setDayTime((F64)val); - LLWLParamManager::getInstance()->mAnimator.mIsRunning = false; - LLWLParamManager::getInstance()->mAnimator.mUseLindenTime = false; + LLWLParamManager::getInstance()->mAnimator.deactivate(); // then call update once LLWLParamManager::getInstance()->mAnimator.update( diff --git a/indra/newview/llfloaterdaycycle.h b/indra/newview/llfloaterdaycycle.h index 17330f8ca..d23003554 100644 --- a/indra/newview/llfloaterdaycycle.h +++ b/indra/newview/llfloaterdaycycle.h @@ -99,30 +99,10 @@ public: /// delete a key frame static void onDeleteKey(void* userData); - /// when user hits the load preset button - static void onNewPreset(void* userData); - - /// when user hits the save preset button - static void onSavePreset(void* userData); - - /// prompts a user when overwriting a preset - static bool saveAlertCallback(const LLSD& notification, const LLSD& response); - - /// when user hits the save preset button - static void onDeletePreset(void* userData); - - /// prompts a user when overwriting a preset - bool deleteAlertCallback(const LLSD& notification, const LLSD& response); - - static bool newPromptCallback(const LLSD& notification, const LLSD& response); - - /// what to do when you change the preset name - static void onChangePresetName(LLUICtrl* ctrl, void* userData); - - /// button to load day OLD -HgB + /// button to load day static void onLoadDayCycle(void* userData); - /// button to save day OLD -HgB + /// button to save day static void onSaveDayCycle(void* userData); /// toggle for Linden time @@ -160,9 +140,6 @@ private: // map of sliders to parameters static std::map sSliderToKey; - //Presets default - static std::set sDefaultPresets; - static const F32 sHoursPerDay; }; diff --git a/indra/newview/llfloaterenvsettings.cpp b/indra/newview/llfloaterenvsettings.cpp index e021e365c..905ad3b68 100644 --- a/indra/newview/llfloaterenvsettings.cpp +++ b/indra/newview/llfloaterenvsettings.cpp @@ -133,7 +133,7 @@ void LLFloaterEnvSettings::syncMenu() param_mgr->setDensitySliderValue(param_mgr->mFogDensity.mExp); // turn off Use Estate Time button if it's already being used - if(LLWLParamManager::getInstance()->mAnimator.mUseLindenTime) + if(LLWLParamManager::getInstance()->mAnimator.getUseLindenTime()) { childDisable("EnvUseEstateTimeButton"); } else { @@ -218,8 +218,7 @@ void LLFloaterEnvSettings::onChangeDayTime(LLUICtrl* ctrl, void* userData) sldr = sEnvSettings->getChild("EnvTimeSlider"); // deactivate animator - LLWLParamManager::getInstance()->mAnimator.mIsRunning = false; - LLWLParamManager::getInstance()->mAnimator.mUseLindenTime = false; + LLWLParamManager::getInstance()->mAnimator.deactivate(); F32 val = sldr->getValueF32() + 0.25f; if(val > 1.0) @@ -311,8 +310,8 @@ void LLFloaterEnvSettings::onUseEstateTime(void* userData) box->selectByValue(""); } - LLWLParamManager::getInstance()->mAnimator.mIsRunning = true; - LLWLParamManager::getInstance()->mAnimator.mUseLindenTime = true; + LLWLParamManager::getInstance()->mAnimator.activate(LLWLAnimator::TIME_LINDEN); + LLEnvManagerNew::instance().setUseDayCycle(LLEnvManagerNew::instance().getDayCycleName()); } std::string LLFloaterEnvSettings::timeToString(F32 curTime) diff --git a/indra/newview/llfloaterwater.cpp b/indra/newview/llfloaterwater.cpp index 3b04f9387..04ef4e5af 100644 --- a/indra/newview/llfloaterwater.cpp +++ b/indra/newview/llfloaterwater.cpp @@ -49,12 +49,16 @@ #include "llfloaterdaycycle.h" #include "llboost.h" #include "llmultisliderctrl.h" -#include "llnotificationsutil.h" + +#include "llagent.h" +#include "llinventorymodel.h" +#include "llviewerinventory.h" #include "v4math.h" #include "llviewerdisplay.h" #include "llviewercontrol.h" #include "llviewerwindow.h" +#include "llsavedsettingsglue.h" #include "llwaterparamset.h" #include "llwaterparammanager.h" @@ -71,21 +75,15 @@ LLFloaterWater::LLFloaterWater() : LLFloater(std::string("water floater")) LLUICtrlFactory::getInstance()->buildFloater(this, "floater_water.xml"); // add the combo boxes - LLComboBox* comboBox = getChild("WaterPresetsCombo"); + mWaterPresetCombo = getChild("WaterPresetsCombo"); - if(comboBox != NULL) { - - std::map::const_iterator mIt = - LLWaterParamManager::getInstance()->getPresets().begin(); - for(; mIt != LLWaterParamManager::getInstance()->getPresets().end(); mIt++) - { - comboBox->add(mIt->first); - } - - // set defaults on combo boxes - comboBox->selectByValue(LLSD("Default")); + if (mWaterPresetCombo != NULL) + { + populateWaterPresetsList(); + mWaterPresetCombo->setCommitCallback(onChangePresetName); } + std::string def_water = getString("WLDefaultWaterNames"); // no editing or deleting of the blank string @@ -152,12 +150,10 @@ void LLFloaterWater::initCallbacks(void) { childSetCommitCallback("WaterBlurMult", onFloatControlMoved, ¶m_mgr->mBlurMultiplier); // Load/save - LLComboBox* comboBox = getChild("WaterPresetsCombo"); - - //childSetAction("WaterLoadPreset", onLoadPreset, comboBox); - childSetAction("WaterNewPreset", onNewPreset, comboBox); - childSetAction("WaterSavePreset", onSavePreset, comboBox); - childSetAction("WaterDeletePreset", onDeletePreset, comboBox); + //childSetAction("WaterLoadPreset", onLoadPreset, mWaterPresetCombo); + childSetAction("WaterNewPreset", onNewPreset, mWaterPresetCombo); + childSetAction("WaterDeletePreset", onDeletePreset, mWaterPresetCombo); + childSetCommitCallback("WaterSavePreset", onSavePreset, this); // wave direction childSetCommitCallback("WaterWave1DirX", onVector2ControlXMoved, ¶m_mgr->mWave1Dir); @@ -165,11 +161,13 @@ void LLFloaterWater::initCallbacks(void) { childSetCommitCallback("WaterWave2DirX", onVector2ControlXMoved, ¶m_mgr->mWave2Dir); childSetCommitCallback("WaterWave2DirY", onVector2ControlYMoved, ¶m_mgr->mWave2Dir); - comboBox->setCommitCallback(onChangePresetName); - LLTextureCtrl* textCtrl = getChild("WaterNormalMap"); textCtrl->setDefaultImageAssetID(DEFAULT_WATER_NORMAL); - childSetCommitCallback("WaterNormalMap", onNormalMapPicked, NULL); + childSetCommitCallback("WaterNormalMap", onNormalMapPicked, NULL); + + // next/prev buttons + childSetAction("next", onClickNext, this); + childSetAction("prev", onClickPrev, this); } void LLFloaterWater::onClickHelp(void* data) @@ -196,31 +194,28 @@ bool LLFloaterWater::newPromptCallback(const LLSD& notification, const LLSD& res } if(option == 0) { - LLComboBox* comboBox = sWaterMenu->getChild( "WaterPresetsCombo"); - LLWaterParamManager * param_mgr = LLWaterParamManager::getInstance(); // add the current parameters to the list // see if it's there first - std::map::const_iterator mIt = - param_mgr->getPresets().find(text); - // if not there, add a new one - if(mIt == param_mgr->getPresets().end()) + if(!LLWaterParamManager::getInstance()->hasParamSet(text)) { param_mgr->addParamSet(text, param_mgr->mCurParams); - comboBox->add(text); - comboBox->sortByName(); + sWaterMenu->mWaterPresetCombo->add(text); + sWaterMenu->mWaterPresetCombo->sortByName(); - comboBox->setSelectedByValue(text, true); + sWaterMenu->mWaterPresetCombo->selectByValue(text); param_mgr->savePreset(text); + LLEnvManagerNew::instance().setUseWaterPreset(text); + // otherwise, send a message to the user } else { - LLNotificationsUtil::add("ExistsWaterPresetAlert"); + LLNotifications::instance().add("ExistsWaterPresetAlert"); } } return false; @@ -234,6 +229,11 @@ void LLFloaterWater::syncMenu() LLWaterParamSet & current_params = param_mgr->mCurParams; + if (mWaterPresetCombo->getSelectedItemLabel() != LLEnvManagerNew::instance().getWaterPresetName()) + { + mWaterPresetCombo->selectByValue(LLEnvManagerNew::instance().getWaterPresetName()); + } + // blue horizon param_mgr->mFogColor = current_params.getVector4(param_mgr->mFogColor.mName, err); @@ -303,19 +303,32 @@ LLFloaterWater* LLFloaterWater::instance() } void LLFloaterWater::show() { - LLFloaterWater* water = instance(); - water->syncMenu(); + if (!sWaterMenu) + { + LLFloaterWater* water = instance(); + water->syncMenu(); - // comment in if you want the menu to rebuild each time - //LLUICtrlFactory::getInstance()->buildFloater(water, "floater_water.xml"); - //water->initCallbacks(); - - water->open(); + // comment in if you want the menu to rebuild each time + //LLUICtrlFactory::getInstance()->buildFloater(water, "floater_water.xml"); + //water->initCallbacks(); + } + else + { + if (sWaterMenu->getVisible()) + { + sWaterMenu->close(); + } + else + { + sWaterMenu->open(); + } + } } bool LLFloaterWater::isOpen() { - if (sWaterMenu != NULL) { + if (sWaterMenu != NULL) + { return sWaterMenu->getVisible(); } return false; @@ -593,33 +606,50 @@ void LLFloaterWater::onNormalMapPicked(LLUICtrl* ctrl, void* userData) void LLFloaterWater::onNewPreset(void* userData) { - LLNotificationsUtil::add("NewWaterPreset", LLSD(), LLSD(), newPromptCallback); + LLNotifications::instance().add("NewWaterPreset", LLSD(), LLSD(), newPromptCallback); } -void LLFloaterWater::onSavePreset(void* userData) +void LLFloaterWater::onSavePreset(LLUICtrl* ctrl, void* userData) { - // get the name - LLComboBox* comboBox = sWaterMenu->getChild("WaterPresetsCombo"); - // don't save the empty name - if(comboBox->getSelectedItemLabel() == "") + if(sWaterMenu->mWaterPresetCombo->getSelectedItemLabel() == "") { return; } - LLWaterParamManager::getInstance()->mCurParams.mName = - comboBox->getSelectedItemLabel(); + if (ctrl->getValue().asString() == "save_inventory_item") + { - // check to see if it's a default and shouldn't be overwritten - std::set::iterator sIt = sDefaultPresets.find( - comboBox->getSelectedItemLabel()); - if(sIt != sDefaultPresets.end() && !gSavedSettings.getBOOL("WaterEditPresets")) - { - LLNotificationsUtil::add("WLNoEditDefault"); - return; } + else + { + LLWaterParamManager::getInstance()->mCurParams.mName = + sWaterMenu->mWaterPresetCombo->getSelectedItemLabel(); - LLNotificationsUtil::add("WLSavePresetAlert", LLSD(), LLSD(), saveAlertCallback); + // check to see if it's a default and shouldn't be overwritten + std::set::iterator sIt = sDefaultPresets.find( + sWaterMenu->mWaterPresetCombo->getSelectedItemLabel()); + if(sIt != sDefaultPresets.end() && !gSavedSettings.getBOOL("WaterEditPresets")) + { + LLNotifications::instance().add("WLNoEditDefault"); + return; + } + + LLNotifications::instance().add("WLSavePresetAlert", LLSD(), LLSD(), saveAlertCallback); + } +} + +bool LLFloaterWater::saveNotecardCallback(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + // if they choose save, do it. Otherwise, don't do anything + if(option == 0) + { + LLWaterParamManager * param_mgr = LLWaterParamManager::getInstance(); + param_mgr->setParamSet(param_mgr->mCurParams.mName, param_mgr->mCurParams); + param_mgr->savePresetToNotecard(param_mgr->mCurParams.mName); + } + return false; } bool LLFloaterWater::saveAlertCallback(const LLSD& notification, const LLSD& response) @@ -642,16 +672,14 @@ bool LLFloaterWater::saveAlertCallback(const LLSD& notification, const LLSD& res void LLFloaterWater::onDeletePreset(void* userData) { - LLComboBox* combo_box = sWaterMenu->getChild("WaterPresetsCombo"); - - if(combo_box->getSelectedValue().asString() == "") + if(sWaterMenu->mWaterPresetCombo->getSelectedValue().asString() == "") { return; } LLSD args; - args["SKY"] = combo_box->getSelectedValue().asString(); - LLNotificationsUtil::add("WLDeletePresetAlert", args, LLSD(), deleteAlertCallback); + args["SKY"] = sWaterMenu->mWaterPresetCombo->getSelectedValue().asString(); + LLNotifications::instance().add("WLDeletePresetAlert", args, LLSD(), deleteAlertCallback); } bool LLFloaterWater::deleteAlertCallback(const LLSD& notification, const LLSD& response) @@ -660,7 +688,6 @@ bool LLFloaterWater::deleteAlertCallback(const LLSD& notification, const LLSD& r // if they choose delete, do it. Otherwise, don't do anything if(option == 0) { - LLComboBox* combo_box = sWaterMenu->getChild("WaterPresetsCombo"); LLFloaterDayCycle* day_cycle = NULL; LLComboBox* key_combo = NULL; LLMultiSliderCtrl* mult_sldr = NULL; @@ -672,22 +699,22 @@ bool LLFloaterWater::deleteAlertCallback(const LLSD& notification, const LLSD& r mult_sldr = day_cycle->getChild("WaterDayCycleKeys"); } - std::string name = combo_box->getSelectedValue().asString(); + std::string name = sWaterMenu->mWaterPresetCombo->getSelectedValue().asString(); // check to see if it's a default and shouldn't be deleted std::set::iterator sIt = sDefaultPresets.find(name); if(sIt != sDefaultPresets.end()) { - LLNotificationsUtil::add("WaterNoEditDefault"); + LLNotifications::instance().add("WaterNoEditDefault"); return false; } LLWaterParamManager::getInstance()->removeParamSet(name, true); // remove and choose another - S32 new_index = combo_box->getCurrentIndex(); + S32 new_index = sWaterMenu->mWaterPresetCombo->getCurrentIndex(); - combo_box->remove(name); + sWaterMenu->mWaterPresetCombo->remove(name); if(key_combo != NULL) { @@ -703,9 +730,9 @@ bool LLFloaterWater::deleteAlertCallback(const LLSD& notification, const LLSD& r new_index--; } - if(combo_box->getItemCount() > 0) + if(sWaterMenu->mWaterPresetCombo->getItemCount() > 0) { - combo_box->setCurrentByIndex(new_index); + sWaterMenu->mWaterPresetCombo->setCurrentByIndex(new_index); } } return false; @@ -720,9 +747,54 @@ void LLFloaterWater::onChangePresetName(LLUICtrl* ctrl, void * userData) { return; } - - LLWaterParamManager::getInstance()->loadPreset( - combo_box->getSelectedValue().asString()); + + const std::string& wwset = combo_box->getSelectedValue().asString(); + if (LLWaterParamManager::getInstance()->hasParamSet(wwset)) + { + LLEnvManagerNew::instance().setUseWaterPreset(wwset); + } + else + { + //if that failed, use region's + // LLEnvManagerNew::instance().useRegionWater(); + LLEnvManagerNew::instance().setUseWaterPreset("Default"); + } sWaterMenu->syncMenu(); } +void LLFloaterWater::onClickNext(void* user_data) +{ + S32 index = sWaterMenu->mWaterPresetCombo->getCurrentIndex(); + index++; + if (index == sWaterMenu->mWaterPresetCombo->getItemCount()) + index = 0; + sWaterMenu->mWaterPresetCombo->setCurrentByIndex(index); + + LLFloaterWater::onChangePresetName(sWaterMenu->mWaterPresetCombo, sWaterMenu); +} + +void LLFloaterWater::onClickPrev(void* user_data) +{ + S32 index = sWaterMenu->mWaterPresetCombo->getCurrentIndex(); + if (index == 0) + index = sWaterMenu->mWaterPresetCombo->getItemCount(); + index--; + sWaterMenu->mWaterPresetCombo->setCurrentByIndex(index); + + LLFloaterWater::onChangePresetName(sWaterMenu->mWaterPresetCombo, sWaterMenu); +} + +void LLFloaterWater::populateWaterPresetsList() +{ + mWaterPresetCombo->removeall(); + + std::list presets; + LLWaterParamManager::getInstance()->getPresetNames(presets); + + for (std::list::const_iterator it = presets.begin(); it != presets.end(); ++it) + { + mWaterPresetCombo->add(*it); + } + + mWaterPresetCombo->selectByValue(LLEnvManagerNew::instance().getWaterPresetName()); +} diff --git a/indra/newview/llfloaterwater.h b/indra/newview/llfloaterwater.h index 774d5c5a7..fbd7e26a9 100644 --- a/indra/newview/llfloaterwater.h +++ b/indra/newview/llfloaterwater.h @@ -41,10 +41,13 @@ #include #include "llwlparamset.h" +#include "llwlparammanager.h" // for LLWLParamKey struct WaterColorControl; struct WaterloatControl; +class LLComboBox; + /// Menuing system for all of windlight's functionality class LLFloaterWater : public LLFloater @@ -95,7 +98,10 @@ public: static void onNewPreset(void* userData); /// when user hits the save preset button - static void onSavePreset(void* userData); + static void onSavePreset(LLUICtrl* ctrl, void* userData); + + /// prompts a user when overwriting a preset notecard + static bool saveNotecardCallback(const LLSD& notification, const LLSD& response); /// prompts a user when overwriting a preset static bool saveAlertCallback(const LLSD& notification, const LLSD& response); @@ -128,6 +134,13 @@ private: static LLFloaterWater* sWaterMenu; static std::set sDefaultPresets; + + static void onClickNext(void* user_data); + static void onClickPrev(void* user_data); + + void populateWaterPresetsList(); + + LLComboBox* mWaterPresetCombo; }; diff --git a/indra/newview/llfloaterwindlight.cpp b/indra/newview/llfloaterwindlight.cpp index 9ec787a6c..4dee4ecd0 100644 --- a/indra/newview/llfloaterwindlight.cpp +++ b/indra/newview/llfloaterwindlight.cpp @@ -47,13 +47,18 @@ #include "llcombobox.h" #include "lllineeditor.h" #include "llfloaterdaycycle.h" +#include "lltabcontainer.h" #include "llboost.h" -#include "llnotificationsutil.h" + +#include "llagent.h" +#include "llinventorymodel.h" +#include "llviewerinventory.h" #include "v4math.h" #include "llviewerdisplay.h" #include "llviewercontrol.h" #include "llviewerwindow.h" +#include "llsavedsettingsglue.h" #include "llwlparamset.h" #include "llwlparammanager.h" @@ -72,22 +77,11 @@ LLFloaterWindLight::LLFloaterWindLight() : LLFloater(std::string("windlight floa LLUICtrlFactory::getInstance()->buildFloater(this, "floater_windlight_options.xml"); // add the combo boxes - LLComboBox* comboBox = getChild("WLPresetsCombo"); + mSkyPresetCombo = getChild("WLPresetsCombo"); - if(comboBox != NULL) { - - std::map::const_iterator mIt = - LLWLParamManager::getInstance()->getPresets().begin(); - for(; mIt != LLWLParamManager::getInstance()->getPresets().end(); mIt++) - { - comboBox->add(mIt->first); - } - - // entry for when we're in estate time - comboBox->add(LLStringUtil::null); - - // set defaults on combo boxes - comboBox->selectByValue(LLSD("Default")); + if(mSkyPresetCombo != NULL) { + populateSkyPresetsList(); + mSkyPresetCombo->setCommitCallback(onChangePresetName); } // add the list of presets @@ -214,20 +208,21 @@ void LLFloaterWindLight::initCallbacks(void) { // WL Top childSetAction("WLDayCycleMenuButton", onOpenDayCycle, NULL); + // Load/save - LLComboBox* comboBox = getChild("WLPresetsCombo"); - - //childSetAction("WLLoadPreset", onLoadPreset, comboBox); - childSetAction("WLNewPreset", onNewPreset, comboBox); - childSetAction("WLSavePreset", onSavePreset, comboBox); - childSetAction("WLDeletePreset", onDeletePreset, comboBox); - - comboBox->setCommitCallback(onChangePresetName); + //childSetAction("WLLoadPreset", onLoadPreset, mSkyPresetCombo); + childSetAction("WLNewPreset", onNewPreset, mSkyPresetCombo); + childSetAction("WLDeletePreset", onDeletePreset, mSkyPresetCombo); + childSetCommitCallback("WLSavePreset", onSavePreset, this); // Dome childSetCommitCallback("WLGamma", onFloatControlMoved, ¶m_mgr->mWLGamma); childSetCommitCallback("WLStarAlpha", onStarAlphaMoved, NULL); + + // next/prev buttons + childSetAction("next", onClickNext, this); + childSetAction("prev", onClickPrev, this); } void LLFloaterWindLight::onClickHelp(void* data) @@ -253,10 +248,8 @@ bool LLFloaterWindLight::newPromptCallback(const LLSD& notification, const LLSD& return false; } - if(option == 0) { - LLComboBox* comboBox = sWindLight->getChild( - "WLPresetsCombo"); - + if(option == 0) + { LLFloaterDayCycle* sDayCycle = NULL; LLComboBox* keyCombo = NULL; if(LLFloaterDayCycle::isOpen()) @@ -268,38 +261,42 @@ bool LLFloaterWindLight::newPromptCallback(const LLSD& notification, const LLSD& // add the current parameters to the list // see if it's there first - std::map::const_iterator mIt = - LLWLParamManager::getInstance()->getPresets().find(text); + + const LLWLParamKey key(text, LLEnvKey::SCOPE_LOCAL); // if not there, add a new one - if(mIt == LLWLParamManager::getInstance()->getPresets().end()) + if(!LLWLParamManager::getInstance()->hasParamSet(key)) { - LLWLParamManager::getInstance()->addParamSet(text, + LLWLParamManager::getInstance()->addParamSet(key, LLWLParamManager::getInstance()->mCurParams); - comboBox->add(text); - comboBox->sortByName(); + sWindLight->mSkyPresetCombo->add(text); + sWindLight->mSkyPresetCombo->sortByName(); // add a blank to the bottom - comboBox->selectFirstItem(); - if(comboBox->getSimple() == "") + sWindLight->mSkyPresetCombo->selectFirstItem(); + if(sWindLight->mSkyPresetCombo->getSimple() == "") { - comboBox->remove(0); + sWindLight->mSkyPresetCombo->remove(0); } - comboBox->add(LLStringUtil::null); + sWindLight->mSkyPresetCombo->add(LLStringUtil::null); + + sWindLight->mSkyPresetCombo->selectByValue(text); - comboBox->setSelectedByValue(text, true); if(LLFloaterDayCycle::isOpen()) { keyCombo->add(text); keyCombo->sortByName(); } - LLWLParamManager::getInstance()->savePreset(text); + const LLWLParamKey key(text, LLEnvKey::SCOPE_LOCAL); + LLWLParamManager::getInstance()->savePreset(key); + + LLEnvManagerNew::instance().setUseSkyPreset(text); // otherwise, send a message to the user } else { - LLNotificationsUtil::add("ExistsSkyPresetAlert"); + LLNotifications::instance().add("ExistsSkyPresetAlert"); } } return false; @@ -316,10 +313,9 @@ void LLFloaterWindLight::syncMenu() // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) // Fixes LL "bug" (preset name isn't kept synchronized) - LLComboBox* comboBox = getChild("WLPresetsCombo"); - if (comboBox->getSelectedItemLabel() != currentParams.mName) + if (mSkyPresetCombo->getSelectedItemLabel() != LLEnvManagerNew::instance().getSkyPresetName()) { - comboBox->setSimple(currentParams.mName); + mSkyPresetCombo->selectByValue(LLEnvManagerNew::instance().getSkyPresetName()); } // [/RLVa:KB] @@ -415,7 +411,7 @@ void LLFloaterWindLight::syncMenu() bool lockY = !param_mgr->mCurParams.getEnableCloudScrollY(); childSetValue("WLCloudLockX", lockX); childSetValue("WLCloudLockY", lockY); - childSetValue("DrawClassicClouds", gSavedSettings.getBOOL("SkyUseClassicClouds")); + childSetValue("DrawClassicClouds", gSavedSettings.getBOOL("SkyUseClassicClouds2")); // disable if locked, enable if not if(lockX) @@ -460,19 +456,32 @@ LLFloaterWindLight* LLFloaterWindLight::instance() } void LLFloaterWindLight::show() { - LLFloaterWindLight* windLight = instance(); - windLight->syncMenu(); + if (!sWindLight) + { + LLFloaterWindLight* windLight = instance(); + windLight->syncMenu(); - // comment in if you want the menu to rebuild each time - //LLUICtrlFactory::getInstance()->buildFloater(windLight, "floater_windlight_options.xml"); - //windLight->initCallbacks(); - - windLight->open(); + // comment in if you want the menu to rebuild each time + //LLUICtrlFactory::getInstance()->buildFloater(windLight, "floater_windlight_options.xml"); + //windLight->initCallbacks(); + } + else + { + if (sWindLight->getVisible()) + { + sWindLight->close(); + } + else + { + sWindLight->open(); + } + } } bool LLFloaterWindLight::isOpen() { - if (sWindLight != NULL) { + if (sWindLight != NULL) + { return sWindLight->getVisible(); } return false; @@ -790,34 +799,50 @@ void LLFloaterWindLight::onStarAlphaMoved(LLUICtrl* ctrl, void* userData) void LLFloaterWindLight::onNewPreset(void* userData) { - LLNotificationsUtil::add("NewSkyPreset", LLSD(), LLSD(), newPromptCallback); + LLNotifications::instance().add("NewSkyPreset", LLSD(), LLSD(), newPromptCallback); } -void LLFloaterWindLight::onSavePreset(void* userData) +void LLFloaterWindLight::onSavePreset(LLUICtrl* ctrl, void* userData) { - // get the name - LLComboBox* comboBox = sWindLight->getChild( - "WLPresetsCombo"); - // don't save the empty name - if(comboBox->getSelectedItemLabel() == "") + if(sWindLight->mSkyPresetCombo->getSelectedItemLabel() == "") { return; } - // check to see if it's a default and shouldn't be overwritten - std::set::iterator sIt = sDefaultPresets.find( - comboBox->getSelectedItemLabel()); - if(sIt != sDefaultPresets.end() && !gSavedSettings.getBOOL("SkyEditPresets")) + if (ctrl->getValue().asString() == "save_inventory_item") { - LLNotificationsUtil::add("WLNoEditDefault"); - return; + } + else + { + // check to see if it's a default and shouldn't be overwritten + std::set::iterator sIt = sDefaultPresets.find( + sWindLight->mSkyPresetCombo->getSelectedItemLabel()); + if(sIt != sDefaultPresets.end() && !gSavedSettings.getBOOL("SkyEditPresets")) + { + LLNotifications::instance().add("WLNoEditDefault"); + return; + } - LLWLParamManager::getInstance()->mCurParams.mName = - comboBox->getSelectedItemLabel(); + LLWLParamManager::getInstance()->mCurParams.mName = + sWindLight->mSkyPresetCombo->getSelectedItemLabel(); - LLNotificationsUtil::add("WLSavePresetAlert", LLSD(), LLSD(), saveAlertCallback); + LLNotifications::instance().add("WLSavePresetAlert", LLSD(), LLSD(), saveAlertCallback); + } +} + +bool LLFloaterWindLight::saveNotecardCallback(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + // if they choose save, do it. Otherwise, don't do anything + if(option == 0) + { + LLWLParamManager * param_mgr = LLWLParamManager::getInstance(); + param_mgr->setParamSet(param_mgr->mCurParams.mName, param_mgr->mCurParams); + param_mgr->savePresetToNotecard(param_mgr->mCurParams.mName); + } + return false; } bool LLFloaterWindLight::saveAlertCallback(const LLSD& notification, const LLSD& response) @@ -831,24 +856,22 @@ bool LLFloaterWindLight::saveAlertCallback(const LLSD& notification, const LLSD& param_mgr->setParamSet(param_mgr->mCurParams.mName, param_mgr->mCurParams); // comment this back in to save to file - param_mgr->savePreset(param_mgr->mCurParams.mName); + const LLWLParamKey key(param_mgr->mCurParams.mName, LLEnvKey::SCOPE_LOCAL); + param_mgr->savePreset(key); } return false; } void LLFloaterWindLight::onDeletePreset(void* userData) { - LLComboBox* combo_box = sWindLight->getChild( - "WLPresetsCombo"); - - if(combo_box->getSelectedValue().asString() == "") + if(sWindLight->mSkyPresetCombo->getSelectedValue().asString() == "") { return; } LLSD args; - args["SKY"] = combo_box->getSelectedValue().asString(); - LLNotificationsUtil::add("WLDeletePresetAlert", args, LLSD(), + args["SKY"] = sWindLight->mSkyPresetCombo->getSelectedValue().asString(); + LLNotifications::instance().add("WLDeletePresetAlert", args, LLSD(), boost::bind(&LLFloaterWindLight::deleteAlertCallback, sWindLight, _1, _2)); } @@ -859,8 +882,6 @@ bool LLFloaterWindLight::deleteAlertCallback(const LLSD& notification, const LLS // if they choose delete, do it. Otherwise, don't do anything if(option == 0) { - LLComboBox* combo_box = getChild( - "WLPresetsCombo"); LLFloaterDayCycle* day_cycle = NULL; LLComboBox* key_combo = NULL; LLMultiSliderCtrl* mult_sldr = NULL; @@ -873,22 +894,22 @@ bool LLFloaterWindLight::deleteAlertCallback(const LLSD& notification, const LLS mult_sldr = day_cycle->getChild("WLDayCycleKeys"); } - std::string name(combo_box->getSelectedValue().asString()); + std::string name(mSkyPresetCombo->getSelectedValue().asString()); // check to see if it's a default and shouldn't be deleted std::set::iterator sIt = sDefaultPresets.find(name); if(sIt != sDefaultPresets.end()) { - LLNotificationsUtil::add("WLNoEditDefault"); + LLNotifications::instance().add("WLNoEditDefault"); return false; } LLWLParamManager::getInstance()->removeParamSet(name, true); // remove and choose another - S32 new_index = combo_box->getCurrentIndex(); + S32 new_index = mSkyPresetCombo->getCurrentIndex(); - combo_box->remove(name); + mSkyPresetCombo->remove(name); if(key_combo != NULL) { key_combo->remove(name); @@ -903,9 +924,17 @@ bool LLFloaterWindLight::deleteAlertCallback(const LLSD& notification, const LLS new_index--; } - if(combo_box->getItemCount() > 0) + if(mSkyPresetCombo->getItemCount() > 0) { - combo_box->setCurrentByIndex(new_index); + mSkyPresetCombo->setCurrentByIndex(new_index); + + // If we don't update the name here, we crash on next/prev -- MC + LLWLParamManager::getInstance()->mCurParams.mName = mSkyPresetCombo->getSelectedValue().asString(); + if (LLWLParamManager::getInstance()->mCurParams.mName.empty()) + { + LLWLParamManager::getInstance()->mCurParams.mName = "Default"; + } + LLEnvManagerNew::instance().setUseSkyPreset(LLWLParamManager::getInstance()->mCurParams.mName); } } return false; @@ -914,17 +943,26 @@ bool LLFloaterWindLight::deleteAlertCallback(const LLSD& notification, const LLS void LLFloaterWindLight::onChangePresetName(LLUICtrl* ctrl, void * userData) { - deactivateAnimator(); - LLComboBox * combo_box = static_cast(ctrl); if(combo_box->getSimple() == "") { return; } + + const LLWLParamKey key(combo_box->getSelectedValue().asString(), LLEnvKey::SCOPE_LOCAL); + if (LLWLParamManager::getInstance()->hasParamSet(key)) + { + LLEnvManagerNew::instance().setUseSkyPreset(key.name); + } + else + { + //if that failed, use region's + // LLEnvManagerNew::instance().useRegionSky(); + LLEnvManagerNew::instance().setUseSkyPreset("Default"); + } - LLWLParamManager::getInstance()->loadPreset( - combo_box->getSelectedValue().asString()); + //LL_INFOS("WindLight") << "Current inventory ID: " << LLWLParamManager::getInstance()->mCurParams.mInventoryID << LL_ENDL; sWindLight->syncMenu(); } @@ -999,6 +1037,52 @@ void LLFloaterWindLight::onCloudScrollYToggled(LLUICtrl* ctrl, void* userData) void LLFloaterWindLight::deactivateAnimator() { - LLWLParamManager::getInstance()->mAnimator.mIsRunning = false; - LLWLParamManager::getInstance()->mAnimator.mUseLindenTime = false; + LLWLParamManager::getInstance()->mAnimator.deactivate(); +} + +void LLFloaterWindLight::onClickNext(void* user_data) +{ + S32 index = sWindLight->mSkyPresetCombo->getCurrentIndex(); + index++; + if (index == sWindLight->mSkyPresetCombo->getItemCount()) + index = 0; + sWindLight->mSkyPresetCombo->setCurrentByIndex(index); + + LLFloaterWindLight::onChangePresetName(sWindLight->mSkyPresetCombo, sWindLight); +} + +void LLFloaterWindLight::onClickPrev(void* user_data) +{ + S32 index = sWindLight->mSkyPresetCombo->getCurrentIndex(); + if (index == 0) + index = sWindLight->mSkyPresetCombo->getItemCount(); + index--; + sWindLight->mSkyPresetCombo->setCurrentByIndex(index); + + LLFloaterWindLight::onChangePresetName(sWindLight->mSkyPresetCombo, sWindLight); +} + +//static +void LLFloaterWindLight::selectTab(std::string tab_name) +{ + if (!tab_name.empty()) + { + LLTabContainer* tabs = LLFloaterWindLight::instance()->getChild("WindLight Tabs"); + tabs->selectTabByName(tab_name); + } +} + +void LLFloaterWindLight::populateSkyPresetsList() +{ + mSkyPresetCombo->removeall(); + + LLWLParamManager::preset_name_list_t local_presets; + LLWLParamManager::getInstance()->getLocalPresetNames(local_presets); + + for (LLWLParamManager::preset_name_list_t::const_iterator it = local_presets.begin(); it != local_presets.end(); ++it) + { + mSkyPresetCombo->add(*it); + } + + mSkyPresetCombo->selectByValue(LLEnvManagerNew::instance().getSkyPresetName()); } diff --git a/indra/newview/llfloaterwindlight.h b/indra/newview/llfloaterwindlight.h index 3447caa92..5ef51bc2e 100644 --- a/indra/newview/llfloaterwindlight.h +++ b/indra/newview/llfloaterwindlight.h @@ -45,6 +45,7 @@ struct WLColorControl; struct WLFloatControl; +class LLComboBox; /// Menuing system for all of windlight's functionality class LLFloaterWindLight : public LLFloater @@ -91,8 +92,11 @@ public: /// when user hits the load preset button static void onNewPreset(void* userData); - /// when user hits the save preset button - static void onSavePreset(void* userData); + /// when user hits the save to file button + static void onSavePreset(LLUICtrl* ctrl, void* userData); + + /// prompts a user when overwriting a preset notecard + static bool saveNotecardCallback(const LLSD& notification, const LLSD& response); /// prompts a user when overwriting a preset static bool saveAlertCallback(const LLSD& notification, const LLSD& response); @@ -132,11 +136,20 @@ public: /// turn off animated skies static void deactivateAnimator(); + static void selectTab(std::string tab_name); + private: // one instance on the inside static LLFloaterWindLight* sWindLight; static std::set sDefaultPresets; + + static void onClickNext(void* user_data); + static void onClickPrev(void* user_data); + + void populateSkyPresetsList(); + + LLComboBox* mSkyPresetCombo; }; diff --git a/indra/newview/llpreviewanim.cpp b/indra/newview/llpreviewanim.cpp index 803a76ba5..6a9033866 100644 --- a/indra/newview/llpreviewanim.cpp +++ b/indra/newview/llpreviewanim.cpp @@ -77,6 +77,25 @@ LLPreviewAnim::LLPreviewAnim(const std::string& name, const LLRect& rect, const if(item) { gAgentAvatarp->createMotion(item->getAssetUUID()); + + const LLPermissions& perm = item->getPermissions(); + U32 mask = PERM_NONE; + if(perm.getOwner() == gAgent.getID()) + { + mask = perm.getMaskBase(); + } + else if(gAgent.isInGroup(perm.getGroup())) + { + mask = perm.getMaskGroup(); + } + else + { + mask = perm.getMaskEveryone(); + } + if((mask & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) + { + mIsCopyable = true; + } } switch ( activate ) @@ -334,7 +353,7 @@ void LLPreviewAnim::copyAnimID(void *userdata) // virtual BOOL LLPreviewAnim::canSaveAs() const { - return TRUE; + return mIsCopyable; } // virtual diff --git a/indra/newview/llpreviewanim.h b/indra/newview/llpreviewanim.h index 3b9c53025..e4ddb65c5 100644 --- a/indra/newview/llpreviewanim.h +++ b/indra/newview/llpreviewanim.h @@ -81,6 +81,7 @@ protected: LLUUID mObjectID; LLButton* mPlayBtn; LLButton* mAuditionBtn; + bool mIsCopyable; }; #endif // LL_LLPREVIEWSOUND_H diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index d678dc490..d01cb7330 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -212,7 +212,7 @@ //#include "llfloateravatars.h" //#include "llactivation.h" #include "wlfPanel_AdvSettings.h" //Lower right Windlight and Rendering options -#include "ascentdaycyclemanager.h" +#include "lldaycyclemanager.h" #include "llfloaterblacklist.h" #include "scriptcounter.h" #include "shfloatermediaticker.h" @@ -1968,7 +1968,7 @@ bool idle_startup() display_startup(); // init the shader managers - AscentDayCycleManager::initClass(); + //LLDayCycleManager::initClass(); display_startup(); // RN: don't initialize VO classes in drone mode, they are too closely tied to rendering diff --git a/indra/newview/llviewergenericmessage.cpp b/indra/newview/llviewergenericmessage.cpp index 796a49fa4..34b45d7bf 100644 --- a/indra/newview/llviewergenericmessage.cpp +++ b/indra/newview/llviewergenericmessage.cpp @@ -92,6 +92,7 @@ void process_generic_message(LLMessageSystem* msg, void**) //This needs to be handled by a dispatcher really, but I'm not sure where is the best place to put it if (method == "Windlight") { +#if 0 //Meta7 WindLight packet //We are delivering with an agentID of NULL_KEY so as to be //friendly and not trigger a warning for unsupporting clients. @@ -192,6 +193,7 @@ void process_generic_message(LLMessageSystem* msg, void**) wl_param_mgr->loadPreset( "LightShare-CurrentRegion",true); } } +#endif } else if (agent_id != gAgent.getID()) { diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index a70806851..cd0c57d75 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -9267,7 +9267,6 @@ class LLWorldEnvSettings : public view_listener_t // [/RLVa:KB] std::string tod = userdata.asString(); - LLVector3 sun_direction; if (tod == "editor") { @@ -9287,53 +9286,25 @@ class LLWorldEnvSettings : public view_listener_t if (tod == "sunrise") { - // set the value, turn off animation - LLWLParamManager::getInstance()->mAnimator.setDayTime(0.25); - LLWLParamManager::getInstance()->mAnimator.mIsRunning = false; - LLWLParamManager::getInstance()->mAnimator.mUseLindenTime = false; - - // then call update once - LLWLParamManager::getInstance()->mAnimator.update( - LLWLParamManager::getInstance()->mCurParams); + LLEnvManagerNew::instance().setUseSkyPreset("Sunrise", gSavedSettings.getBOOL("PhoenixInterpolateSky")); } else if (tod == "noon") { - // set the value, turn off animation - LLWLParamManager::getInstance()->mAnimator.setDayTime(0.567); - LLWLParamManager::getInstance()->mAnimator.mIsRunning = false; - LLWLParamManager::getInstance()->mAnimator.mUseLindenTime = false; - - // then call update once - LLWLParamManager::getInstance()->mAnimator.update( - LLWLParamManager::getInstance()->mCurParams); + LLEnvManagerNew::instance().setUseSkyPreset("Midday", gSavedSettings.getBOOL("PhoenixInterpolateSky")); } else if (tod == "sunset") { - // set the value, turn off animation - LLWLParamManager::getInstance()->mAnimator.setDayTime(0.75); - LLWLParamManager::getInstance()->mAnimator.mIsRunning = false; - LLWLParamManager::getInstance()->mAnimator.mUseLindenTime = false; - - // then call update once - LLWLParamManager::getInstance()->mAnimator.update( - LLWLParamManager::getInstance()->mCurParams); + LLEnvManagerNew::instance().setUseSkyPreset("Sunset", gSavedSettings.getBOOL("PhoenixInterpolateSky")); } else if (tod == "midnight") { - // set the value, turn off animation - LLWLParamManager::getInstance()->mAnimator.setDayTime(0.0); - LLWLParamManager::getInstance()->mAnimator.mIsRunning = false; - LLWLParamManager::getInstance()->mAnimator.mUseLindenTime = false; - - // then call update once - LLWLParamManager::getInstance()->mAnimator.update( - LLWLParamManager::getInstance()->mCurParams); + LLEnvManagerNew::instance().setUseSkyPreset("Midnight", gSavedSettings.getBOOL("PhoenixInterpolateSky")); } - else + else // Use Region Environment Settings { - LLWLParamManager::getInstance()->mAnimator.mIsRunning = true; - LLWLParamManager::getInstance()->mAnimator.mUseLindenTime = true; + LLEnvManagerNew::instance().setUseRegionSettings(true, gSavedSettings.getBOOL("PhoenixInterpolateSky")); } + return true; } }; diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index ef5efc2ac..cca871171 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -3815,6 +3815,7 @@ void process_teleport_finish(LLMessageSystem* msg, void**) //Reset the windlight profile to default //LLWLParamManager::getInstance()->mAnimator.mIsRunning = false; //LLWLParamManager::getInstance()->mAnimator.mUseLindenTime = false; + /* LLWLParamSet wl_backup; if(LLWLParamManager::getInstance()->getParamSet("LightShare-Backup", wl_backup)) { LLWLParamManager::getInstance()->propagateParameters(); @@ -3824,7 +3825,7 @@ void process_teleport_finish(LLMessageSystem* msg, void**) if(LLWaterParamManager::getInstance()->getParamSet("LightShare-Backup", backup)) { LLWaterParamManager::getInstance()->propagateParameters(); LLWaterParamManager::getInstance()->removeParamSet("LightShare-Backup", true); - } + }*/ // now, use the circuit info to tell simulator about us! LL_INFOS("Messaging") << "process_teleport_finish() Enabling " diff --git a/indra/newview/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp index 782f70e1f..d70cf66ee 100644 --- a/indra/newview/llwaterparammanager.cpp +++ b/indra/newview/llwaterparammanager.cpp @@ -50,13 +50,23 @@ #include "lllineeditor.h" #include "llsdserialize.h" +// For notecard loading +#include "llvfile.h" +#include "llnotecard.h" +#include "llmemorystream.h" +#include "llnotify.h" +#include "llagent.h" +#include "llinventorymodel.h" +#include "llviewerinventory.h" +#include "llviewerregion.h" +#include "llassetuploadresponders.h" + #include "v4math.h" #include "llviewerdisplay.h" #include "llviewercontrol.h" #include "llviewerwindow.h" #include "lldrawpoolwater.h" #include "llagent.h" -#include "llagentcamera.h" #include "llviewerregion.h" #include "llwlparammanager.h" @@ -64,6 +74,8 @@ #include "llpostprocess.h" #include "llfloaterwater.h" +#include "llagentcamera.h" + #include "curl/curl.h" LLWaterParamManager::LLWaterParamManager() : @@ -87,124 +99,133 @@ LLWaterParamManager::~LLWaterParamManager() { } -void LLWaterParamManager::loadAllPresets(const std::string& file_name) +void LLWaterParamManager::loadAllPresets() { - std::string path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/water", "")); - LL_INFOS2("AppInit", "Shaders") << "Loading Default water settings from " << path_name << LL_ENDL; - - bool found = true; - LLDirIterator app_settings_iter(path_name, "*.xml"); - while(found) - { - std::string name; - found = app_settings_iter.next(name); - if(found) - { - - name=name.erase(name.length()-4); - - // bugfix for SL-46920: preventing filenames that break stuff. - char * curl_str = curl_unescape(name.c_str(), name.size()); - std::string unescaped_name(curl_str); - curl_free(curl_str); - curl_str = NULL; - - LL_DEBUGS2("AppInit", "Shaders") << "name: " << name << LL_ENDL; - loadPreset(unescaped_name,FALSE); - } - } - - // And repeat for user presets, note the user presets will modify any system presets already loaded - - std::string path_name2(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/water", "")); - LL_INFOS2("AppInit", "Shaders") << "Loading User water settings from " << path_name2 << LL_ENDL; - - found = true; - LLDirIterator user_settings_iter(path_name2, "*.xml"); - while(found) - { - std::string name; - found = user_settings_iter.next(name); - if(found) - { - name=name.erase(name.length()-4); - - // bugfix for SL-46920: preventing filenames that break stuff. - char * curl_str = curl_unescape(name.c_str(), name.size()); - std::string unescaped_name(curl_str); - curl_free(curl_str); - curl_str = NULL; - - LL_DEBUGS2("AppInit", "Shaders") << "name: " << name << LL_ENDL; - loadPreset(unescaped_name,FALSE); - } - } + // 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::loadPreset(const std::string & name,bool propagate) +void LLWaterParamManager::loadPresetsFromDir(const std::string& dir) { - // bugfix for SL-46920: preventing filenames that break stuff. - std::string escaped_filename = LLWeb::curlEscape(name); + LL_INFOS2("AppInit", "Shaders") << "Loading water presets from " << dir << LL_ENDL; - escaped_filename += ".xml"; - - std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/water", escaped_filename)); - llinfos << "Loading water settings from " << pathName << llendl; - - std::ifstream presetsXML; - presetsXML.open(pathName.c_str()); - - // That failed, try loading from the users area instead. - if(!presetsXML) + LLDirIterator dir_iter(dir, "*.xml"); + while (1) { - pathName=gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/water", escaped_filename); - llinfos << "Loading User water setting from " << pathName << llendl; - presetsXML.open(pathName.c_str()); + std::string file; + if (!dir_iter.next(file)) + { + break; // no more files + } + + std::string path = dir + file; + if (!loadPreset(path)) + { + llwarns << "Error loading water preset from " << path << llendl; + } + } +} + +bool LLWaterParamManager::loadPreset(const std::string& path) +{ + llifstream xml_file; + std::string name(gDirUtilp->getBaseFileName(LLWeb::curlEscape(path), /*strip_exten = */ true)); + + xml_file.open(path.c_str()); + if (!xml_file) + { + return false; } - if (presetsXML) + LL_DEBUGS2("AppInit", "Shaders") << "Loading water " << name << LL_ENDL; + + LLSD params_data; + LLPointer parser = new LLSDXMLParser(); + parser->parse(xml_file, params_data, LLSDSerialize::SIZE_UNLIMITED); + xml_file.close(); + + if (hasParamSet(name)) { - LLSD paramsData(LLSD::emptyMap()); + setParamSet(name, params_data); + } + else + { + addParamSet(name, params_data); + } - LLPointer parser = new LLSDXMLParser(); + return true; +} - parser->parse(presetsXML, paramsData, LLSDSerialize::SIZE_UNLIMITED); +bool LLWaterParamManager::loadPresetXML(const std::string& name, std::istream& preset_stream) +{ + LLSD paramsData(LLSD::emptyMap()); + + LLPointer parser = new LLSDXMLParser(); + + if(parser->parse(preset_stream, paramsData, LLSDSerialize::SIZE_UNLIMITED) == LLSDParser::PARSE_FAILURE) + { + return false; + } - std::map::iterator mIt = mParamList.find(name); - if(mIt == mParamList.end()) + static const char* expected_windlight_settings[] = { + "blurMultiplier", + "fresnelOffset", + "fresnelScale", + "normScale", + "normalMap", + "scaleAbove", + "scaleBelow", + "waterFogColor", + "waterFogDensity", + "wave1Dir", + "wave2Dir" + }; + static S32 expected_count = LL_ARRAY_SIZE(expected_windlight_settings); + for(S32 i = 0; i < expected_count; ++i) + { + if(!paramsData.has(expected_windlight_settings[i])) { - addParamSet(name, paramsData); + LL_WARNS("WindLight") << "Attempted to load WindLight water param set without " << expected_windlight_settings[i] << LL_ENDL; + return false; } - else - { - setParamSet(name, paramsData); - } - presetsXML.close(); - } + } + + if(!hasParamSet(name)) + { + addParamSet(name, paramsData); + } else { - llwarns << "Can't find " << name << llendl; - return; + setParamSet(name, paramsData); } - if(propagate) - { - getParamSet(name, mCurParams); - propagateParameters(); - } -} + return true; +} + +void LLWaterParamManager::loadPresetNotecard(const std::string& name, const LLUUID& asset_id, const LLUUID& inv_id) +{ + gAssetStorage->getInvItemAsset(LLHost::invalid, + gAgent.getID(), + gAgent.getSessionID(), + gAgent.getID(), + LLUUID::null, + inv_id, + asset_id, + LLAssetType::AT_NOTECARD, + &loadWaterNotecard, + (void*)&inv_id); +} void LLWaterParamManager::savePreset(const std::string & name) { - // bugfix for SL-46920: preventing filenames that break stuff. - std::string escaped_filename = LLWeb::curlEscape(name); - - escaped_filename += ".xml"; + llassert(!name.empty()); // make an empty llsd LLSD paramsData(LLSD::emptyMap()); - std::string pathName(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/water", escaped_filename)); + std::string pathName(getUserDir() + LLWeb::curlEscape(name) + ".xml"); // fill it with LLSD windlight params paramsData = mParamList[name].getAll(); @@ -218,6 +239,63 @@ void LLWaterParamManager::savePreset(const std::string & name) propagateParameters(); } +// Yes, this function is completely identical to LLWLParamManager::savePresetToNotecard. +// I feel some refactoring of this whole WindLight thing would be generally beneficial. +// Damned if I'm going to be the one to do it, though. +bool LLWaterParamManager::savePresetToNotecard(const std::string & name) +{ + if(!hasParamSet(name)) return false; + + // make an empty llsd + LLSD paramsData(LLSD::emptyMap()); + + // fill it with LLSD windlight params + paramsData = mParamList[name].getAll(); + + // get some XML + std::ostringstream presetsXML; + LLPointer formatter = new LLSDXMLFormatter(); + formatter->format(paramsData, presetsXML, LLSDFormatter::OPTIONS_PRETTY); + + // Write it to a notecard + LLNotecard notecard; + notecard.setText(presetsXML.str()); + + LLInventoryItem *item = gInventory.getItem(mParamList[name].mInventoryID); + if(!item) + { + mParamList[name].mInventoryID = LLUUID::null; + return false; + } + std::string agent_url = gAgent.getRegion()->getCapability("UpdateNotecardAgentInventory"); + if(!agent_url.empty()) + { + LLTransactionID tid; + LLAssetID asset_id; + tid.generate(); + asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); + + LLVFile file(gVFS, asset_id, LLAssetType::AT_NOTECARD, LLVFile::APPEND); + + std::ostringstream stream; + notecard.exportStream(stream); + std::string buffer = stream.str(); + + S32 size = buffer.length() + 1; + file.setMaxSize(size); + file.write((U8*)buffer.c_str(), size); + LLSD body; + body["item_id"] = item->getUUID(); + LLHTTPClient::post(agent_url, body, new LLUpdateAgentInventoryResponder(body, asset_id, LLAssetType::AT_NOTECARD)); + } + else + { + LL_WARNS("WindLight") << "Stuff the legacy system." << LL_ENDL; + return false; + } + + return true; +} void LLWaterParamManager::propagateParameters(void) { @@ -232,9 +310,9 @@ void LLWaterParamManager::propagateParameters(void) } bool err; - F32 fog_density_slider = - log(mCurParams.getFloat(mFogDensity.mName, err)) / - log(mFogDensity.mBase); + F32 fog_density_slider = + log(mCurParams.getFloat(mFogDensity.mName, err)) / + log(mFogDensity.mBase); setDensitySliderValue(fog_density_slider); } @@ -246,7 +324,6 @@ void LLWaterParamManager::updateShaderUniforms(LLGLSLShader * shader) shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, LLWLParamManager::getInstance()->getRotatedLightDir().mV); shader->uniform3fv("camPosLocal", 1, LLViewerCamera::getInstance()->getOrigin().mV); shader->uniform4fv("waterFogColor", 1, LLDrawPoolWater::sWaterFogColor.mV); - shader->uniform1f("waterFogEnd", LLDrawPoolWater::sWaterFogEnd); shader->uniform4fv("waterPlane", 1, mWaterPlane.mV); shader->uniform1f("waterFogDensity", getFogDensity()); shader->uniform1f("waterFogKS", mWaterFogKS); @@ -254,6 +331,26 @@ void LLWaterParamManager::updateShaderUniforms(LLGLSLShader * shader) } } +void LLWaterParamManager::applyParams(const LLSD& params, bool interpolate) +{ + if (params.size() == 0) + { + llwarns << "Undefined water params" << llendl; + return; + } + + if (interpolate) + { + LLWLParamManager::getInstance()->mAnimator.startInterpolation(params); + } + else + { + mCurParams.setAll(params); + } +} + +//static LLFastTimer::DeclareTimer FTM_UPDATE_WATERPARAM("Update Water Params"); + void LLWaterParamManager::updateShaderLinks() { mShaderList.clear(); @@ -267,7 +364,6 @@ void LLWaterParamManager::updateShaderLinks() if( glGetUniformLocationARB(shaders_iter->mProgramObject,"lightnorm")>=0 || glGetUniformLocationARB(shaders_iter->mProgramObject,"camPosLocal")>=0 || glGetUniformLocationARB(shaders_iter->mProgramObject,"waterFogColor")>=0 || - glGetUniformLocationARB(shaders_iter->mProgramObject,"waterFogEnd")>=0 || glGetUniformLocationARB(shaders_iter->mProgramObject,"waterPlane")>=0 || glGetUniformLocationARB(shaders_iter->mProgramObject,"waterFogDensity")>=0 || glGetUniformLocationARB(shaders_iter->mProgramObject,"waterFogKS")>=0 || @@ -277,11 +373,9 @@ void LLWaterParamManager::updateShaderLinks() } } -static LLFastTimer::DeclareTimer FTM_UPDATE_WATERPARAM("Update Water Params"); - void LLWaterParamManager::update(LLViewerCamera * cam) { - LLFastTimer ftm(FTM_UPDATE_WATERPARAM); + //LLFastTimer ftm(LLFastTimer::FTM_UPDATE_WLPARAM); // update the shaders and the menu propagateParameters(); @@ -317,19 +411,14 @@ void LLWaterParamManager::update(LLViewerCamera * cam) mWaterPlane = LLVector4(enorm.v[0], enorm.v[1], enorm.v[2], -ep.dot(enorm)); - if((mWaterPlane.mV[3] >= 0.f) == LLViewerCamera::getInstance()->cameraUnderWater()) //Sign borkage.. - { - mWaterPlane.scaleVec(LLVector4(-1.f,-1.f,-1.f,-1.f)); - } - LLVector3 sunMoonDir; if (gSky.getSunDirection().mV[2] > LLSky::NIGHTTIME_ELEVATION_COS) { sunMoonDir = gSky.getSunDirection(); } else - { - sunMoonDir = gSky.getMoonDirection(); + { + sunMoonDir = gSky.getMoonDirection(); } sunMoonDir.normVec(); mWaterFogKS = 1.f/llmax(sunMoonDir.mV[2], WATER_FOG_LIGHT_CLAMP); @@ -339,6 +428,7 @@ void LLWaterParamManager::update(LLViewerCamera * cam) { (*shaders_iter)->mUniformsDirty = TRUE; } + } } @@ -346,10 +436,11 @@ void LLWaterParamManager::update(LLViewerCamera * cam) bool LLWaterParamManager::addParamSet(const std::string& name, LLWaterParamSet& param) { // add a new one if not one there already - std::map::iterator mIt = mParamList.find(name); + preset_map_t::iterator mIt = mParamList.find(name); if(mIt == mParamList.end()) { mParamList[name] = param; + mPresetListChangeSignal(); return true; } @@ -358,23 +449,15 @@ bool LLWaterParamManager::addParamSet(const std::string& name, LLWaterParamSet& BOOL LLWaterParamManager::addParamSet(const std::string& name, LLSD const & param) { - // add a new one if not one there already - std::map::const_iterator finder = mParamList.find(name); - if(finder == mParamList.end()) - { - mParamList[name].setAll(param); - return TRUE; - } - else - { - return FALSE; - } + 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 - std::map::iterator mIt = mParamList.find(name); + preset_map_t::iterator mIt = mParamList.find(name); if(mIt != mParamList.end()) { param = mParamList[name]; @@ -385,6 +468,12 @@ bool LLWaterParamManager::getParamSet(const std::string& name, LLWaterParamSet& 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; @@ -408,26 +497,74 @@ bool LLWaterParamManager::setParamSet(const std::string& name, const LLSD & para bool LLWaterParamManager::removeParamSet(const std::string& name, bool delete_from_disk) { // remove from param list - std::map::iterator mIt = mParamList.find(name); - if(mIt != mParamList.end()) + preset_map_t::iterator it = mParamList.find(name); + if (it == mParamList.end()) { - mParamList.erase(mIt); + LL_WARNS("WindLight") << "No water preset named " << name << LL_ENDL; + return false; } - if(delete_from_disk) - { + mParamList.erase(it); - std::string path_name(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/water", "")); - - // use full curl escaped name - std::string escaped_name = LLWeb::curlEscape(name); - - gDirUtilp->deleteFilesInDir(path_name, escaped_name + ".xml"); + // remove from file system if requested + if (delete_from_disk) + { + if (gDirUtilp->deleteFilesInDir(getUserDir(), LLWeb::curlEscape(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() + LLWeb::curlEscape(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; @@ -449,9 +586,63 @@ F32 LLWaterParamManager::getFogDensity(void) // static void LLWaterParamManager::initSingleton() { - - loadAllPresets(LLStringUtil::null); + LL_DEBUGS("Windlight") << "Initializing water" << LL_ENDL; - getParamSet("Default", mCurParams); + loadAllPresets(); + + LLEnvManagerNew::instance().usePrefs(); } +// 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", ""); +} + +// static +void LLWaterParamManager::loadWaterNotecard(LLVFS *vfs, const LLUUID& asset_id, LLAssetType::EType asset_type, void *user_data, S32 status, LLExtStat ext_status) +{ + LLUUID inventory_id(*((LLUUID*)user_data)); + std::string name = "WindLight Setting.ww"; + LLViewerInventoryItem *item = gInventory.getItem(inventory_id); + if(item) + { + inventory_id = item->getUUID(); + name = item->getName(); + } + if(LL_ERR_NOERR == status) + { + std::string key(" Notecard: " + name); + + LLVFile file(vfs, asset_id, asset_type, LLVFile::READ); + S32 file_length = file.getSize(); + std::vector buffer(file_length + 1); + file.read((U8*)&buffer[0], file_length); + buffer[file_length] = 0; + LLNotecard notecard(LLNotecard::MAX_SIZE); + LLMemoryStream str((U8*)&buffer[0], file_length + 1); + notecard.importStream(str); + std::string settings = notecard.getText(); + LLMemoryStream settings_str((U8*)settings.c_str(), settings.length()); + + bool is_real_setting = getInstance()->loadPresetXML(key, settings_str); + if(!is_real_setting) + { + LLSD subs; + subs["NAME"] = name; + LLNotifications::instance().add("KittyInvalidWaterlightNotecard", subs); + } + else + { + // We can do this because we know mCurParams + getInstance()->mParamList[key].mInventoryID = inventory_id; + LLEnvManagerNew::instance().setUseWaterPreset(key); + } + } +} diff --git a/indra/newview/llwaterparammanager.h b/indra/newview/llwaterparammanager.h index d0f1be510..4d0aad0e8 100644 --- a/indra/newview/llwaterparammanager.h +++ b/indra/newview/llwaterparammanager.h @@ -33,11 +33,16 @@ #ifndef LL_WATER_PARAMMANAGER_H #define LL_WATER_PARAMMANAGER_H -#include +#include #include #include "llwaterparamset.h" #include "llviewercamera.h" #include "v4color.h" +#include + +#include "llassettype.h" // Ugh. + +class LLVFS; const F32 WATER_FOG_LIGHT_CLAMP = 0.3f; @@ -222,17 +227,34 @@ class LLWaterParamManager : public LLSingleton { LOG_CLASS(LLWaterParamManager); public: - + typedef std::list preset_name_list_t; typedef std::map preset_map_t; - + typedef boost::signals2::signal preset_list_signal_t; + void updateShaderLinks(); + /// load a preset file + void loadAllPresets(const std::string & fileName); + + /// load an individual preset into the sky from an LLSD stream + /// Returns whether the stream was actually reasonable XML to load from. + bool loadPresetXML(const std::string& name, std::istream& preset_stream); + + /// Load an individual preset from a notecard. + void loadPresetNotecard(const std::string& name, const LLUUID& asset_id, const LLUUID& inv_id); + /// save the parameter presets to file void savePreset(const std::string & name); + + /// save the parameter presets to file + bool savePresetToNotecard(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); @@ -248,6 +270,9 @@ public: /// 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); @@ -257,9 +282,24 @@ public: /// 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); @@ -279,6 +319,9 @@ public: F32 getFogDensity(void); LLColor4 getFogColor(void); + // singleton pattern implementation + static LLWaterParamManager * instance(); + public: LLWaterParamSet mCurParams; @@ -300,29 +343,31 @@ public: WaterFloatControl mScaleBelow; WaterFloatControl mBlurMultiplier; - F32 mDensitySliderValue; - /// load an individual preset into the sky - void loadPreset(const std::string & name,bool propagate=true); private: friend class LLSingleton; /*virtual*/ void initSingleton(); LLWaterParamManager(); ~LLWaterParamManager(); - /// load a preset file - void loadAllPresets(const std::string & fileName); + 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; - + std::vector mShaderList; // list of all the parameters, listed by name preset_map_t mParamList; - std::vector mShaderList; + preset_list_signal_t mPresetListChangeSignal; + + static void loadWaterNotecard(LLVFS *vfs, const LLUUID& asset_id, LLAssetType::EType asset_type, void *user_data, S32 status, LLExtStat ext_status); }; inline void LLWaterParamManager::setDensitySliderValue(F32 val) diff --git a/indra/newview/llwaterparamset.h b/indra/newview/llwaterparamset.h index 9d51be652..08e5b7abb 100644 --- a/indra/newview/llwaterparamset.h +++ b/indra/newview/llwaterparamset.h @@ -48,7 +48,8 @@ class LLWaterParamSet friend class LLWaterParamManager; public: - std::string mName; + std::string mName; + LLUUID mInventoryID; private: diff --git a/indra/newview/llwlanimator.cpp b/indra/newview/llwlanimator.cpp index ed90c9d7c..e0aa84806 100644 --- a/indra/newview/llwlanimator.cpp +++ b/indra/newview/llwlanimator.cpp @@ -2,31 +2,25 @@ * @file llwlanimator.cpp * @brief Implementation for the LLWLAnimator class. * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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$ */ @@ -36,15 +30,24 @@ #include "llsky.h" #include "pipeline.h" #include "llwlparammanager.h" +#include "llwaterparammanager.h" -LLWLAnimator::LLWLAnimator() : mStartTime(0), mDayRate(1), mDayTime(0), - mIsRunning(FALSE), mUseLindenTime(false) +F64 LLWLAnimator::INTERP_TOTAL_SECONDS = 3.f; + +LLWLAnimator::LLWLAnimator() : mStartTime(0.f), mDayRate(1.f), mDayTime(0.f), + mIsRunning(FALSE), mIsInterpolating(FALSE), mIsInterpolatingSky(FALSE), + mTimeType(TIME_LINDEN), mInterpStartTime(), mInterpEndTime() { - mDayTime = 0; + mInterpBeginWL = new LLWLParamSet(); + mInterpEndWL = new LLWLParamSet(); + mInterpBeginWater = new LLWaterParamSet(); + mInterpEndWater = new LLWaterParamSet(); } void LLWLAnimator::update(LLWLParamSet& curParams) { + //llassert(mUseLindenTime != mUseLocalTime); + F64 curTime; curTime = getDayTime(); @@ -108,9 +111,53 @@ void LLWLAnimator::update(LLWLParamSet& curParams) 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) + { + if (mIsInterpolatingSky) + { + deactivate(); + // FIRE-3245: Some settings do not get fully mixed properly (possibly due to value extremes) + // at the end of the interp cycle, force the end settings to get applied + curParams.setAll(mInterpEndWL->getAll()); + } + mIsInterpolating = false; + mIsInterpolatingSky = false; + return; + } + + + if (mIsInterpolatingSky) + { + weight = (current - mInterpStartTime) / (INTERP_TOTAL_SECONDS * CLOCKS_PER_SEC); + curParams.mix(*mInterpBeginWL, *mInterpEndWL, weight); + } + else + { + + // 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 - curParams.mix(LLWLParamManager::getInstance()->mParamList[mFirstIt->second], - LLWLParamManager::getInstance()->mParamList[mSecondIt->second], weight); + // *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() @@ -119,8 +166,7 @@ F64 LLWLAnimator::getDayTime() { return mDayTime; } - - if(mUseLindenTime) + else if(mTimeType == TIME_LINDEN) { F32 phase = gSky.getSunPhase() / F_PI; @@ -141,6 +187,10 @@ F64 LLWLAnimator::getDayTime() return mDayTime; } + else if(mTimeType == TIME_LOCAL) + { + return getLocalTime(); + } // get the time; mDayTime = (LLTimer::getElapsedSeconds() - mStartTime) / mDayRate; @@ -176,7 +226,7 @@ void LLWLAnimator::setDayTime(F64 dayTime) } -void LLWLAnimator::setTrack(std::map& curTrack, +void LLWLAnimator::setTrack(std::map& curTrack, F32 dayRate, F64 dayTime, bool run) { mTimeTrack = curTrack; @@ -185,3 +235,103 @@ void LLWLAnimator::setTrack(std::map& curTrack, 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; +} + +void LLWLAnimator::startInterpolationSky(const LLSD& targetSky) +{ + mInterpEndWL->setAll(targetSky); + + mIsInterpolatingSky = 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 = llround(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 index 533fd120d..8b9af371d 100644 --- a/indra/newview/llwlanimator.h +++ b/indra/newview/llwlanimator.h @@ -2,31 +2,25 @@ * @file llwlanimator.h * @brief Interface for the LLWLAnimator class. * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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$ */ @@ -34,28 +28,41 @@ #define LL_WL_ANIMATOR_H #include "llwlparamset.h" +#include "llwlparamkey.h" +#include "llwaterparamset.h" #include #include +struct LLWLParamKey; + 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 mTimeTrack; - std::map::iterator mFirstIt, mSecondIt; - - // params to use - //std::map mParamList; - - bool mIsRunning; - bool mUseLindenTime; + std::map mTimeTrack; + std::map::iterator mFirstIt, mSecondIt; // simple constructor LLWLAnimator(); + ~LLWLAnimator() + { + delete mInterpBeginWL; + delete mInterpEndWL; + delete mInterpBeginWater; + delete mInterpEndWater; + } + // update the parameters void update(LLWLParamSet& curParams); @@ -69,9 +76,67 @@ public: void setDayTime(F64 dayTime); // set an animation track - void setTrack(std::map& track, + void setTrack(std::map& 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); + void startInterpolationSky(const LLSD& targetSky); + + 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, mIsInterpolatingSky; + LLWLParamSet *mInterpBeginWL, *mInterpEndWL; + 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 abb9cd03f..61222520b 100644 --- a/indra/newview/llwldaycycle.cpp +++ b/indra/newview/llwldaycycle.cpp @@ -2,31 +2,25 @@ * @file llwldaycycle.cpp * @brief Implementation for the LLWLDayCycle class. * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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$ */ @@ -35,15 +29,13 @@ #include "llwldaycycle.h" #include "llsdserialize.h" #include "llwlparammanager.h" -#include "llweb.h" +#include "llnotificationsutil.h" #include "llviewerwindow.h" #include -LLWLDayCycle::LLWLDayCycle() : - mDayRate(120), - mName("Unnamed Cycle") +LLWLDayCycle::LLWLDayCycle() : mDayRate(120) { } @@ -52,112 +44,157 @@ LLWLDayCycle::~LLWLDayCycle() { } -void LLWLDayCycle::loadDayCycle(const std::string & fileName) +void LLWLDayCycle::loadDayCycle(const LLSD& day_data, LLWLParamKey::EScope scope) { - // clear the first few things + lldebugs << "Loading day cycle (day_data.size() = " << day_data.size() << ", scope = " << scope << ")" << llendl; mTimeMap.clear(); - // bugfix for SL-46920: preventing filenames that break stuff. - std::string escaped_filename = LLWeb::curlEscape(fileName); - - escaped_filename += ".xml"; - - std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/days", escaped_filename)); - llinfos << "Loading Day Cycle preset from " << pathName << llendl; - - llifstream day_cycle_xml; - day_cycle_xml.open(pathName.c_str()); - - // That failed, try loading from the users area instead. - if(!day_cycle_xml) + // add each key frame + for(S32 i = 0; i < day_data.size(); ++i) { - pathName=gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/days", escaped_filename); - llinfos << "Loading User Day Cycle preset from " << pathName << llendl; - day_cycle_xml.open(pathName.c_str()); - } + // make sure it's a two array + if(day_data[i].size() != 2) + { + continue; + } + + // check each param key exists in param manager + bool success; + LLWLParamSet pset; + LLWLParamKey frame = LLWLParamKey(day_data[i][1].asString(), scope); + success = + LLWLParamManager::getInstance()->getParamSet(frame, pset); + if(!success) + { + // *HACK: If loading region day cycle, try local sky presets as well. + // Local presets may be referenced by a region day cycle after + // it has been edited but the changes have not been uploaded. + if (scope == LLEnvKey::SCOPE_REGION) + { + frame.scope = LLEnvKey::SCOPE_LOCAL; + success = LLWLParamManager::getInstance()->getParamSet(frame, pset); + } - if (day_cycle_xml) + if (!success) + { + // alert the user + LLSD args; + args["SKY"] = day_data[i][1].asString(); + LLNotificationsUtil::add("WLMissingSky", args, LLSD()); + continue; + } + } + + // then add the keyframe + addKeyframe((F32)day_data[i][0].asReal(), frame); + } +} + +void LLWLDayCycle::loadDayCycleFromFile(const std::string & fileName) +{ + loadDayCycle(loadCycleDataFromFile(fileName), LLWLParamKey::SCOPE_LOCAL); +} + +/*static*/ LLSD LLWLDayCycle::loadCycleDataFromFile(const std::string & fileName) +{ + // *FIX: Cannot load user day cycles. + std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, + "windlight/days", fileName)); + + return loadDayCycleFromPath(pathName); +} + +// static +LLSD LLWLDayCycle::loadDayCycleFromPath(const std::string& file_path) +{ + LL_INFOS("Windlight") << "Loading DayCycle settings from " << file_path << LL_ENDL; + + llifstream day_cycle_xml(file_path); + if (day_cycle_xml.is_open()) { // load and parse it LLSD day_data(LLSD::emptyArray()); LLPointer parser = new LLSDXMLParser(); parser->parse(day_cycle_xml, day_data, LLSDSerialize::SIZE_UNLIMITED); - llinfos << "Loading day cycle into timeline..." << llendl; - // add each key - for(S32 i = 0; i < day_data.size(); ++i) - { - llinfos << "Loading value" << i << llendl; - // make sure it's a two array - if(day_data[i].size() != 2) - { - continue; - } - - // check each param name exists in param manager - bool success; - LLWLParamSet pset; - success = LLWLParamManager::getInstance()->getParamSet(day_data[i][1].asString(), pset); - if(!success) - { - // alert the user - LLSD args; - args["SKY"] = day_data[i][1].asString(); - LLNotifications::instance().add("WLMissingSky", args, LLSD()); - continue; - } - - // then add the key - addKey((F32)day_data[i][0].asReal(), day_data[i][1].asString()); - } - day_cycle_xml.close(); + return day_data; } - else + else { - llwarns << "Can't find " << fileName << llendl; - return; + return LLSD(); } } void LLWLDayCycle::saveDayCycle(const std::string & fileName) { - - // bugfix for SL-46920: preventing filenames that break stuff. - std::string escaped_filename = LLWeb::curlEscape(fileName); + std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/days", fileName)); + //llinfos << "Saving WindLight settings to " << pathName << llendl; - escaped_filename += ".xml"; + save(pathName); +} - std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/days", escaped_filename)); - llinfos << "Saving Day Cycle preset from " << pathName << llendl; - - llofstream day_cycle_xml; - day_cycle_xml.open(pathName.c_str()); - - // That failed, try loading from the users area instead. - if(!day_cycle_xml) - { - pathName=gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/days", escaped_filename); - llinfos << "Saving User Day Cycle preset from " << pathName << llendl; - day_cycle_xml.open(pathName.c_str()); - } - - LLSD day_data(LLSD::emptyArray()); - - for(std::map::const_iterator mIt = mTimeMap.begin(); - mIt != mTimeMap.end(); - ++mIt) - { - LLSD key(LLSD::emptyArray()); - key.append(mIt->first); - key.append(mIt->second); - day_data.append(key); - } +void LLWLDayCycle::save(const std::string& file_path) +{ + LLSD day_data = asLLSD(); + llofstream day_cycle_xml(file_path); LLPointer formatter = new LLSDXMLFormatter(); formatter->format(day_data, day_cycle_xml, LLSDFormatter::OPTIONS_PRETTY); day_cycle_xml.close(); } +LLSD LLWLDayCycle::asLLSD() +{ + LLSD day_data(LLSD::emptyArray()); + for(std::map::const_iterator mIt = mTimeMap.begin(); mIt != mTimeMap.end(); ++mIt) + { + LLSD key(LLSD::emptyArray()); + key.append(mIt->first); + key.append(mIt->second.name); + day_data.append(key); + } + + lldebugs << "Dumping day cycle (" << mTimeMap.size() << ") to LLSD: " << day_data << llendl; + return day_data; +} + +bool LLWLDayCycle::getSkyRefs(std::map& refs) const +{ + bool result = true; + LLWLParamManager* wl_mgr = LLWLParamManager::getInstance(); + + refs.clear(); + for (std::map::const_iterator iter = mTimeMap.begin(); iter != mTimeMap.end(); ++iter) + { + const LLWLParamKey& key = iter->second; + if (!wl_mgr->getParamSet(key, refs[key])) + { + llwarns << "Cannot find sky [" << key.name << "] referenced by a day cycle" << llendl; + result = false; + } + } + + return result; +} + +bool LLWLDayCycle::getSkyMap(LLSD& sky_map) const +{ + std::map refs; + + if (!getSkyRefs(refs)) + { + return false; + } + + sky_map = LLWLParamManager::createSkyMap(refs); + return true; +} + +void LLWLDayCycle::clearKeyframes() +{ + lldebugs << "Clearing key frames" << llendl; + mTimeMap.clear(); +} void LLWLDayCycle::clearKeys() { @@ -166,6 +203,11 @@ void LLWLDayCycle::clearKeys() bool LLWLDayCycle::addKey(F32 newTime, const std::string & paramName) +{ + return addKeyframe(newTime, LLWLParamKey(paramName, LLWLParamKey::SCOPE_LOCAL)); +} + +bool LLWLDayCycle::addKeyframe(F32 newTime, LLWLParamKey frame) { // no adding negative time if(newTime < 0) @@ -176,48 +218,68 @@ bool LLWLDayCycle::addKey(F32 newTime, const std::string & paramName) // if time not being used, add it and return true if(mTimeMap.find(newTime) == mTimeMap.end()) { - mTimeMap.insert(std::pair(newTime, paramName)); + mTimeMap.insert(std::pair(newTime, frame)); + lldebugs << "Adding key frame (" << newTime << ", " << frame.toLLSD() << ")" << llendl; return true; } // otherwise, don't add, and return error + llwarns << "Error adding key frame (" << newTime << ", " << frame.toLLSD() << ")" << llendl; return false; } bool LLWLDayCycle::changeKeyTime(F32 oldTime, F32 newTime) { - // just remove and add back - std::string name = mTimeMap[oldTime]; + return changeKeyframeTime(oldTime, newTime); +} - bool stat = removeKey(oldTime); +bool LLWLDayCycle::changeKeyframeTime(F32 oldTime, F32 newTime) +{ + lldebugs << "Changing key frame time (" << oldTime << " => " << newTime << ")" << llendl; + + // just remove and add back + LLWLParamKey frame = mTimeMap[oldTime]; + + bool stat = removeKeyframe(oldTime); if(stat == false) { + lldebugs << "Failed to change key frame time (" << oldTime << " => " << newTime << ")" << llendl; return stat; } - return addKey(newTime, name); + return addKeyframe(newTime, frame); } bool LLWLDayCycle::changeKeyParam(F32 time, const std::string & name) { + return changeKeyframeParam(time, LLWLParamKey(name, LLWLParamKey::SCOPE_LOCAL)); +} + +bool LLWLDayCycle::changeKeyframeParam(F32 time, LLWLParamKey key) +{ + lldebugs << "Changing key frame param (" << time << ", " << key.toLLSD() << ")" << llendl; + // just remove and add back // make sure param exists LLWLParamSet tmp; - bool stat = LLWLParamManager::getInstance()->getParamSet(name, tmp); + bool stat = LLWLParamManager::getInstance()->getParamSet(key, tmp); if(stat == false) { + lldebugs << "Failed to change key frame param (" << time << ", " << key.toLLSD() << ")" << llendl; return stat; } - mTimeMap[time] = name; + mTimeMap[time] = key; return true; } -bool LLWLDayCycle::removeKey(F32 time) +bool LLWLDayCycle::removeKeyframe(F32 time) { + lldebugs << "Removing key frame (" << time << ")" << llendl; + // look for the time. If there, erase it - std::map::iterator mIt = mTimeMap.find(time); + std::map::iterator mIt = mTimeMap.find(time); if(mIt != mTimeMap.end()) { mTimeMap.erase(mIt); @@ -229,13 +291,18 @@ bool LLWLDayCycle::removeKey(F32 time) bool LLWLDayCycle::getKey(const std::string & name, F32& key) { - // scroll through till we find the - std::map::iterator mIt = mTimeMap.begin(); + return getKeytime(LLWLParamKey(name, LLWLParamKey::SCOPE_LOCAL), key); +} + +bool LLWLDayCycle::getKeytime(LLWLParamKey frame, F32& key_time) const +{ + // scroll through till we find the correct value in the map + std::map::const_iterator mIt = mTimeMap.begin(); for(; mIt != mTimeMap.end(); ++mIt) { - if(name == mIt->second) + if(frame == mIt->second) { - key = mIt->first; + key_time = mIt->first; return true; } } @@ -246,26 +313,52 @@ bool LLWLDayCycle::getKey(const std::string & name, F32& key) bool LLWLDayCycle::getKeyedParam(F32 time, LLWLParamSet& param) { // just scroll on through till you find it - std::map::iterator mIt = mTimeMap.find(time); - if(mIt != mTimeMap.end()) + std::map::iterator mIt = mTimeMap.find(time); + if(mIt != mTimeMap.end()) { return LLWLParamManager::getInstance()->getParamSet(mIt->second, param); } // return error if not found + lldebugs << "Key " << time << " not found" << llendl; return false; } bool LLWLDayCycle::getKeyedParamName(F32 time, std::string & name) { // just scroll on through till you find it - std::map::iterator mIt = mTimeMap.find(time); + std::map::iterator mIt = mTimeMap.find(time); if(mIt != mTimeMap.end()) { - name = mTimeMap[time]; + name = mTimeMap[time].name; return true; } // return error if not found + lldebugs << "Key " << time << " not found" << llendl; return false; } + +bool LLWLDayCycle::hasReferencesTo(const LLWLParamKey& keyframe) const +{ + F32 dummy; + return getKeytime(keyframe, dummy); +} + +void LLWLDayCycle::removeReferencesTo(const LLWLParamKey& keyframe) +{ + lldebugs << "Removing references to key frame " << keyframe.toLLSD() << llendl; + F32 keytime; + bool might_exist; + do + { + // look for it + might_exist = getKeytime(keyframe, keytime); + if(!might_exist) + { + return; + } + might_exist = removeKeyframe(keytime); + + } while(might_exist); // might be another one +} diff --git a/indra/newview/llwldaycycle.h b/indra/newview/llwldaycycle.h index d886317a2..492151d59 100644 --- a/indra/newview/llwldaycycle.h +++ b/indra/newview/llwldaycycle.h @@ -2,31 +2,25 @@ * @file llwlparammanager.h * @brief Implementation for the LLWLParamManager class. * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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$ */ @@ -35,23 +29,21 @@ class LLWLDayCycle; -#include "llfloater.h" - #include #include #include #include "llwlparamset.h" #include "llwlanimator.h" +struct LLWLParamKey; +#include "llenvmanager.h" // for LLEnvKey::EScope class LLWLDayCycle { - -public: - std::string mName; + LOG_CLASS(LLWLDayCycle); public: // lists what param sets are used when during the day - std::map mTimeMap; + std::map mTimeMap; // how long is my day F32 mDayRate; @@ -65,35 +57,63 @@ public: ~LLWLDayCycle(); /// load a day cycle - void loadDayCycle(const std::string & fileName); + void loadDayCycle(const LLSD& llsd, LLEnvKey::EScope scope); /// load a day cycle + void loadDayCycleFromFile(const std::string & fileName); + + /// save a day cycle void saveDayCycle(const std::string & fileName); /// clear keys void clearKeys(); + /// save a day cycle + void save(const std::string& file_path); + + /// load the LLSD data from a file (returns the undefined LLSD if not found) + static LLSD loadCycleDataFromFile(const std::string & fileName); + + /// load the LLSD data from a file specified by full path + static LLSD loadDayCycleFromPath(const std::string& file_path); + + /// get the LLSD data for this day cycle + LLSD asLLSD(); + + // get skies referenced by this day cycle + bool getSkyRefs(std::map& refs) const; + + // get referenced skies as LLSD + bool getSkyMap(LLSD& sky_map) const; + + /// clear keyframes + void clearKeyframes(); + /// Getters and Setters /// add a new key frame to the day cycle /// returns true if successful /// no negative time bool addKey(F32 newTime, const std::string & paramName); + bool addKeyframe(F32 newTime, LLWLParamKey key); - /// adjust a key's placement in the day cycle + /// adjust a keyframe's placement in the day cycle /// returns true if successful bool changeKeyTime(F32 oldTime, F32 newTime); + bool changeKeyframeTime(F32 oldTime, F32 newTime); - /// adjust a key's parameter used + /// adjust a keyframe's parameter used /// returns true if successful bool changeKeyParam(F32 time, const std::string & paramName); + bool changeKeyframeParam(F32 time, LLWLParamKey key); - /// remove a key from the day cycle + /// remove a key frame from the day cycle /// returns true if successful - bool removeKey(F32 time); + bool removeKeyframe(F32 time); /// get the first key time for a parameter /// returns false if not there bool getKey(const std::string & name, F32& key); + bool getKeytime(LLWLParamKey keyFrame, F32& keyTime) const; /// get the param set at a given time /// returns true if found one @@ -103,6 +123,12 @@ public: /// returns true if it found one bool getKeyedParamName(F32 time, std::string & name); + /// @return true if there are references to the given sky + bool hasReferencesTo(const LLWLParamKey& keyframe) const; + + /// removes all references to the sky (paramkey) + /// does nothing if the sky doesn't exist in the day + void removeReferencesTo(const LLWLParamKey& keyframe); }; diff --git a/indra/newview/llwlhandlers.cpp b/indra/newview/llwlhandlers.cpp new file mode 100644 index 000000000..669ffb070 --- /dev/null +++ b/indra/newview/llwlhandlers.cpp @@ -0,0 +1,203 @@ +/** + * @file llwlhandlers.cpp + * @brief Various classes which handle Windlight-related messaging + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llwlhandlers.h" + +#include "llagent.h" +#include "llviewerregion.h" +#include "llenvmanager.h" +#include "llnotifications.h" + +/**** + * LLEnvironmentRequest + ****/ +// static +bool LLEnvironmentRequest::initiate() +{ + LLViewerRegion* cur_region = gAgent.getRegion(); + + if (!cur_region) + { + LL_WARNS("WindlightCaps") << "Viewer region not set yet, skipping env. settings request" << LL_ENDL; + return false; + } + + 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)); + return false; + } + + return doRequest(); +} + +// static +void LLEnvironmentRequest::onRegionCapsReceived(const LLUUID& region_id) +{ + if (region_id != gAgent.getRegion()->getRegionID()) + { + LL_INFOS("WindlightCaps") << "Got caps for a non-current region" << LL_ENDL; + return; + } + + LL_DEBUGS("WindlightCaps") << "Received region capabilities" << LL_ENDL; + doRequest(); +} + +// static +bool LLEnvironmentRequest::doRequest() +{ + std::string url = gAgent.getRegion()->getCapability("EnvironmentSettings"); + if (url.empty()) + { + LL_INFOS("WindlightCaps") << "Skipping windlight setting request - we don't have this capability" << LL_ENDL; + // region is apparently not capable of this; don't respond at all + return false; + } + + LL_INFOS("WindlightCaps") << "Requesting region windlight settings via " << url << LL_ENDL; + LLHTTPClient::get(url, new LLEnvironmentRequestResponder()); + return true; +} + +/**** + * LLEnvironmentRequestResponder + ****/ +int LLEnvironmentRequestResponder::sCount = 0; // init to 0 + +LLEnvironmentRequestResponder::LLEnvironmentRequestResponder() +{ + mID = ++sCount; +} +/*virtual*/ void LLEnvironmentRequestResponder::result(const LLSD& unvalidated_content) +{ + LL_INFOS("WindlightCaps") << "Received region windlight settings" << LL_ENDL; + + if (mID != sCount) + { + LL_INFOS("WindlightCaps") << "Got superseded by another responder; ignoring..." << LL_ENDL; + return; + } + + if (unvalidated_content[0]["regionID"].asUUID() != gAgent.getRegion()->getRegionID()) + { + LL_WARNS("WindlightCaps") << "Not in the region from where this data was received (wanting " + << gAgent.getRegion()->getRegionID() << " but got " << unvalidated_content[0]["regionID"].asUUID() + << ") - ignoring..." << LL_ENDL; + return; + } + + LLEnvManagerNew::getInstance()->onRegionSettingsResponse(unvalidated_content); +} +/*virtual*/ void LLEnvironmentRequestResponder::error(U32 status, const std::string& reason) +{ + LL_INFOS("WindlightCaps") << "Got an error, not using region windlight..." << LL_ENDL; + LLEnvManagerNew::getInstance()->onRegionSettingsResponse(LLSD()); +} + +/**** + * LLEnvironmentApply + ****/ + +clock_t LLEnvironmentApply::UPDATE_WAIT_SECONDS = clock_t(3.f); +clock_t LLEnvironmentApply::sLastUpdate = clock_t(0.f); + +// static +bool LLEnvironmentApply::initiateRequest(const LLSD& content) +{ + clock_t current = clock(); + + // Make sure we don't update too frequently. + if (current < sLastUpdate + (UPDATE_WAIT_SECONDS * CLOCKS_PER_SEC)) + { + LLSD args(LLSD::emptyMap()); + args["WAIT"] = (F64)UPDATE_WAIT_SECONDS; + LLNotifications::instance().add("EnvUpdateRate", args); + return false; + } + + sLastUpdate = current; + + // Send update request. + std::string url = gAgent.getRegion()->getCapability("EnvironmentSettings"); + if (url.empty()) + { + LL_WARNS("WindlightCaps") << "Applying windlight settings not supported" << LL_ENDL; + return false; + } + + LL_INFOS("WindlightCaps") << "Sending windlight settings to " << url << LL_ENDL; + LL_DEBUGS("WindlightCaps") << "content: " << content << LL_ENDL; + LLHTTPClient::post(url, content, new LLEnvironmentApplyResponder()); + return true; +} + +/**** + * LLEnvironmentApplyResponder + ****/ +/*virtual*/ void LLEnvironmentApplyResponder::result(const LLSD& content) +{ + if (content["regionID"].asUUID() != gAgent.getRegion()->getRegionID()) + { + LL_WARNS("WindlightCaps") << "No longer in the region where data was sent (currently " + << gAgent.getRegion()->getRegionID() << ", reply is from " << content["regionID"].asUUID() + << "); ignoring..." << LL_ENDL; + return; + } + else if (content["success"].asBoolean()) + { + LL_DEBUGS("WindlightCaps") << "Success in applying windlight settings to region " << content["regionID"].asUUID() << LL_ENDL; + LLEnvManagerNew::instance().onRegionSettingsApplyResponse(true); + } + else + { + LL_WARNS("WindlightCaps") << "Region couldn't apply windlight settings! Reason from sim: " << content["fail_reason"].asString() << LL_ENDL; + LLSD args(LLSD::emptyMap()); + args["FAIL_REASON"] = content["fail_reason"].asString(); + LLNotifications::instance().add("WLRegionApplyFail", args); + LLEnvManagerNew::instance().onRegionSettingsApplyResponse(false); + } +} +/*virtual*/ void LLEnvironmentApplyResponder::error(U32 status, const std::string& reason) +{ + std::stringstream msg; + msg << reason << " (Code " << status << ")"; + + LL_WARNS("WindlightCaps") << "Couldn't apply windlight settings to region! Reason: " << msg << LL_ENDL; + + LLSD args(LLSD::emptyMap()); + args["FAIL_REASON"] = msg.str(); + LLNotifications::instance().add("WLRegionApplyFail", args); +} diff --git a/indra/newview/llwlhandlers.h b/indra/newview/llwlhandlers.h new file mode 100644 index 000000000..213bc7c7c --- /dev/null +++ b/indra/newview/llwlhandlers.h @@ -0,0 +1,106 @@ +/** + * @file llwlhandlers.h + * @brief Headers for classes in llwlhandlers.cpp + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLWLHANDLERS_H +#define LL_LLWLHANDLERS_H + +#include "llviewerprecompiledheaders.h" +#include "llhttpclient.h" + +class LLEnvironmentRequest +{ + LOG_CLASS(LLEnvironmentRequest); +public: + /// @return true if request was successfully sent + static bool initiate(); + +private: + static void onRegionCapsReceived(const LLUUID& region_id); + static bool doRequest(); +}; + +class LLEnvironmentRequestResponder: public LLHTTPClient::Responder +{ + LOG_CLASS(LLEnvironmentRequestResponder); +public: + virtual void result(const LLSD& content); + virtual void error(U32 status, const std::string& reason); + +private: + friend class LLEnvironmentRequest; + + LLEnvironmentRequestResponder(); + static int sCount; + int mID; +}; + +class LLEnvironmentApply +{ + LOG_CLASS(LLEnvironmentApply); +public: + /// @return true if request was successfully sent + static bool initiateRequest(const LLSD& content); + +private: + static clock_t sLastUpdate; + static clock_t UPDATE_WAIT_SECONDS; +}; + +class LLEnvironmentApplyResponder: public LLHTTPClient::Responder +{ + LOG_CLASS(LLEnvironmentApplyResponder); +public: + /* + * Expecting reply from sim in form of: + * { + * regionID : uuid, + * messageID: uuid, + * success : true + * } + * or + * { + * regionID : uuid, + * success : false, + * fail_reason : string + * } + */ + virtual void result(const LLSD& content); + + virtual void error(U32 status, const std::string& reason); // non-200 errors only + +private: + friend class LLEnvironmentApply; + + LLEnvironmentApplyResponder() {} +}; + +#endif // LL_LLWLHANDLERS_H diff --git a/indra/newview/llwlparamkey.h b/indra/newview/llwlparamkey.h new file mode 100644 index 000000000..7895da371 --- /dev/null +++ b/indra/newview/llwlparamkey.h @@ -0,0 +1,127 @@ +/** + * @file llwlparamkey.h + * @brief LLWLParamKey struct + * + * $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_LLWLPARAMKEY_H +#define LL_LLWLPARAMKEY_H + +#include "lltrans.h" +#include "llenvmanager.h" + +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); + } + + inline std::string 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 + " (?)"; + } + } +}; + +#endif diff --git a/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp index a79c83b44..7943d4d29 100644 --- a/indra/newview/llwlparammanager.cpp +++ b/indra/newview/llwlparammanager.cpp @@ -55,6 +55,8 @@ #include "llagent.h" #include "llviewerregion.h" +#include "lldaycyclemanager.h" +#include "llenvmanager.h" #include "llwlparamset.h" #include "llpostprocess.h" #include "llfloaterwindlight.h" @@ -64,7 +66,19 @@ #include "llviewershadermgr.h" #include "llglslshader.h" +// For notecard loading +#include "llvfile.h" +#include "llnotecard.h" +#include "llmemorystream.h" +#include "llnotify.h" +#include "llagent.h" +#include "llinventorymodel.h" +#include "llviewerinventory.h" +#include "llviewerregion.h" +#include "llassetuploadresponders.h" + #include "curl/curl.h" +#include "llstreamtools.h" LLWLParamManager::LLWLParamManager() : @@ -107,154 +121,237 @@ LLWLParamManager::~LLWLParamManager() { } -void LLWLParamManager::loadPresets(const std::string& file_name) +void LLWLParamManager::clearParamSetsOfScope(LLWLParamKey::EScope scope) { - std::string path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", "")); - LL_INFOS2("AppInit", "Shaders") << "Loading Default WindLight settings from " << path_name << LL_ENDL; - - bool found = true; - LLDirIterator app_settings_iter(path_name, "*.xml"); - while(found) + if (LLWLParamKey::SCOPE_LOCAL == scope) { - std::string name; - found = app_settings_iter.next(name); - if(found) - { - - name=name.erase(name.length()-4); - - // bugfix for SL-46920: preventing filenames that break stuff. - char * curl_str = curl_unescape(name.c_str(), name.size()); - std::string unescaped_name(curl_str); - curl_free(curl_str); - curl_str = NULL; - - LL_DEBUGS2("AppInit", "Shaders") << "name: " << name << LL_ENDL; - loadPreset(unescaped_name,FALSE); - } - } - - // And repeat for user presets, note the user presets will modify any system presets already loaded - - std::string path_name2(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/skies", "")); - LL_INFOS2("AppInit", "Shaders") << "Loading User WindLight settings from " << path_name2 << LL_ENDL; - - found = true; - LLDirIterator user_settings_iter(path_name2, "*.xml"); - while(found) - { - std::string name; - found = user_settings_iter.next(name); - if(found) - { - name=name.erase(name.length()-4); - - // bugfix for SL-46920: preventing filenames that break stuff. - char * curl_str = curl_unescape(name.c_str(), name.size()); - std::string unescaped_name(curl_str); - curl_free(curl_str); - curl_str = NULL; - - LL_DEBUGS2("AppInit", "Shaders") << "name: " << name << LL_ENDL; - loadPreset(unescaped_name,FALSE); - } - } - -} - -void LLWLParamManager::savePresets(const std::string & fileName) -{ - //Nobody currently calls me, but if they did, then its reasonable to write the data out to the user's folder - //and not over the RO system wide version. - - LLSD paramsData(LLSD::emptyMap()); - - std::string pathName(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight", fileName)); - - for(std::map::iterator mIt = mParamList.begin(); - mIt != mParamList.end(); - ++mIt) - { - paramsData[mIt->first] = mIt->second.getAll(); - } - - llofstream presetsXML(pathName); - - LLPointer formatter = new LLSDXMLFormatter(); - - formatter->format(paramsData, presetsXML, LLSDFormatter::OPTIONS_PRETTY); - - presetsXML.close(); -} - -void LLWLParamManager::loadPreset(const std::string & name,bool propagate) -{ - - // bugfix for SL-46920: preventing filenames that break stuff. - std::string escaped_filename = LLWeb::curlEscape(name); - - escaped_filename += ".xml"; - - std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", escaped_filename)); - llinfos << "Loading WindLight sky setting from " << pathName << llendl; - - llifstream presetsXML; - presetsXML.open(pathName.c_str()); - - // That failed, try loading from the users area instead. - if(!presetsXML) - { - pathName=gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/skies", escaped_filename); - llinfos << "Loading User WindLight sky setting from " << pathName << llendl; - presetsXML.open(pathName.c_str()); - } - - if (presetsXML) - { - LLSD paramsData(LLSD::emptyMap()); - - LLPointer parser = new LLSDXMLParser(); - - parser->parse(presetsXML, paramsData, LLSDSerialize::SIZE_UNLIMITED); - - std::map::iterator mIt = mParamList.find(name); - if(mIt == mParamList.end()) - { - addParamSet(name, paramsData); - } - else - { - setParamSet(name, paramsData); - } - presetsXML.close(); - } - else - { - llwarns << "Can't find " << name << llendl; + LL_WARNS("Windlight") << "Tried to clear windlight sky presets from local system! This shouldn't be called..." << LL_ENDL; return; } - - if(propagate) + std::set to_remove; + for(std::map::iterator iter = mParamList.begin(); iter != mParamList.end(); ++iter) { - getParamSet(name, mCurParams); - propagateParameters(); + if(iter->first.scope == scope) + { + to_remove.insert(iter->first); + } } -} -void LLWLParamManager::savePreset(const std::string & name) + for(std::set::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 LLWLParamManager::finalizeFromDayCycle(LLWLParamKey::EScope scope) { - // bugfix for SL-46920: preventing filenames that break stuff. - std::string escaped_filename = LLWeb::curlEscape(name); + lldebugs << "mDay before finalizing:" << llendl; + { + for (std::map::iterator iter = mDay.mTimeMap.begin(); iter != mDay.mTimeMap.end(); ++iter) + { + LLWLParamKey& key = iter->second; + lldebugs << iter->first << "->" << key.name << llendl; + } + } - escaped_filename += ".xml"; + std::map final_references; + + // Move all referenced to desired scope, renaming if necessary + // First, save skies referenced + std::map current_references; // all skies referenced by the day cycle, with their current names + // guard against skies with same name and different scopes + std::set inserted_names; + std::map conflicted_names; // integer later used as a count, for uniquely renaming conflicts + + LLWLDayCycle& cycle = mDay; + for(std::map::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::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::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; + } + + lldebugs << "mDay after finalizing:" << llendl; + { + for (std::map::iterator iter = mDay.mTimeMap.begin(); iter != mDay.mTimeMap.end(); ++iter) + { + LLWLParamKey& key = iter->second; + lldebugs << iter->first << "->" << key.name << llendl; + } + } + + return final_references; +} + +// static +LLSD LLWLParamManager::createSkyMap(std::map refs) +{ + LLSD skies = LLSD::emptyMap(); + for(std::map::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() +{ + // 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, LLEnvManagerNew::instance().getRegionSettings().getSkyMap()); +} + +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_INFOS2("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 = dir + file; + if (!loadPreset(path)) + { + llwarns << "Error loading sky preset from " << path << llendl; + } + } +} + +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_DEBUGS2("AppInit", "Shaders") << "Loading sky " << name << LL_ENDL; + + LLSD params_data; + LLPointer 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(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/skies", escaped_filename)); + std::string pathName(getUserDir() + LLWeb::curlEscape(key.name) + ".xml"); // fill it with LLSD windlight params - paramsData = mParamList[name].getAll(); + paramsData = mParamList[key].getAll(); // write to file llofstream presetsXML(pathName); @@ -286,7 +383,6 @@ void LLWLParamManager::updateShaderUniforms(LLGLSLShader * shader) shader->uniform1f("scene_light_strength", mSceneLightStrength); } -static LLFastTimer::DeclareTimer FTM_UPDATE_WLPARAM("Update Windlight Params"); void LLWLParamManager::updateShaderLinks() { @@ -307,6 +403,8 @@ void LLWLParamManager::updateShaderLinks() } } +static LLFastTimer::DeclareTimer FTM_UPDATE_WLPARAM("Update Windlight Params"); + void LLWLParamManager::propagateParameters(void) { LLFastTimer ftm(FTM_UPDATE_WLPARAM); @@ -380,7 +478,7 @@ void LLWLParamManager::update(LLViewerCamera * cam) mCurParams.updateCloudScrolling(); // update only if running - if(mAnimator.mIsRunning) + if(mAnimator.getIsRunning()) { mAnimator.update(mCurParams); } @@ -411,7 +509,7 @@ void LLWLParamManager::update(LLViewerCamera * cam) { F32 camYawDelta = mSunDeltaYaw * DEG_TO_RAD; - LLVector3 lightNorm3(mLightDir); + LLVector3 lightNorm3(mLightDir); lightNorm3 *= LLQuaternion(-(camYaw + camYawDelta), LLVector3(0.f, 1.f, 0.f)); mRotatedLightDir = LLVector4(lightNorm3, 0.f); @@ -423,6 +521,37 @@ void LLWLParamManager::update(LLViewerCamera * cam) } } +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; +} + +bool LLWLParamManager::applySkyParams(const LLSD& params, bool interpolate /*= false*/) +{ + if (params.size() == 0) + { + llwarns << "Undefined sky params" << llendl; + return false; + } + + if (interpolate) + { + if (!mAnimator.getIsRunning()) + resetAnimator(0.f, true); + + if (!params.has("mName") || mCurParams.mName != params["mName"]) + LLWLParamManager::getInstance()->mAnimator.startInterpolationSky(params); + } + else + { + mAnimator.deactivate(); + mCurParams.setAll(params); + } + + return true; +} void LLWLParamManager::resetAnimator(F32 curTime, bool run) { @@ -431,125 +560,423 @@ void LLWLParamManager::resetAnimator(F32 curTime, bool run) return; } -bool LLWLParamManager::addParamSet(const std::string& name, LLWLParamSet& param) + +bool LLWLParamManager::addParamSet(const LLWLParamKey& key, LLWLParamSet& param) { // add a new one if not one there already - std::map::iterator mIt = mParamList.find(name); + std::map::iterator mIt = mParamList.find(key); if(mIt == mParamList.end()) { - mParamList[name] = param; + llassert(!key.name.empty()); + // *TODO: validate params + mParamList[key] = param; + mPresetListChangeSignal(); return true; } return false; } -BOOL LLWLParamManager::addParamSet(const std::string& name, LLSD const & param) +BOOL LLWLParamManager::addParamSet(const LLWLParamKey& key, LLSD const & param) { - // add a new one if not one there already - std::map::const_iterator finder = mParamList.find(name); - if(finder == mParamList.end()) - { - mParamList[name].setAll(param); - return TRUE; - } - else - { - return FALSE; - } + LLWLParamSet param_set; + param_set.setAll(param); + return addParamSet(key, param_set); } -bool LLWLParamManager::getParamSet(const std::string& name, LLWLParamSet& param) +bool LLWLParamManager::getParamSet(const LLWLParamKey& key, LLWLParamSet& param) { // find it and set it - std::map::iterator mIt = mParamList.find(name); + std::map::iterator mIt = mParamList.find(key); if(mIt != mParamList.end()) { - param = mParamList[name]; - param.mName = name; + 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 std::string& name, LLWLParamSet& param) { - mParamList[name] = param; + const LLWLParamKey key(name, LLEnvKey::SCOPE_LOCAL); + return setParamSet(key, param); +} + +bool LLWLParamManager::setParamSet(const LLWLParamKey& key, LLWLParamSet& param) +{ + llassert(!key.name.empty()); + // *TODO: validate params + mParamList[key] = param; return true; } bool LLWLParamManager::setParamSet(const std::string& name, const LLSD & param) { + const LLWLParamKey key(name, LLEnvKey::SCOPE_LOCAL); + return setParamSet(key, param); +} + +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; } - mParamList[name].setAll(param); - - return true; + LLWLParamSet param_set; + param_set.setAll(param); + return setParamSet(key, param_set); } bool LLWLParamManager::removeParamSet(const std::string& name, bool delete_from_disk) { - // remove from param list - std::map::iterator mIt = mParamList.find(name); - if(mIt != mParamList.end()) + const LLWLParamKey key(name, LLEnvKey::SCOPE_LOCAL); + return removeParamSet(key, delete_from_disk); +} + +bool 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) { - mParamList.erase(mIt); + llwarns << "Removing region skies not supported" << llendl; + llassert(key.scope == LLEnvKey::SCOPE_LOCAL); + return false; } - F32 key; - - // remove all references - bool stat = true; - do + // remove from param list + std::map::iterator it = mParamList.find(key); + if (it == mParamList.end()) { - // get it - stat = mDay.getKey(name, key); - if(stat == false) + LL_WARNS("WindLight") << "No sky preset named " << key.name << LL_ENDL; + return false; + } + + 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 = LLWeb::curlEscape(key.name); + + if(gDirUtilp->deleteFilesInDir(path_name, escaped_name + ".xml") < 1) { - break; + LL_WARNS("WindLight") << "Error removing sky preset " << key.name << " from disk" << LL_ENDL; } + } - // and remove - stat = mDay.removeKey(key); + // signal interested parties + mPresetListChangeSignal(); - } while(stat == true); - - if(delete_from_disk) + return true; +} + +bool LLWLParamManager::isSystemPreset(const std::string& preset_name) const +{ + // *TODO: file system access is excessive here. + return gDirUtilp->fileExists(getSysDir() + LLWeb::curlEscape(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::const_iterator it = mParamList.begin(); it != mParamList.end(); it++) { - std::string path_name(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/skies", "")); - - // use full curl escaped name - std::string escaped_name = LLWeb::curlEscape(name); - - gDirUtilp->deleteFilesInDir(path_name, escaped_name + ".xml"); + 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::getLocalPresetNames(preset_name_list_t& local) const +{ + local.clear(); + + for (std::map::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) + { + local.push_back(name); + } + } +} + +void LLWLParamManager::getPresetKeys(preset_key_list_t& keys) const +{ + keys.clear(); + + for (std::map::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); +} + + + +// static +void LLWLParamManager::initSingleton() +{ + LL_DEBUGS("Windlight") << "Initializing sky" << LL_ENDL; + + loadAllPresets(); + + // load the day + std::string preferred_day = LLEnvManagerNew::instance().getDayCycleName(); + if (!LLDayCycleManager::instance().getPreset(preferred_day, mDay)) + { + // Fall back to default. + llwarns << "No day cycle named " << preferred_day << ", falling back to defaults" << llendl; + mDay.loadDayCycleFromFile("Default.xml"); + + // *TODO: Fix user preferences accordingly. + } + + // *HACK - sets cloud scrolling to what we want... fix this better in the future + std::string sky = LLEnvManagerNew::instance().getSkyPresetName(); + if (!getParamSet(LLWLParamKey(sky, LLWLParamKey::SCOPE_LOCAL), mCurParams)) + { + llwarns << "No sky preset named " << sky << ", falling back to defaults" << llendl; + getParamSet(LLWLParamKey("Default", LLWLParamKey::SCOPE_LOCAL), mCurParams); + + // *TODO: Fix user preferences accordingly. + } + + // set it to noon + resetAnimator(0.5, LLEnvManagerNew::instance().getUseDayCycle()); + + // but use linden time sets it to what the estate is + mAnimator.setTimeType(LLWLAnimator::TIME_LINDEN); + + LLEnvManagerNew::instance().usePrefs(); +} + +// 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", ""); +} + + +bool LLWLParamManager::loadPresetXML(const LLWLParamKey& key, std::istream& preset_stream) +{ + LLSD params_data(LLSD::emptyMap()); + + LLPointer parser = new LLSDXMLParser(); + + if(parser->parse(preset_stream, params_data, LLSDSerialize::SIZE_UNLIMITED) == LLSDParser::PARSE_FAILURE) + { + return false; + } + + static const char* expected_windlight_settings[] = { + "ambient", + "blue_density", + "blue_horizon", + "cloud_color", + "cloud_pos_density1", + "cloud_pos_density2", + "cloud_scale", + "cloud_scroll_rate", + "cloud_shadow", + "density_multiplier", + "distance_multiplier", + "east_angle", + "enable_cloud_scroll", + "gamma", + "glow", + "haze_density", + "haze_horizon", + "lightnorm", + "max_y", + "star_brightness", + "sun_angle", + "sunlight_color" + }; + static S32 expected_count = LL_ARRAY_SIZE(expected_windlight_settings); + for(S32 i = 0; i < expected_count; ++i) + { + if(!params_data.has(expected_windlight_settings[i])) + { + LL_WARNS("WindLight") << "Attempted to load WindLight param set without " << expected_windlight_settings[i] << LL_ENDL; + return false; + } + } + + if (hasParamSet(key)) + { + setParamSet(key, params_data); + } + else + { + addParamSet(key, params_data); } return true; } - -// virtual static -void LLWLParamManager::initSingleton() +void LLWLParamManager::loadPresetNotecard(const std::string& name, const LLUUID& asset_id, const LLUUID& inv_id) { - - loadPresets(LLStringUtil::null); - - // load the day - mDay.loadDayCycle(gSavedSettings.getString("AscentActiveDayCycle")); - - // *HACK - sets cloud scrolling to what we want... fix this better in the future - getParamSet("Default", mCurParams); - - // set it to noon - resetAnimator(0.5, true); - - // but use linden time sets it to what the estate is - mAnimator.mUseLindenTime = true; - + gAssetStorage->getInvItemAsset(LLHost::invalid, + gAgent.getID(), + gAgent.getSessionID(), + gAgent.getID(), + LLUUID::null, + inv_id, + asset_id, + LLAssetType::AT_NOTECARD, + &loadWindlightNotecard, + (void*)&inv_id); +} + + +bool LLWLParamManager::savePresetToNotecard(const std::string & name) +{ + // make an empty llsd + LLSD paramsData(LLSD::emptyMap()); + + LLWLParamKey key(name, LLEnvKey::SCOPE_LOCAL); + if(!hasParamSet(key)) return false; + + // fill it with LLSD windlight params + paramsData = mParamList[key].getAll(); + + // get some XML + std::ostringstream presetsXML; + LLPointer formatter = new LLSDXMLFormatter(); + formatter->format(paramsData, presetsXML, LLSDFormatter::OPTIONS_PRETTY); + + // Write it to a notecard + LLNotecard notecard; + notecard.setText(presetsXML.str()); + + LLInventoryItem *item = gInventory.getItem(mParamList[key].mInventoryID); + if(!item) + { + mParamList[key].mInventoryID = LLUUID::null; + return false; + } + std::string agent_url = gAgent.getRegion()->getCapability("UpdateNotecardAgentInventory"); + if(!agent_url.empty()) + { + LLTransactionID tid; + LLAssetID asset_id; + tid.generate(); + asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); + + LLVFile file(gVFS, asset_id, LLAssetType::AT_NOTECARD, LLVFile::APPEND); + + std::ostringstream stream; + notecard.exportStream(stream); + std::string buffer = stream.str(); + + S32 size = buffer.length() + 1; + file.setMaxSize(size); + file.write((U8*)buffer.c_str(), size); + LLSD body; + body["item_id"] = item->getUUID(); + LLHTTPClient::post(agent_url, body, new LLUpdateAgentInventoryResponder(body, asset_id, LLAssetType::AT_NOTECARD)); + } + else + { + LL_WARNS("WindLight") << "Failed to save notecard." << LL_ENDL; + return false; + } + + return true; +} + +// static +void LLWLParamManager::loadWindlightNotecard(LLVFS *vfs, const LLUUID& asset_id, LLAssetType::EType asset_type, void *user_data, S32 status, LLExtStat ext_status) +{ + LLUUID inventory_id(*((LLUUID*)user_data)); + std::string name = "WindLight Setting.wl"; + LLViewerInventoryItem *item = gInventory.getItem(inventory_id); + if(item) + { + inventory_id = item->getUUID(); + name = item->getName(); + } + if(LL_ERR_NOERR == status) + { + LLVFile file(vfs, asset_id, asset_type, LLVFile::READ); + S32 file_length = file.getSize(); + std::vector buffer(file_length + 1); + file.read((U8*)&buffer[0], file_length); + buffer[file_length] = 0; + LLNotecard notecard(LLNotecard::MAX_SIZE); + LLMemoryStream str((U8*)&buffer[0], file_length + 1); + notecard.importStream(str); + std::string settings = notecard.getText(); + LLMemoryStream settings_str((U8*)settings.c_str(), settings.length()); + + LLWLParamKey key((" Notecard: " + name), LLEnvKey::SCOPE_LOCAL); + bool is_real_setting = getInstance()->loadPresetXML(key, settings_str); + if(!is_real_setting) + { + LLSD subs; + subs["NAME"] = name; + LLNotifications::getInstance()->add("KittyInvalidWindlightNotecard", subs); + } + else + { + // We can do this because we know mCurParams + getInstance()->mParamList[key].mInventoryID = inventory_id; + LLEnvManagerNew::instance().setUseSkyPreset(key.name); + } + } } diff --git a/indra/newview/llwlparammanager.h b/indra/newview/llwlparammanager.h index e89f1ee22..104ac8374 100644 --- a/indra/newview/llwlparammanager.h +++ b/indra/newview/llwlparammanager.h @@ -33,14 +33,28 @@ #ifndef LL_WLPARAMMANAGER_H #define LL_WLPARAMMANAGER_H -#include +#include #include +#include "llenvmanager.h" #include "llwlparamset.h" #include "llwlanimator.h" #include "llwldaycycle.h" #include "llviewercamera.h" +#include "lltrans.h" + +#include "llassettype.h" // Ugh. +class LLVFS; class LLGLSLShader; + +class LLWLAnimator; + +//class LLWLPresetsObserver +//{ +//public: +// virtual ~LLWLPresetsObserver() { }; +// virtual void changed() = 0; +//}; // color control struct WLColorControl { @@ -78,7 +92,7 @@ struct WLColorControl { r = val.mV[0]; g = val.mV[1]; b = val.mV[2]; - i = val.mV[3]; + i = val.mV[3]; return *this; } @@ -127,18 +141,24 @@ class LLWLParamManager : public LLSingleton LOG_CLASS(LLWLParamManager); public: + typedef std::list preset_name_list_t; + typedef std::list preset_key_list_t; + typedef boost::signals2::signal preset_list_signal_t; void updateShaderLinks(); - - /// save the preset file - void savePresets(const std::string & fileName); - - /// load an individual preset into the sky - void loadPreset(const std::string & name,bool propogate=true); - + /// load an individual preset into the sky from an LLSD stream + /// Returns whether the stream was actually reasonable XML to load from. + bool loadPresetXML(const LLWLParamKey& key, std::istream& preset_stream); + + /// Load an individual preset from a notecard. + void loadPresetNotecard(const std::string& name, const LLUUID& asset_id, const LLUUID& inv_id); + /// save the parameter presets to file - void savePreset(const std::string & name); + void savePreset(const LLWLParamKey key); + + /// save the parameter presets to file + bool savePresetToNotecard(const std::string & name); /// Set shader uniforms dirty, so they'll update automatically. void propagateParameters(void); @@ -152,6 +172,12 @@ public: /// 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 specified fixed sky params + bool applySkyParams(const LLSD& params, bool interpolate = false); + // get where the light is pointing inline LLVector4 getLightDir(void) const; @@ -166,6 +192,69 @@ public: /// 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 std::string& name, LLWLParamSet& param); + bool setParamSet(const LLWLParamKey& key, LLWLParamSet& param); + + /// set the param in the list with a new param + bool setParamSet(const std::string& name, LLSD const & param); + bool setParamSet(const LLWLParamKey& key, 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); + /// ignores "delete_from_disk" if the scope is not local + bool 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 all local (user + sys) preset names + void getLocalPresetNames(preset_name_list_t& local) 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(); + + // 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 finalizeFromDayCycle(LLWLParamKey::EScope scope); + + // returns all skies in map (intended to be called with output from a finalize) + static LLSD createSkyMap(std::map map); + + /// @return all named windlight presets. + const std::map& getPresets() const { return mParamList; } /// Perform global initialization for this class. static void initClass(void); @@ -173,30 +262,6 @@ public: // Cleanup of global data that's only inited once per class. static void cleanupClass(); - /// add a param to the list - bool addParamSet(const std::string& name, LLWLParamSet& 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, LLWLParamSet& param); - - /// set the param in the list with a new param - bool setParamSet(const std::string& name, LLWLParamSet& 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 all named windlight presets. - const std::map& getPresets() const { return mParamList; } - -public: - // helper variables LLWLAnimator mAnimator; @@ -248,23 +313,30 @@ public: F32 mDomeOffset; F32 mDomeRadius; - - + private: - /// load a preset file friend class LLWLAnimator; - void loadPresets(const std::string & fileName); + + std::vector mShaderList; friend class LLSingleton; /*virtual*/ void initSingleton(); LLWLParamManager(); ~LLWLParamManager(); + static void loadWindlightNotecard(LLVFS *vfs, const LLUUID& asset_id, LLAssetType::EType asset_type, void *user_data, S32 status, LLExtStat ext_status); + + void loadAllPresets(); + void loadPresetsFromDir(const std::string& dir); + bool loadPreset(const std::string& path); + + static std::string getSysDir(); + static std::string getUserDir(); + // list of all the parameters, listed by name - std::map mParamList; - - std::vector mShaderList; + std::map mParamList; + preset_list_signal_t mPresetListChangeSignal; }; inline F32 LLWLParamManager::getDomeOffset(void) const diff --git a/indra/newview/llwlparamset.h b/indra/newview/llwlparamset.h index f403fbe23..ab7903240 100644 --- a/indra/newview/llwlparamset.h +++ b/indra/newview/llwlparamset.h @@ -48,7 +48,8 @@ class LLWLParamSet { friend class LLWLParamManager; public: - std::string mName; + std::string mName; + LLUUID mInventoryID; private: diff --git a/indra/newview/rlvextensions.cpp b/indra/newview/rlvextensions.cpp index 11e89f0e9..1da5f55a9 100644 --- a/indra/newview/rlvextensions.cpp +++ b/indra/newview/rlvextensions.cpp @@ -312,11 +312,11 @@ std::string RlvExtGetSet::onGetEnv(std::string strSetting) F32 nValue = 0.0f; if ("daytime" == strSetting) { - nValue = (pWLParams->mAnimator.mIsRunning && pWLParams->mAnimator.mUseLindenTime) ? -1.0f : pWLParams->mAnimator.getDayTime(); + nValue = (pWLParams->mAnimator.getIsRunning() && pWLParams->mAnimator.getUseLindenTime()) ? -1.0f : pWLParams->mAnimator.getDayTime(); } else if ("preset" == strSetting) { - return (pWLParams->mAnimator.mIsRunning && pWLParams->mAnimator.mUseLindenTime) ? std::string() : pWLParams->mCurParams.mName; + return (pWLParams->mAnimator.getIsRunning() && pWLParams->mAnimator.getUseLindenTime()) ? std::string() : pWLParams->mCurParams.mName; } else if ("cloudcoverage" == strSetting) nValue = pWLParams->mCloudCoverage; else if ("cloudscale" == strSetting) nValue = pWLParams->mCloudScale; @@ -390,8 +390,8 @@ ERlvCmdRet RlvExtGetSet::onSetEnv(std::string strSetting, const std::string& str return RLV_RET_FAILED_OPTION; // Not quite correct, but RLV-1.16.0 will halt the default daytime cycle on invalid commands so we need to as well - pWLParams->mAnimator.mIsRunning = false; - pWLParams->mAnimator.mUseLindenTime = false; + pWLParams->mAnimator.deactivate(); + //pWLParams->mAnimator.mUseLindenTime = false; // See LLWorldEnvSettings::handleEvent() if ("daytime" == strSetting) @@ -403,15 +403,16 @@ ERlvCmdRet RlvExtGetSet::onSetEnv(std::string strSetting, const std::string& str } else { - pWLParams->mAnimator.mIsRunning = true; - pWLParams->mAnimator.mUseLindenTime = true; + pWLParams->mAnimator.activate(LLWLAnimator::TIME_LINDEN); } return RLV_RET_SUCCESS; } // See LLFloaterWindLight::onChangePresetName() else if ("preset" == strSetting) { - pWLParams->loadPreset(strValue, true); + // LLEnvManagerNew manages using presets now -KC + //pWLParams->loadPreset(strValue, true); + LLEnvManagerNew::instance().useSkyPreset(strValue); return RLV_RET_SUCCESS; } // See LLFloaterWindLight::onStarAlphaMoved diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp index c27ee59ce..2c2314aa9 100644 --- a/indra/newview/rlvhelper.cpp +++ b/indra/newview/rlvhelper.cpp @@ -1019,8 +1019,10 @@ void RlvWLSnapshot::restoreSnapshot(const RlvWLSnapshot* pWLSnapshot) LLWLParamManager* pWLParams = LLWLParamManager::getInstance(); if ( (pWLSnapshot) && (pWLParams) ) { - pWLParams->mAnimator.mIsRunning = pWLSnapshot->fIsRunning; - pWLParams->mAnimator.mUseLindenTime = pWLSnapshot->fUseLindenTime; + if (pWLSnapshot->fIsRunning) + { + pWLParams->mAnimator.activate(pWLSnapshot->fUseLindenTime ? LLWLAnimator::TIME_LINDEN : LLWLAnimator::TIME_CUSTOM); + } pWLParams->mCurParams = pWLSnapshot->WLParams; pWLParams->propagateParameters(); } @@ -1041,8 +1043,8 @@ RlvWLSnapshot* RlvWLSnapshot::takeSnapshot() if (pWLParams) { pWLSnapshot = new RlvWLSnapshot(); - pWLSnapshot->fIsRunning = pWLParams->mAnimator.mIsRunning; - pWLSnapshot->fUseLindenTime = pWLParams->mAnimator.mUseLindenTime; + pWLSnapshot->fIsRunning = pWLParams->mAnimator.getIsRunning(); + pWLSnapshot->fUseLindenTime = pWLParams->mAnimator.getUseLindenTime(); pWLSnapshot->WLParams = pWLParams->mCurParams; } return pWLSnapshot; diff --git a/indra/newview/wlfPanel_AdvSettings.cpp b/indra/newview/wlfPanel_AdvSettings.cpp index 40952c1bd..9219e9798 100644 --- a/indra/newview/wlfPanel_AdvSettings.cpp +++ b/indra/newview/wlfPanel_AdvSettings.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009 +/* Copyright (c) 2010 * * Modular Systems All rights reserved. * @@ -16,7 +16,7 @@ * may be used to endorse or promote products derived from this * software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY MODULAR SYSTEMS AND CONTRIBUTORS “AS IS” + * THIS SOFTWARE IS PROVIDED BY MODULAR SYSTEMS AND CONTRIBUTORS “AS IS” * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MODULAR SYSTEMS OR CONTRIBUTORS @@ -40,15 +40,26 @@ #include "lloverlaybar.h" #include "lltextbox.h" #include "llcombobox.h" -#include "llwlparammanager.h" -#include "llwaterparammanager.h" +#include "llsliderctrl.h" +#include "llcheckboxctrl.h" #include "llstartup.h" +#include "llfloaterwindlight.h" +#include "llfloaterwater.h" + +#include "lldaycyclemanager.h" +#include "llenvmanager.h" +#include "llwaterparammanager.h" +#include "llwlparamset.h" +#include "llwlparammanager.h" + +// [RLVa:KB] +#include "rlvhandler.h" +// [/RLVa:KB] BOOL firstBuildDone; void* fixPointer; std::string ButtonState; -std::string current_preset = "Default"; wlfPanel_AdvSettings::wlfPanel_AdvSettings() { @@ -73,11 +84,49 @@ void wlfPanel_AdvSettings::build() void wlfPanel_AdvSettings::refresh() { - if (gSavedSettings.getBOOL("wlfAdvSettingsPopup")) +// [RLVa:KB] - Checked: 2009-09-19 + if ( (rlv_handler_t::isEnabled()) && (gSavedSettings.getBOOL("wlfAdvSettingsPopup")) ) { - childSetEnabled("WLSkyPresetsCombo", true); - childSetEnabled("WLWaterPresetsCombo", true); + childSetEnabled("use_estate_wl", !gRlvHandler.hasBehaviour(RLV_BHVR_SETENV)); + childSetEnabled("EnvAdvancedWaterButton", !gRlvHandler.hasBehaviour(RLV_BHVR_SETENV)); + childSetEnabled("WWPresetsCombo", !gRlvHandler.hasBehaviour(RLV_BHVR_SETENV)); + childSetEnabled("WWprev", !gRlvHandler.hasBehaviour(RLV_BHVR_SETENV)); + childSetEnabled("WWnext", !gRlvHandler.hasBehaviour(RLV_BHVR_SETENV)); + childSetEnabled("EnvAdvancedSkyButton", !gRlvHandler.hasBehaviour(RLV_BHVR_SETENV)); + childSetEnabled("WLPresetsCombo", !gRlvHandler.hasBehaviour(RLV_BHVR_SETENV)); + childSetEnabled("WLprev", !gRlvHandler.hasBehaviour(RLV_BHVR_SETENV)); + childSetEnabled("WLnext", !gRlvHandler.hasBehaviour(RLV_BHVR_SETENV)); + childSetEnabled("EnvTimeSlider", !gRlvHandler.hasBehaviour(RLV_BHVR_SETENV)); } +// [/RLVa:KB] +} + +void wlfPanel_AdvSettings::refreshLists() +{ + LLEnvManagerNew& env_mgr = LLEnvManagerNew::instance(); + + // Populate the combo boxes with appropriate lists of available presets. + //actually, dont do this, its laggy and not needed to just refresh the selections + // populateWaterPresetsList(); + // populateSkyPresetsList(); + // populateDayCyclePresetsList(); + + //populate the combos with "Default" if using region settings + if (gSavedSettings.getBOOL("UseEnvironmentFromRegion")) + { + mWaterPresetCombo->selectByValue("Default"); + mSkyPresetCombo->selectByValue("Default"); + //mDayCyclePresetCombo->selectByValue("Default"); + } + else + { + // Select the current presets in combo boxes. + mWaterPresetCombo->selectByValue(env_mgr.getWaterPresetName()); + mSkyPresetCombo->selectByValue(env_mgr.getSkyPresetName()); + //mDayCyclePresetCombo->selectByValue(env_mgr.getDayCycleName()); + } + + updateTimeSlider(); } void wlfPanel_AdvSettings::fixPanel() @@ -89,46 +138,52 @@ void wlfPanel_AdvSettings::fixPanel() onClickExpandBtn(fixPointer); } } + BOOL wlfPanel_AdvSettings::postBuild() { childSetAction("expand", onClickExpandBtn, this); - - LLComboBox* comboBoxSky = getChild("WLSkyPresetsCombo"); - if(comboBoxSky != NULL) - { - std::map::const_iterator mIt = LLWLParamManager::getInstance()->getPresets().begin(); - for(; mIt != LLWLParamManager::getInstance()->getPresets().end(); mIt++) - { - if (mIt->first.length() > 0) - comboBoxSky->add(mIt->first); - } - comboBoxSky->add(LLStringUtil::null); - comboBoxSky->selectByValue(LLSD(current_preset)); - } - comboBoxSky->setCommitCallback(onChangePresetName); - LLComboBox* comboBoxWater = getChild("WLWaterPresetsCombo"); - if(comboBoxWater != NULL) - { - std::map::const_iterator mIt = LLWaterParamManager::getInstance()->getPresets().begin(); - for(; mIt != LLWaterParamManager::getInstance()->getPresets().end(); mIt++) - { - if (mIt->first.length() > 0) - comboBoxWater->add(mIt->first); - } - comboBoxWater->add(LLStringUtil::null); - comboBoxWater->selectByValue(LLSD(current_preset)); - } - comboBoxWater->setCommitCallback(onChangePresetName); + getChild("use_estate_wl")->setCommitCallback(onUseRegionSettings); + + mWaterPresetCombo = getChild("WWPresetsCombo"); + mWaterPresetCombo->setCommitCallback(onChangeWWPresetName); + + mSkyPresetCombo = getChild("WLPresetsCombo"); + mSkyPresetCombo->setCommitCallback(onChangeWLPresetName); + + // mDayCyclePresetCombo = getChild("DCPresetsCombo"); + // mDayCyclePresetCombo->setCommitCallback(onChangeDCPresetName); + + LLEnvManagerNew::instance().setPreferencesChangeCallback(boost::bind(&wlfPanel_AdvSettings::refreshLists, this)); + LLWaterParamManager::getInstance()->setPresetListChangeCallback(boost::bind(&wlfPanel_AdvSettings::populateWaterPresetsList, this)); + LLWLParamManager::getInstance()->setPresetListChangeCallback(boost::bind(&wlfPanel_AdvSettings::populateSkyPresetsList, this)); + // LLDayCycleManager::instance().setModifyCallback(boost::bind(&wlfPanel_AdvSettings::populateDayCyclePresetsList, this)); + + populateWaterPresetsList(); + populateSkyPresetsList(); + //populateDayCyclePresetsList(); + + // next/prev buttons + childSetAction("WWnext", onClickWWNext, this); + childSetAction("WWprev", onClickWWPrev, this); + childSetAction("WLnext", onClickWLNext, this); + childSetAction("WLprev", onClickWLPrev, this); + + childSetAction("EnvAdvancedSkyButton", onOpenAdvancedSky, NULL); + childSetAction("EnvAdvancedWaterButton", onOpenAdvancedWater, NULL); + + mTimeSlider = getChild("EnvTimeSlider"); + mTimeSlider->setCommitCallback(onChangeDayTime); + updateTimeSlider(); + fixPointer = this; - /*onClickExpandBtn(fixPointer); - onClickExpandBtn(fixPointer);*/ return TRUE; } + void wlfPanel_AdvSettings::draw() { LLButton* expand_button = getChild("expand"); - /*if (expand_button) +/* if (expand_button) { if (expand_button->getToggleState()) { @@ -138,14 +193,16 @@ void wlfPanel_AdvSettings::draw() { expand_button->setImageOverlay("arrow_up.tga"); } - }*/ - expand_button->setImageOverlay(ButtonState); + } */ + expand_button->setImageOverlay(ButtonState); refresh(); LLPanel::draw(); } + wlfPanel_AdvSettings::~wlfPanel_AdvSettings () { } + void wlfPanel_AdvSettings::onClickExpandBtn(void* user_data) { gSavedSettings.setBOOL("wlfAdvSettingsPopup",!gSavedSettings.getBOOL("wlfAdvSettingsPopup")); @@ -153,29 +210,229 @@ void wlfPanel_AdvSettings::onClickExpandBtn(void* user_data) remotep->build(); gOverlayBar->layoutButtons(); } -void wlfPanel_AdvSettings::onChangePresetName(LLUICtrl* ctrl, void * userData) -{ - LLWLParamManager::getInstance()->mAnimator.mIsRunning = false; - LLWLParamManager::getInstance()->mAnimator.mUseLindenTime = false; +void wlfPanel_AdvSettings::onUseRegionSettings(LLUICtrl* ctrl, void* userdata) +{ + LLEnvManagerNew::instance().setUseRegionSettings(gSavedSettings.getBOOL("UseEnvironmentFromRegion"), gSavedSettings.getBOOL("PhoenixInterpolateSky")); +} + +void wlfPanel_AdvSettings::onChangeWWPresetName(LLUICtrl* ctrl, void * userData) +{ LLComboBox * combo_box = static_cast(ctrl); - llinfos << "Combobox is " << combo_box->getControlName() << " aka " << combo_box->getName() << llendl; - if (combo_box->getName() == "WLSkyPresetsCombo") + + if(combo_box->getSimple() == "") { - if(combo_box->getSimple() == "") - { - return; - } - current_preset = combo_box->getSelectedValue().asString(); - LLWLParamManager::getInstance()->loadPreset(current_preset); + return; } - else if (combo_box->getName() == "WLWaterPresetsCombo") + + const std::string& wwset = combo_box->getSelectedValue().asString(); + if (LLWaterParamManager::getInstance()->hasParamSet(wwset)) { - if(combo_box->getSimple() == "") - { - return; - } - current_preset = combo_box->getSelectedValue().asString(); - LLWaterParamManager::getInstance()->loadPreset(current_preset); + LLEnvManagerNew::instance().setUseWaterPreset(wwset, gSavedSettings.getBOOL("PhoenixInterpolateWater")); + } + else + { + //if that failed, use region's + // LLEnvManagerNew::instance().useRegionWater(); + LLEnvManagerNew::instance().setUseWaterPreset("Default", gSavedSettings.getBOOL("PhoenixInterpolateWater")); } } + +void wlfPanel_AdvSettings::onChangeWLPresetName(LLUICtrl* ctrl, void * userData) +{ + LLComboBox * combo_box = static_cast(ctrl); + + if(combo_box->getSimple() == "") + { + return; + } + + const LLWLParamKey key(combo_box->getSelectedValue().asString(), LLEnvKey::SCOPE_LOCAL); + if (LLWLParamManager::getInstance()->hasParamSet(key)) + { + LLEnvManagerNew::instance().setUseSkyPreset(key.name, gSavedSettings.getBOOL("PhoenixInterpolateSky")); + } + else + { + //if that failed, use region's + // LLEnvManagerNew::instance().useRegionSky(); + LLEnvManagerNew::instance().setUseSkyPreset("Default", gSavedSettings.getBOOL("PhoenixInterpolateSky")); + } +} + +void wlfPanel_AdvSettings::onClickWWNext(void* user_data) +{ + wlfPanel_AdvSettings* self = (wlfPanel_AdvSettings*) user_data; + + S32 index = self->mWaterPresetCombo->getCurrentIndex(); + index++; + if (index == self->mWaterPresetCombo->getItemCount()) + index = 0; + self->mWaterPresetCombo->setCurrentByIndex(index); + + wlfPanel_AdvSettings::onChangeWWPresetName(self->mWaterPresetCombo, self); +} + +void wlfPanel_AdvSettings::onClickWWPrev(void* user_data) +{ + wlfPanel_AdvSettings* self = (wlfPanel_AdvSettings*) user_data; + + S32 index = self->mWaterPresetCombo->getCurrentIndex(); + if (index == 0) + index = self->mWaterPresetCombo->getItemCount(); + index--; + self->mWaterPresetCombo->setCurrentByIndex(index); + + wlfPanel_AdvSettings::onChangeWWPresetName(self->mWaterPresetCombo, self); +} + +void wlfPanel_AdvSettings::onClickWLNext(void* user_data) +{ + wlfPanel_AdvSettings* self = (wlfPanel_AdvSettings*) user_data; + + S32 index = self->mSkyPresetCombo->getCurrentIndex(); + index++; + if (index == self->mSkyPresetCombo->getItemCount()) + index = 0; + self->mSkyPresetCombo->setCurrentByIndex(index); + + wlfPanel_AdvSettings::onChangeWLPresetName(self->mSkyPresetCombo, self); +} + +void wlfPanel_AdvSettings::onClickWLPrev(void* user_data) +{ + wlfPanel_AdvSettings* self = (wlfPanel_AdvSettings*) user_data; + + S32 index = self->mSkyPresetCombo->getCurrentIndex(); + if (index == 0) + index = self->mSkyPresetCombo->getItemCount(); + index--; + self->mSkyPresetCombo->setCurrentByIndex(index); + + wlfPanel_AdvSettings::onChangeWLPresetName(self->mSkyPresetCombo, self); +} + +void wlfPanel_AdvSettings::onOpenAdvancedSky(void* userData) +{ + LLFloaterWindLight::show(); +} + +void wlfPanel_AdvSettings::onOpenAdvancedWater(void* userData) +{ + LLFloaterWater::show(); +} + +void wlfPanel_AdvSettings::onChangeDayTime(LLUICtrl* ctrl, void* userData) +{ + LLSliderCtrl* sldr = static_cast(ctrl); + + if (sldr) { + // deactivate animator + LLWLParamManager::getInstance()->mAnimator.deactivate(); + + F32 val = sldr->getValueF32() + 0.25f; + if(val > 1.0) + { + val--; + } + + LLWLParamManager::getInstance()->mAnimator.setDayTime((F64)val); + LLWLParamManager::getInstance()->mAnimator.update( + LLWLParamManager::getInstance()->mCurParams); + } +} + +void wlfPanel_AdvSettings::populateWaterPresetsList() +{ + mWaterPresetCombo->removeall(); + + std::list presets; + LLWaterParamManager::getInstance()->getPresetNames(presets); + + for (std::list::const_iterator it = presets.begin(); it != presets.end(); ++it) + { + mWaterPresetCombo->add(*it); + } + + //populate the combos with "Default" if using region settings + if (gSavedSettings.getBOOL("UseEnvironmentFromRegion")) + { + mWaterPresetCombo->selectByValue("Default"); + } + else + { + // Select the current presets in combo boxes. + mWaterPresetCombo->selectByValue(LLEnvManagerNew::instance().getWaterPresetName()); + } +} + +void wlfPanel_AdvSettings::populateSkyPresetsList() +{ + mSkyPresetCombo->removeall(); + + LLWLParamManager::preset_name_list_t local_presets; + LLWLParamManager::getInstance()->getLocalPresetNames(local_presets); + + for (LLWLParamManager::preset_name_list_t::const_iterator it = local_presets.begin(); it != local_presets.end(); ++it) + { + mSkyPresetCombo->add(*it); + } + + //populate the combos with "Default" if using region settings + if (gSavedSettings.getBOOL("UseEnvironmentFromRegion")) + { + mSkyPresetCombo->selectByValue("Default"); + } + else + { + // Select the current presets in combo boxes. + mSkyPresetCombo->selectByValue(LLEnvManagerNew::instance().getSkyPresetName()); + } +} + +// void wlfPanel_AdvSettings::populateDayCyclePresetsList() +// { + // mDayCyclePresetCombo->removeall(); + + // LLDayCycleManager::preset_name_list_t user_days, sys_days; + // LLDayCycleManager::instance().getPresetNames(user_days, sys_days); + + // // 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); + // } + + //populate the combos with "Default" if using region settings + // if (gSavedSettings.getBOOL("UseEnvironmentFromRegion")) + // { + // mDayCyclePresetCombo->selectByValue("Default"); + // } + // else + // { + // Select the current presets in combo boxes. + // mDayCyclePresetCombo->selectByValue(LLEnvManagerNew::instance().getDayCycleName()); + // } +// } + +void wlfPanel_AdvSettings::updateTimeSlider() +{ + + F32 val = LLWLParamManager::getInstance()->mAnimator.getDayTime() - 0.25f; + if(val < 0.0) + { + val++; + } + mTimeSlider->setValue(val); +} diff --git a/indra/newview/wlfPanel_AdvSettings.h b/indra/newview/wlfPanel_AdvSettings.h index 73d59a65d..b2f48431d 100644 --- a/indra/newview/wlfPanel_AdvSettings.h +++ b/indra/newview/wlfPanel_AdvSettings.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2009 +/* Copyright (c) 2010 * * Modular Systems All rights reserved. * @@ -16,7 +16,7 @@ * may be used to endorse or promote products derived from this * software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY MODULAR SYSTEMS AND CONTRIBUTORS “AS IS” + * THIS SOFTWARE IS PROVIDED BY MODULAR SYSTEMS AND CONTRIBUTORS “AS IS” * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MODULAR SYSTEMS OR CONTRIBUTORS @@ -34,6 +34,9 @@ #include "llpanel.h" +class LLComboBox; +class LLSliderCtrl; + class wlfPanel_AdvSettings : public LLPanel { public: @@ -46,11 +49,32 @@ public: static void fixPanel(); static void onClickExpandBtn(void* user_data); - static void onChangePresetName(LLUICtrl* ctrl, void* userData); + static void onChangeWWPresetName(LLUICtrl* ctrl, void* userData); + static void onChangeWLPresetName(LLUICtrl* ctrl, void* userData); protected: void build(); + static void onUseRegionSettings(LLUICtrl* ctrl, void* userdata); + static void onClickWWNext(void* user_data); + static void onClickWWPrev(void* user_data); + static void onClickWLNext(void* user_data); + static void onClickWLPrev(void* user_data); + static void onOpenAdvancedSky(void* userData); + static void onOpenAdvancedWater(void* userData); + static void onChangeDayTime(LLUICtrl* ctrl, void* userData); + + void refreshLists(); /// update controls with user prefs + + void populateWaterPresetsList(); + void populateSkyPresetsList(); + // void populateDayCyclePresetsList(); + void updateTimeSlider(); + + LLComboBox* mWaterPresetCombo; + LLComboBox* mSkyPresetCombo; + // LLComboBox* mDayCyclePresetCombo; + LLSliderCtrl* mTimeSlider; }; #endif // LL_wlfPanel_AdvSettings_H