diff --git a/indra/llcommon/llfasttimer_class.cpp b/indra/llcommon/llfasttimer_class.cpp index 83c5b4fc1..15075aa87 100644 --- a/indra/llcommon/llfasttimer_class.cpp +++ b/indra/llcommon/llfasttimer_class.cpp @@ -27,7 +27,7 @@ // // LLFastTimer documentation, written by Aleric (Feb 2012). // -// Disclaimer: this is horrible code and I distantiate myself from it's design. +// Disclaimer: this is horrible code and I distantiate myself from its design. // It's neither robust nor object oriented. I just document what I find, in // order to be able to fix the bugs (that logically result from such a design). // @@ -63,12 +63,12 @@ // LLFastTimer::getFrameStateList()[named_timer.getFrameStateIndex()], where // getFrameStateList() is a static function returning a global std::vector. // This vector is ordered "Depth First" (the FrameState objects (belonging to -// NamedTimer objects) with smallest depth first). The vector is resorted a few +// NamedTimer objects) with smallest depth first). The vector is re-sorted a few // times in the beginning (and indexes in FrameState updated) since timers are added // whenever they are first used, not in "Depth First" order, but stabilizes after a // while. This implies that FrameState pointers can't really be used: FrameState // objects move around in memory whenever something is inserted or removed from the -// std::vector and/or when the vector is resorted. However, FrameState pointers ARE +// std::vector and/or when the vector is re-sorted. However, FrameState pointers ARE // being used and code exists that tries to update those pointers in the above // mentioned cases (this part had bugs, which I now fixed). // diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 454cbfd94..2df854365 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -85,7 +85,11 @@ set(viewer_SOURCE_FILES floaterao.cpp floatervoicelicense.cpp cofmgr.cpp - ascentdaycyclemanager.cpp + lldaycyclemanager.cpp + llenvmanager.cpp + llwlhandlers.cpp + llregioninfomodel.cpp + m7wlinterface.cpp ascentfloatercontactgroups.cpp ascentkeyword.cpp ascentprefschat.cpp @@ -564,7 +568,11 @@ set(viewer_HEADER_FILES floaterao.h floatervoicelicense.h cofmgr.h - ascentdaycyclemanager.h + lldaycyclemanager.h + llenvmanager.h + llwlhandlers.h + llregioninfomodel.h + m7wlinterface.h ascentfloatercontactgroups.h ascentkeyword.h ascentprefschat.h diff --git a/indra/newview/app_settings/keys.ini b/indra/newview/app_settings/keys.ini index 2cdc5e8d9..bf9c94a09 100644 --- a/indra/newview/app_settings/keys.ini +++ b/indra/newview/app_settings/keys.ini @@ -52,7 +52,7 @@ FIRST_PERSON F SHIFT toggle_fly FIRST_PERSON SPACE NONE stop_moving FIRST_PERSON ENTER NONE start_chat -FIRST_PERSON DIVIDE NONE start_gesture +FIRST_PERSON / NONE start_gesture FIRST_PERSON LEFT SHIFT slide_left FIRST_PERSON RIGHT SHIFT slide_right @@ -89,7 +89,7 @@ THIRD_PERSON F SHIFT toggle_fly THIRD_PERSON SPACE NONE stop_moving THIRD_PERSON ENTER NONE start_chat -THIRD_PERSON DIVIDE NONE start_gesture +THIRD_PERSON / NONE start_gesture THIRD_PERSON LEFT NONE turn_left THIRD_PERSON LEFT SHIFT slide_left @@ -201,7 +201,7 @@ EDIT S NONE move_backward EDIT E NONE spin_over EDIT C NONE spin_under EDIT ENTER NONE start_chat -EDIT DIVIDE NONE start_gesture +EDIT / NONE start_gesture EDIT PAD_ENTER NONE start_chat EDIT PAD_DIVIDE NONE start_gesture @@ -330,7 +330,7 @@ SITTING PAD_ENTER CTL_ALT_SHIFT start_chat SITTING PAD_DIVIDE CTL_ALT_SHIFT start_gesture SITTING ENTER NONE start_chat -SITTING DIVIDE NONE start_gesture +SITTING / NONE start_gesture # Avatar editing camera controls EDIT_AVATAR A NONE edit_avatar_spin_cw @@ -346,7 +346,7 @@ EDIT_AVATAR DOWN NONE edit_avatar_move_backward EDIT_AVATAR PGUP NONE edit_avatar_spin_over EDIT_AVATAR PGDN NONE edit_avatar_spin_under EDIT_AVATAR ENTER NONE start_chat -EDIT_AVATAR DIVIDE NONE start_gesture +EDIT_AVATAR / NONE start_gesture EDIT_AVATAR PAD_LEFT NONE edit_avatar_spin_cw EDIT_AVATAR PAD_RIGHT NONE edit_avatar_spin_ccw EDIT_AVATAR PAD_UP NONE edit_avatar_move_forward diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index f9365d8da..0b4e7c630 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 @@ -10944,7 +11046,7 @@ Comment Maximum size of a single node's vertex data (in KB). Persist - 1 + 0 Type S32 Value diff --git a/indra/newview/app_settings/settings_ascent_coa.xml b/indra/newview/app_settings/settings_ascent_coa.xml index 660c18d14..ca4baa6d4 100644 --- a/indra/newview/app_settings/settings_ascent_coa.xml +++ b/indra/newview/app_settings/settings_ascent_coa.xml @@ -2,7 +2,22 @@ - MoyMiniMapCustomColor + + SGDisableChatAnimation + + Comment + Disable whisper, chat and shout animations on your avatar + Persist + 1 + Type + Boolean + Value + 0 + IsCOA + 1 + + + MoyMiniMapCustomColor Comment Custom minimap color you wish to have. 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/ascentprefsvan.cpp b/indra/newview/ascentprefsvan.cpp index 411e159de..4b73e2e1f 100644 --- a/indra/newview/ascentprefsvan.cpp +++ b/indra/newview/ascentprefsvan.cpp @@ -218,6 +218,7 @@ void LLPrefsAscentVan::refreshValues() mShowTPScreen = !gSavedSettings.getBOOL("AscentDisableTeleportScreens"); mPlayTPSound = gSavedSettings.getBOOL("OptionPlayTpSound"); mShowLogScreens = !gSavedSettings.getBOOL("AscentDisableLogoutScreens"); + mDisableChatAnimation = gSavedSettings.getBOOL("SGDisableChatAnimation"); //Tags\Colors ---------------------------------------------------------------------------- mAscentUseTag = gSavedSettings.getBOOL("AscentUseTag"); @@ -291,6 +292,7 @@ void LLPrefsAscentVan::cancel() gSavedSettings.setBOOL("AscentDisableTeleportScreens", !mShowTPScreen); gSavedSettings.setBOOL("OptionPlayTpSound", mPlayTPSound); gSavedSettings.setBOOL("AscentDisableLogoutScreens", !mShowLogScreens); + gSavedSettings.setBOOL("SGDisableChatAnimation", mDisableChatAnimation); //Tags\Colors ---------------------------------------------------------------------------- gSavedSettings.setBOOL("AscentUseTag", mAscentUseTag); diff --git a/indra/newview/ascentprefsvan.h b/indra/newview/ascentprefsvan.h index 5545c5b2f..115b1c206 100644 --- a/indra/newview/ascentprefsvan.h +++ b/indra/newview/ascentprefsvan.h @@ -57,6 +57,7 @@ protected: BOOL mShowTPScreen; BOOL mPlayTPSound; BOOL mShowLogScreens; + bool mDisableChatAnimation; //Tags\Colors BOOL mAscentUseTag; std::string mReportClientUUID; diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 2c7c1d4b4..103a5e594 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -43,10 +43,10 @@ #include "llanimationstates.h" #include "llcallingcard.h" #include "llconsole.h" +#include "llenvmanager.h" #include "llfirstuse.h" #include "llfloatercamera.h" #include "llfloatertools.h" - #include "llgroupmgr.h" #include "llhomelocationresponder.h" #include "llhudmanager.h" @@ -645,6 +645,8 @@ void LLAgent::toggleTPosed() //----------------------------------------------------------------------------- void LLAgent::setRegion(LLViewerRegion *regionp) { + bool teleport = true; + llassert(regionp); if (mRegionp != regionp) { @@ -682,6 +684,8 @@ void LLAgent::setRegion(LLViewerRegion *regionp) gSky.mVOGroundp->setRegion(regionp); } + // Notify windlight managers + teleport = (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE); } else { @@ -713,6 +717,15 @@ void LLAgent::setRegion(LLViewerRegion *regionp) mRegionsVisited.insert(handle); LLSelectMgr::getInstance()->updateSelectionCenter(); + + if (teleport) + { + LLEnvManagerNew::instance().onTeleport(); + } + else + { + LLEnvManagerNew::instance().onRegionCrossing(); + } } diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp index 2ddb614d3..ef1413954 100644 --- a/indra/newview/llchatbar.cpp +++ b/indra/newview/llchatbar.cpp @@ -685,8 +685,10 @@ void LLChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL } // [/RLVa:KB] + LLCachedControl disable_chat_animation("SGDisableChatAnimation"); + // Don't animate for chats people can't hear (chat to scripts) - if (animate && (channel == 0)) + if (animate && (channel == 0) && !disable_chat_animation) { if (type == CHAT_TYPE_WHISPER) { diff --git a/indra/newview/lldaycyclemanager.cpp b/indra/newview/lldaycyclemanager.cpp new file mode 100644 index 000000000..d027d6557 --- /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(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/days", "")); + + // Then load user presets. Note that user day cycles will modify any system ones already loaded. + loadPresets(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/days", "")); +} + +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(LLURI::unescape(gDirUtilp->getBaseFileName(path, 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 8daa0f69d..371f979a0 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..afbf505aa --- /dev/null +++ b/indra/newview/llenvmanager.cpp @@ -0,0 +1,698 @@ +/** + * @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 "m7wlinterface.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 (!M7WindlightInterface::getInstance()->hasOverride()) + { + // 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/llfloaterfriends.cpp b/indra/newview/llfloaterfriends.cpp index 28c79d928..078e0e507 100644 --- a/indra/newview/llfloaterfriends.cpp +++ b/indra/newview/llfloaterfriends.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llfloaterfriends.cpp * @author Phoenix * @date 2005-01-13 @@ -310,44 +310,45 @@ void LLPanelFriends::categorizeContacts() } } -void LLPanelFriends::filterContacts() +void LLPanelFriends::filterContacts(const std::string& search_name) { std::string friend_name; - std::string search_name; - - search_name = LLPanelFriends::getChild("buddy_search_lineedit")->getValue().asString(); if ((search_name != "" /*&& search_name != mLastContactSearch*/)) { - mLastContactSearch = search_name; - refreshNames(LLFriendObserver::ADD); + if (search_name.find(mLastContactSearch) == std::string::npos) + { + refreshNames(LLFriendObserver::ADD); + } + + //llinfos << "search_name = " << search_name < vFriends = mFriendsList->getAllData(); // all of it. for (std::vector::iterator itr = vFriends.begin(); itr != vFriends.end(); ++itr) { friend_name = utf8str_tolower((*itr)->getColumn(LIST_FRIEND_NAME)->getValue().asString()); BOOL show_entry = (friend_name.find(utf8str_tolower(search_name)) != std::string::npos); - + //llinfos << "friend_name = " << friend_name << (show_entry?" (shown)":"") <deleteItems((*itr)->getValue()); } } + mFriendsList->updateLayout(); refreshUI(); } else if (search_name == "" && search_name != mLastContactSearch) refreshNames(LLFriendObserver::ADD); + mLastContactSearch = search_name; } -void LLPanelFriends::onContactSearchKeystroke(LLLineEditor* caller, void* user_data) +//static +void LLPanelFriends::onContactSearchEdit(const std::string& search_string, void* user_data) { - if (caller) + LLPanelFriends* panelp = (LLPanelFriends*)user_data; + if (panelp) { - LLPanelFriends* panelp = (LLPanelFriends*)caller->getParent(); - if (panelp) - { - panelp->filterContacts(); - } + panelp->filterContacts(search_string); } } @@ -377,10 +378,10 @@ BOOL LLPanelFriends::postBuild() // // Contact search and group system. // 09/05/2010 - Charley Levenque - LLLineEditor* contact = getChild("buddy_search_lineedit"); + LLSearchEditor* contact = getChild("buddy_search_lineedit"); if (contact) { - contact->setKeystrokeCallback(&onContactSearchKeystroke); + contact->setSearchCallback(&onContactSearchEdit, this); } getChild("s_num")->setValue("0"); diff --git a/indra/newview/llfloaterfriends.h b/indra/newview/llfloaterfriends.h index acac9f590..b930d6627 100644 --- a/indra/newview/llfloaterfriends.h +++ b/indra/newview/llfloaterfriends.h @@ -105,7 +105,7 @@ private: typedef std::map rights_map_t; void refreshNames(U32 changed_mask); // Contacts search and group system - void filterContacts(); + void filterContacts(const std::string& search_name); void categorizeContacts(); void setContactGroup(std::string contact_grp); std::string cleanFileName(std::string filename); @@ -136,7 +136,7 @@ private: static bool callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response); static void onPickAvatar(const std::vector& names, const std::vector& ids, void* user_data); static void onMaximumSelect(void* user_data); - static void onContactSearchKeystroke(LLLineEditor* caller, void* user_data); + static void onContactSearchEdit(const std::string& search_string, void* user_data); static void onClickIM(void* user_data); static void onClickAssign(void* user_data); static void onClickExpand(void* user_data); 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..4c2af3564 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] @@ -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/llimpanel.cpp b/indra/newview/llimpanel.cpp index 1bed779ff..56375829a 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -2156,55 +2156,58 @@ void LLFloaterIMPanel::sendMsg() if (mInputEditor) mInputEditor->updateHistory(); // Truncate and convert to UTF8 for transport std::string utf8text = wstring_to_utf8str(text); + // Convert MU*s style poses into IRC emotes here. + if (gSavedSettings.getBOOL("AscentAllowMUpose") && utf8text.length() > 3 && utf8text[0] == ':') + { + if (utf8text[1] == '\'') + { + utf8text.replace(0, 1, "/me"); + } + else if (isalpha(utf8text[1])) // Do not prevent smileys and such. + { + utf8text.replace(0, 1, "/me "); + } + } + if (utf8text.find("/ME'") == 0 || utf8text.find("/ME ") == 0) //Allow CAPSlock /me + utf8text.replace(1, 2, "me"); + std::string prefix = utf8text.substr(0, 4); if (gSavedSettings.getBOOL("AscentAutoCloseOOC") && (utf8text.length() > 1) && !mRPMode) { // Chalice - OOC autoclosing patch based on code by Henri Beauchamp int needsClosingType=0; //Check if it needs the end-of-chat brackets -HgB - if (utf8text.find("((") == 0 && utf8text.find("))") == -1) + if (utf8text.find("((") == 0 && utf8text.find("))") == std::string::npos) { - if(utf8text.at(utf8text.length() - 1) == ')') + if(*utf8text.rbegin() == ')') utf8text+=" "; utf8text+="))"; } - else if(utf8text.find("[[") == 0 && utf8text.find("]]") == -1) + else if(utf8text.find("[[") == 0 && utf8text.find("]]") == std::string::npos) { - if(utf8text.at(utf8text.length() - 1) == ']') + if(*utf8text.rbegin() == ']') utf8text+=" "; utf8text+="]]"; } //Check if it needs the start-of-chat brackets -HgB needsClosingType=0; - if (utf8text.find("((") == -1 && utf8text.find("))") == (utf8text.length() - 2)) + if (prefix != "/me " && prefix != "/me'") //Allow /me to end with )) or ]] { - if(utf8text.at(0) == '(') - utf8text.insert(0," "); - utf8text.insert(0,"(("); - } - else if (utf8text.find("[[") == -1 && utf8text.find("]]") == (utf8text.length() - 2)) - { - if(utf8text.at(0) == '[') - utf8text.insert(0," "); - utf8text.insert(0,"[["); + if (utf8text.find("((") == std::string::npos && utf8text.find("))") == (utf8text.length() - 2)) + { + if(utf8text[0] == '(') + utf8text.insert(0," "); + utf8text.insert(0,"(("); + } + else if (utf8text.find("[[") == std::string::npos && utf8text.find("]]") == (utf8text.length() - 2)) + { + if(utf8text[0] == '[') + utf8text.insert(0," "); + utf8text.insert(0,"[["); + } } } - // Convert MU*s style poses into IRC emotes here. - if (gSavedSettings.getBOOL("AscentAllowMUpose") && utf8text.find(":") == 0 && utf8text.length() > 3) - { - if (utf8text.find(":'") == 0) - { - utf8text.replace(0, 1, "/me"); - } - else if (isalpha(utf8text.at(1))) // Do not prevent smileys and such. - { - utf8text.replace(0, 1, "/me "); - } - } - - std::string prefix = utf8text.substr(0, 4); - if (prefix != "/me " && prefix != "/me'") - if (mRPMode) utf8text = "[[" + utf8text + "]]"; - + if (mRPMode && prefix != "/me " && prefix != "/me'") + utf8text = "[[" + utf8text + "]]"; // [RLVa:KB] - Checked: 2011-09-17 (RLVa-1.1.4b) | Modified: RLVa-1.1.4b if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SENDIM)) || (gRlvHandler.hasBehaviour(RLV_BHVR_SENDIMTO)) ) { diff --git a/indra/newview/llpreviewanim.cpp b/indra/newview/llpreviewanim.cpp index a4e8dfddd..0752292ae 100644 --- a/indra/newview/llpreviewanim.cpp +++ b/indra/newview/llpreviewanim.cpp @@ -73,10 +73,14 @@ LLPreviewAnim::LLPreviewAnim(const std::string& name, const LLRect& rect, const translate(rect.mLeft - curRect.mLeft, rect.mTop - curRect.mTop); } + mIsCopyable = false; // preload the animation if(item) { gAgentAvatarp->createMotion(item->getAssetUUID()); + + const LLPermissions& perm = item->getPermissions(); + mIsCopyable = (perm.getCreator() == gAgent.getID()); } switch ( activate ) @@ -334,7 +338,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/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index a968f6e12..b6dfcc185 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -567,20 +567,23 @@ void LLPreviewGesture::addModifiers() combo->setCurrentByIndex(0); } + +static const std::string valid_key_to_string(KEY key) +{ + std::string skey(1,(char)key); + std::string strkey = LLKeyboard::stringFromKey(key); + return ((skey == strkey && key >= ' ' && key <= '~') || (skey != strkey) ) ? strkey : ""; +} + void LLPreviewGesture::addKeys() { LLComboBox* combo = mKeyCombo; - combo->add( NONE_LABEL ); - - // - //define for the lulz -#define addKey(k) combo->add( LLKeyboard::stringFromKey(k), ADD_BOTTOM ); - for (KEY key = KEY_F2; key <= KEY_F12; key++) - addKey(key) - for (KEY key = ' '; key <= '~'; key++) - addKey(key) - // + for (KEY key = ' '; key < KEY_NONE; key++) + { + std::string keystr = valid_key_to_string(key); + if(keystr != "")combo->add( keystr, ADD_BOTTOM ); + } combo->setCurrentByIndex(0); } diff --git a/indra/newview/llpreviewsound.cpp b/indra/newview/llpreviewsound.cpp index 446647f9b..c88cc1cc6 100644 --- a/indra/newview/llpreviewsound.cpp +++ b/indra/newview/llpreviewsound.cpp @@ -78,6 +78,13 @@ LLPreviewSound::LLPreviewSound(const std::string& name, const LLRect& rect, cons button->setSoundFlags(LLView::SILENT); const LLInventoryItem* item = getItem(); + + mIsCopyable = false; + if(item) + { + const LLPermissions& perm = item->getPermissions(); + mIsCopyable = (perm.getCreator() == gAgent.getID()); + } childSetCommitCallback("desc", LLPreview::onText, this); childSetText("desc", item->getDescription()); @@ -293,7 +300,7 @@ void LLPreviewSound::copyUUID( void *userdata ) // virtual BOOL LLPreviewSound::canSaveAs() const { - return TRUE; + return mIsCopyable; } // virtual diff --git a/indra/newview/llpreviewsound.h b/indra/newview/llpreviewsound.h index bd8b9c0f0..6d8928c97 100644 --- a/indra/newview/llpreviewsound.h +++ b/indra/newview/llpreviewsound.h @@ -71,7 +71,8 @@ protected: virtual void saveAs(); virtual LLUUID getItemID(); // - +private: + bool mIsCopyable; }; #endif // LL_LLPREVIEWSOUND_H diff --git a/indra/newview/llregioninfomodel.cpp b/indra/newview/llregioninfomodel.cpp new file mode 100644 index 000000000..698c4f9bb --- /dev/null +++ b/indra/newview/llregioninfomodel.cpp @@ -0,0 +1,217 @@ +/** + * @file llregioninfomodel.cpp + * @brief Region info model + * + * $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 "llregioninfomodel.h" + +// libs +#include "message.h" +#include "llregionflags.h" + +// viewer +#include "llagent.h" +#include "llviewerregion.h" + +void LLRegionInfoModel::reset() +{ + mSimAccess = 0; + mAgentLimit = 0; + + mRegionFlags = 0; + mEstateID = 0; + mParentEstateID = 0; + + mPricePerMeter = 0; + mRedirectGridX = 0; + mRedirectGridY = 0; + + mBillableFactor = 0.0f; + mObjectBonusFactor = 0.0f; + mWaterHeight = 0.0f; + mTerrainRaiseLimit = 0.0f; + mTerrainLowerLimit = 0.0f; + mSunHour = 0.0f; + + mUseEstateSun = false; + + mSimType.clear(); + mSimName.clear(); +} + +LLRegionInfoModel::LLRegionInfoModel() +{ + reset(); +} + +boost::signals2::connection LLRegionInfoModel::setUpdateCallback(const update_signal_t::slot_type& cb) +{ + return mUpdateSignal.connect(cb); +} + +void LLRegionInfoModel::sendRegionTerrain(const LLUUID& invoice) const +{ + std::string buffer; + std::vector strings; + + // ========================================== + // Assemble and send setregionterrain message + // "setregionterrain" + // strings[0] = float water height + // strings[1] = float terrain raise + // strings[2] = float terrain lower + // strings[3] = 'Y' use estate time + // strings[4] = 'Y' fixed sun + // strings[5] = float sun_hour + // strings[6] = from estate, 'Y' use global time + // strings[7] = from estate, 'Y' fixed sun + // strings[8] = from estate, float sun_hour + + // *NOTE: this resets estate sun info. + BOOL estate_global_time = true; + BOOL estate_fixed_sun = false; + F32 estate_sun_hour = 0.f; + + buffer = llformat("%f", mWaterHeight); + strings.push_back(buffer); + buffer = llformat("%f", mTerrainRaiseLimit); + strings.push_back(buffer); + buffer = llformat("%f", mTerrainLowerLimit); + strings.push_back(buffer); + buffer = llformat("%s", (mUseEstateSun ? "Y" : "N")); + strings.push_back(buffer); + buffer = llformat("%s", (getUseFixedSun() ? "Y" : "N")); + strings.push_back(buffer); + buffer = llformat("%f", mSunHour); + strings.push_back(buffer); + buffer = llformat("%s", (estate_global_time ? "Y" : "N") ); + strings.push_back(buffer); + buffer = llformat("%s", (estate_fixed_sun ? "Y" : "N") ); + strings.push_back(buffer); + buffer = llformat("%f", estate_sun_hour); + strings.push_back(buffer); + + sendEstateOwnerMessage(gMessageSystem, "setregionterrain", invoice, strings); +} + +bool LLRegionInfoModel::getUseFixedSun() const +{ + return mRegionFlags & REGION_FLAGS_SUN_FIXED; +} + +void LLRegionInfoModel::setUseFixedSun(bool fixed) +{ + if (fixed) + { + mRegionFlags |= REGION_FLAGS_SUN_FIXED; + } + else + { + mRegionFlags &= ~REGION_FLAGS_SUN_FIXED; + } +} + +void LLRegionInfoModel::update(LLMessageSystem* msg) +{ + reset(); + + msg->getStringFast(_PREHASH_RegionInfo, _PREHASH_SimName, mSimName); + msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_EstateID, mEstateID); + msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_ParentEstateID, mParentEstateID); + msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_RegionFlags, mRegionFlags); + msg->getU8Fast(_PREHASH_RegionInfo, _PREHASH_SimAccess, mSimAccess); + msg->getU8Fast(_PREHASH_RegionInfo, _PREHASH_MaxAgents, mAgentLimit); + msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_ObjectBonusFactor, mObjectBonusFactor); + msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_BillableFactor, mBillableFactor); + msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_WaterHeight, mWaterHeight); + msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_TerrainRaiseLimit, mTerrainRaiseLimit); + msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_TerrainLowerLimit, mTerrainLowerLimit); + msg->getS32Fast(_PREHASH_RegionInfo, _PREHASH_PricePerMeter, mPricePerMeter); + msg->getS32Fast(_PREHASH_RegionInfo, _PREHASH_RedirectGridX, mRedirectGridX); + msg->getS32Fast(_PREHASH_RegionInfo, _PREHASH_RedirectGridY, mRedirectGridY); + + msg->getBOOL(_PREHASH_RegionInfo, _PREHASH_UseEstateSun, mUseEstateSun); + + // actually the "last set" sun hour, not the current sun hour. JC + msg->getF32(_PREHASH_RegionInfo, _PREHASH_SunHour, mSunHour); + LL_DEBUGS("Windlight Sync") << "Got region sun hour: " << mSunHour << LL_ENDL; + + // the only reasonable way to decide if we actually have any data is to + // check to see if any of these fields have nonzero sizes + if (msg->getSize(_PREHASH_RegionInfo2, _PREHASH_ProductSKU) > 0 || + msg->getSize(_PREHASH_RegionInfo2, "ProductName") > 0) + { + msg->getString(_PREHASH_RegionInfo2, "ProductName", mSimType); + } + + // Let interested parties know that region info has been updated. + mUpdateSignal(); +} + +// static +void LLRegionInfoModel::sendEstateOwnerMessage( + LLMessageSystem* msg, + const std::string& request, + const LLUUID& invoice, + const std::vector& strings) +{ + LLViewerRegion* cur_region = gAgent.getRegion(); + + if (!cur_region) + { + llwarns << "Agent region not set" << llendl; + return; + } + + llinfos << "Sending estate request '" << request << "'" << llendl; + msg->newMessage("EstateOwnerMessage"); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used + msg->nextBlock("MethodData"); + msg->addString("Method", request); + msg->addUUID("Invoice", invoice); + + if (strings.empty()) + { + msg->nextBlock("ParamList"); + msg->addString("Parameter", NULL); + } + else + { + std::vector::const_iterator it = strings.begin(); + std::vector::const_iterator end = strings.end(); + for (unsigned i = 0; it != end; ++it, ++i) + { + lldebugs << "- [" << i << "] " << (*it) << llendl; + msg->nextBlock("ParamList"); + msg->addString("Parameter", *it); + } + } + + msg->sendReliable(cur_region->getHost()); +} diff --git a/indra/newview/llregioninfomodel.h b/indra/newview/llregioninfomodel.h new file mode 100644 index 000000000..1fc8f3e7c --- /dev/null +++ b/indra/newview/llregioninfomodel.h @@ -0,0 +1,100 @@ +/** + * @file llregioninfomodel.h + * @brief Region info model + * + * $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_LLREGIONINFOMODEL_H +#define LL_LLREGIONINFOMODEL_H + +class LLMessageSystem; + +#include "llmemory.h" +#include + +/** + * Contains region info, notifies interested parties of its changes. + */ +class LLRegionInfoModel : public LLSingleton +{ + LOG_CLASS(LLRegionInfoModel); + +public: + typedef boost::signals2::signal update_signal_t; + boost::signals2::connection setUpdateCallback(const update_signal_t::slot_type& cb); + + void sendRegionTerrain(const LLUUID& invoice) const; /// upload region terrain data + + bool getUseFixedSun() const; + + void setUseFixedSun(bool fixed); + + // *TODO: Add getters and make the data private. + U8 mSimAccess; + U8 mAgentLimit; + + U32 mRegionFlags; + U32 mEstateID; + U32 mParentEstateID; + + S32 mPricePerMeter; + S32 mRedirectGridX; + S32 mRedirectGridY; + + F32 mBillableFactor; + F32 mObjectBonusFactor; + F32 mWaterHeight; + F32 mTerrainRaiseLimit; + F32 mTerrainLowerLimit; + F32 mSunHour; // 6..30 + + BOOL mUseEstateSun; + + std::string mSimName; + std::string mSimType; + +protected: + friend class LLSingleton; + friend class LLViewerRegion; + + LLRegionInfoModel(); + + /** + * Refresh model with data from the incoming server message. + */ + void update(LLMessageSystem* msg); + +private: + void reset(); + + // *FIXME: Duplicated code from LLPanelRegionInfo + static void sendEstateOwnerMessage( + LLMessageSystem* msg, + const std::string& request, + const LLUUID& invoice, + const std::vector& strings); + + update_signal_t mUpdateSignal; +}; + +#endif // LL_LLREGIONINFOMODEL_H diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 618aeaf37..2b29ac839 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/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 96b1f0b6c..b239823af 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -1969,14 +1969,14 @@ void LLTextureCache::removeEntry(S32 idx, Entry& entry, std::string& filename, b } } - entry.mImageSize = -1; - entry.mBodySize = 0; + mTexturesSizeTotal -= entry.mBodySize; + entry.mImageSize = -1; + entry.mBodySize = 0; mHeaderIDMap.erase(entry.mID); mTexturesSizeMap.erase(entry.mID); - mTexturesSizeTotal -= entry.mBodySize; - mFreeList.insert(idx); - } + mFreeList.insert(idx); + } if (remove_file && file_maybe_exists) { diff --git a/indra/newview/llviewergenericmessage.cpp b/indra/newview/llviewergenericmessage.cpp index 796a49fa4..312fae50a 100644 --- a/indra/newview/llviewergenericmessage.cpp +++ b/indra/newview/llviewergenericmessage.cpp @@ -34,7 +34,6 @@ #include "llviewerprecompiledheaders.h" #include "llviewergenericmessage.h" -#include "meta7windlight.h" #include "lldispatcher.h" #include "lluuid.h" #include "message.h" @@ -43,9 +42,12 @@ #include "llwaterparammanager.h" #include "llwlparamset.h" #include "llwlparammanager.h" +#include "m7wlinterface.h" #include "lluuid.h" LLDispatcher gGenericDispatcher; +bool animatorIsRunning = true; +bool animatorUseLindenTime = true; void send_generic_message(const std::string& method, @@ -91,107 +93,15 @@ 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") - { + { //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. - S32 count = msg->getNumberOfBlocksFast(_PREHASH_ParamList); - for (S32 i = 0; i < count; ++i) - { - // our param is binary data) - S32 size = msg->getSizeFast(_PREHASH_ParamList, i, _PREHASH_Parameter); - if (size >= 0) - { - char buf[250]; - msg->getBinaryDataFast( - _PREHASH_ParamList, _PREHASH_Parameter, - buf, size, i, 249); - - Meta7WindlightPacket* wl = (Meta7WindlightPacket*)buf; - - LLWaterParamManager * param_mgr = LLWaterParamManager::getInstance(); - LLWaterParamSet & param_set = param_mgr->mCurParams; - LLWaterParamSet backup; - if(!param_mgr->getParamSet("LightShare-Backup", backup)) { - param_mgr->addParamSet("LightShare-Backup", param_set); - } - - param_set.set("waterFogColor", wl->waterColor.red / 256.f, wl->waterColor.green / 256.f, wl->waterColor.blue / 256.f); - param_set.set("waterFogDensity", pow(2.0f, wl->waterFogDensityExponent)); - param_set.set("underWaterFogMod", wl->underwaterFogModifier); - param_set.set("normScale", wl->reflectionWaveletScale.X,wl->reflectionWaveletScale.Y,wl->reflectionWaveletScale.Z); - param_set.set("fresnelScale", wl->fresnelScale); - param_set.set("fresnelOffset", wl->fresnelOffset); - param_set.set("scaleAbove", wl->refractScaleAbove); - param_set.set("scaleBelow", wl->refractScaleBelow); - param_set.set("blurMultiplier", wl->blurMultiplier); - param_set.set("wave1Dir", wl->littleWaveDirection.X, wl->littleWaveDirection.Y); - param_set.set("wave2Dir", wl->bigWaveDirection.X, wl->bigWaveDirection.Y); - - LLUUID normalMapTexture; - - std::string out = llformat( - "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", - (U8)(wl->normalMapTexture[0]), - (U8)(wl->normalMapTexture[1]), - (U8)(wl->normalMapTexture[2]), - (U8)(wl->normalMapTexture[3]), - (U8)(wl->normalMapTexture[4]), - (U8)(wl->normalMapTexture[5]), - (U8)(wl->normalMapTexture[6]), - (U8)(wl->normalMapTexture[7]), - (U8)(wl->normalMapTexture[8]), - (U8)(wl->normalMapTexture[9]), - (U8)(wl->normalMapTexture[10]), - (U8)(wl->normalMapTexture[11]), - (U8)(wl->normalMapTexture[12]), - (U8)(wl->normalMapTexture[13]), - (U8)(wl->normalMapTexture[14]), - (U8)(wl->normalMapTexture[15])); - - normalMapTexture.set(out); - - param_mgr->setParamSet( "LightShare-CurrentRegion", param_set); - param_mgr->setNormalMapID(normalMapTexture); - - LLWLParamManager * wl_param_mgr = LLWLParamManager::getInstance(); - LLWLParamSet & wl_param_set = wl_param_mgr->mCurParams; - LLWLParamSet wl_backup; - if(!wl_param_mgr->getParamSet("LightShare-Backup", wl_backup)) { - wl_param_mgr->addParamSet("LightShare-Backup", wl_param_set); - } - - wl_param_set.setSunAngle(F_TWO_PI * wl->sunMoonPosiiton); - wl_param_set.setEastAngle(F_TWO_PI * wl->eastAngle); - wl_param_set.set("sunlight_color", wl->sunMoonColor.red * 3.0f, wl->sunMoonColor.green * 3.0f, wl->sunMoonColor.blue * 3.0f, wl->sunMoonColor.alpha * 3.0f); - wl_param_set.set("ambient", wl->ambient.red * 3.0f, wl->ambient.green * 3.0f, wl->ambient.blue * 3.0f, wl->ambient.alpha * 3.0f); - wl_param_set.set("blue_horizon", wl->horizon.red * 2.0f, wl->horizon.green *2.0f, wl->horizon.blue * 2.0f, wl->horizon.alpha * 2.0f); - wl_param_set.set("blue_density", wl->blueDensity.red * 2.0f, wl->blueDensity.green * 2.0f, wl->blueDensity.blue * 2.0f, wl->blueDensity.alpha * 2.0f); - wl_param_set.set("haze_horizon", wl->hazeHorizon, wl->hazeHorizon, wl->hazeHorizon, 1.f); - wl_param_set.set("haze_density", wl->hazeDensity, wl->hazeDensity, wl->hazeDensity, 1.f); - wl_param_set.set("cloud_shadow", wl->cloudCoverage, wl->cloudCoverage, wl->cloudCoverage, wl->cloudCoverage); - wl_param_set.set("density_multiplier", wl->densityMultiplier / 1000.0f); - wl_param_set.set("distance_multiplier", wl->distanceMultiplier, wl->distanceMultiplier, wl->distanceMultiplier, wl->distanceMultiplier); - wl_param_set.set("max_y",(F32)wl->maxAltitude); - wl_param_set.set("cloud_color", wl->cloudColor.red, wl->cloudColor.green, wl->cloudColor.blue, wl->cloudColor.alpha); - wl_param_set.set("cloud_pos_density1", wl->cloudXYDensity.X, wl->cloudXYDensity.Y, wl->cloudXYDensity.Z); - wl_param_set.set("cloud_pos_density2", wl->cloudDetailXYDensity.X, wl->cloudDetailXYDensity.Y, wl->cloudDetailXYDensity.Z); - wl_param_set.set("cloud_scale", wl->cloudScale, 0.f, 0.f, 1.f); - wl_param_set.set("gamma", wl->sceneGamma, wl->sceneGamma, wl->sceneGamma, 0.0f); - wl_param_set.set("glow",(2 - wl->sunGlowSize) * 20 , 0.f, -wl->sunGlowFocus * 5); - wl_param_set.setCloudScrollX(wl->cloudScrollX + 10.0f); - wl_param_set.setCloudScrollY(wl->cloudScrollY + 10.0f); - wl_param_set.setEnableCloudScrollX(!wl->cloudScrollXLock); - wl_param_set.setEnableCloudScrollY(!wl->cloudScrollYLock); - wl_param_set.setStarBrightness(wl->starBrightness); - wl_param_mgr->removeParamSet("LightShare-CurrentRegion",true); - wl_param_mgr->addParamSet( "LightShare-CurrentRegion", wl_param_set); - wl_param_mgr->savePreset( "LightShare-CurrentRegion"); - LLWLParamManager::getInstance()->mAnimator.mIsRunning = false; - LLWLParamManager::getInstance()->mAnimator.mUseLindenTime = false; - wl_param_mgr->loadPreset( "LightShare-CurrentRegion",true); - } - } + M7WindlightInterface::getInstance()->receiveMessage(msg); + } + else if (method == "WindlightReset") + { + M7WindlightInterface::getInstance()->receiveReset(); } else if (agent_id != gAgent.getID()) { diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 42ea1e456..bf4d71edd 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -9268,7 +9268,6 @@ class LLWorldEnvSettings : public view_listener_t // [/RLVa:KB] std::string tod = userdata.asString(); - LLVector3 sun_direction; if (tod == "editor") { @@ -9288,53 +9287,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 13d5074e3..5fa5bbf40 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -164,6 +164,7 @@ #include "hipporestrequest.h" #include "hippofloaterxml.h" #include "llversionviewer.h" +#include "m7wlinterface.h" #include "llwlparammanager.h" #include "llwaterparammanager.h" @@ -3496,6 +3497,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) } // [/RLVa:KB] case CHAT_TYPE_DEBUG_MSG: + case CHAT_TYPE_DIRECT: // llRegionSayTo() case CHAT_TYPE_NORMAL: verb = ": "; break; @@ -3813,19 +3815,7 @@ void process_teleport_finish(LLMessageSystem* msg, void**) gCacheName->setUpstream(sim); */ - //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(); - LLWLParamManager::getInstance()->removeParamSet("LightShare-Backup", true); - } - LLWaterParamSet backup; - if(LLWaterParamManager::getInstance()->getParamSet("LightShare-Backup", backup)) { - LLWaterParamManager::getInstance()->propagateParameters(); - LLWaterParamManager::getInstance()->removeParamSet("LightShare-Backup", true); - } + M7WindlightInterface::getInstance()->receiveReset(); // now, use the circuit info to tell simulator about us! LL_INFOS("Messaging") << "process_teleport_finish() Enabling " diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index a678e14bb..4b3660daf 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -55,6 +55,7 @@ #include "llfloaterreporter.h" #include "llfloaterregioninfo.h" #include "llhttpnode.h" +#include "llregioninfomodel.h" #include "llsdutil.h" #include "llstartup.h" #include "lltrans.h" @@ -647,6 +648,9 @@ std::string LLViewerRegion::accessToShortString(U8 sim_access) void LLViewerRegion::processRegionInfo(LLMessageSystem* msg, void**) { // send it to 'observers' + // *TODO: switch the floaters to using LLRegionInfoModel + llinfos << "Processing region info" << llendl; + LLRegionInfoModel::getInstance()->update(msg); LLFloaterGodTools::processRegionInfo(msg); LLFloaterRegionInfo::processRegionInfo(msg); LLFloaterReporter::processRegionInfo(msg); @@ -1495,8 +1499,8 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("DispatchRegionInfo"); capabilityNames.append("EstateChangeInfo"); capabilityNames.append("EventQueueGet"); - /*capabilityNames.append("EnvironmentSettings"); - capabilityNames.append("ObjectMedia"); + capabilityNames.append("EnvironmentSettings"); + /*capabilityNames.append("ObjectMedia"); capabilityNames.append("ObjectMediaNavigate");*/ if (gSavedSettings.getBOOL("UseHTTPInventory")) //Caps suffixed with 2 by LL. Don't update until rest of fetch system is updated first. diff --git a/indra/newview/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp index 782f70e1f..480681636 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(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/water", "")); + // Then load user presets. Note that user day presets will modify any system ones already loaded. + loadPresetsFromDir(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/water", "")); } -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(LLURI::unescape(gDirUtilp->getBaseFileName(path, 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..2c245480a --- /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.str() << 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..4b9b1338b 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(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", "")); + + // Then load user presets. Note that user day presets will modify any system ones already loaded. + loadPresetsFromDir(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", "")); +} + +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(LLURI::unescape(gDirUtilp->getBaseFileName(path, 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/m7wlinterface.cpp b/indra/newview/m7wlinterface.cpp new file mode 100644 index 000000000..365e6165a --- /dev/null +++ b/indra/newview/m7wlinterface.cpp @@ -0,0 +1,125 @@ +/* Copyright (C) 2012 Siana Gearz + * + * 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; either + * version 2.1 of the License, or (at your option) any later version. + * + * 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 */ + +#include "llviewerprecompiledheaders.h" + +#include "meta7windlight.h" +#include "llenvmanager.h" +#include "llwaterparammanager.h" +#include "llwlparammanager.h" +#include "message_prehash.h" + +#include "m7wlinterface.h" + +M7WindlightInterface::M7WindlightInterface() +:mHasOverride(false) +{ +} + +void M7WindlightInterface::receiveMessage(LLMessageSystem* msg) +{ + S32 count = msg->getNumberOfBlocksFast(_PREHASH_ParamList); + for (S32 i = 0; i < count; ++i) + { + // our param is binary data) + S32 size = msg->getSizeFast(_PREHASH_ParamList, i, _PREHASH_Parameter); + if (size >= 0) + { + mHasOverride = true; + char buf[250]; + msg->getBinaryDataFast( + _PREHASH_ParamList, _PREHASH_Parameter, + buf, size, i, 249); + + LLWaterParamManager::getInstance()->getParamSet("Default", mWater); + + Meta7WindlightPacket* wl = (Meta7WindlightPacket*)buf; + mWater.set("waterFogColor", wl->waterColor.red / 256.f, wl->waterColor.green / 256.f, wl->waterColor.blue / 256.f); + mWater.set("waterFogDensity", pow(2.0f, wl->waterFogDensityExponent)); + mWater.set("underWaterFogMod", wl->underwaterFogModifier); + mWater.set("normScale", wl->reflectionWaveletScale.X,wl->reflectionWaveletScale.Y,wl->reflectionWaveletScale.Z); + mWater.set("fresnelScale", wl->fresnelScale); + mWater.set("fresnelOffset", wl->fresnelOffset); + mWater.set("scaleAbove", wl->refractScaleAbove); + mWater.set("scaleBelow", wl->refractScaleBelow); + mWater.set("blurMultiplier", wl->blurMultiplier); + mWater.set("wave1Dir", wl->littleWaveDirection.X, wl->littleWaveDirection.Y); + mWater.set("wave2Dir", wl->bigWaveDirection.X, wl->bigWaveDirection.Y); + + std::string out = llformat( + "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + (U8)(wl->normalMapTexture[0]), + (U8)(wl->normalMapTexture[1]), + (U8)(wl->normalMapTexture[2]), + (U8)(wl->normalMapTexture[3]), + (U8)(wl->normalMapTexture[4]), + (U8)(wl->normalMapTexture[5]), + (U8)(wl->normalMapTexture[6]), + (U8)(wl->normalMapTexture[7]), + (U8)(wl->normalMapTexture[8]), + (U8)(wl->normalMapTexture[9]), + (U8)(wl->normalMapTexture[10]), + (U8)(wl->normalMapTexture[11]), + (U8)(wl->normalMapTexture[12]), + (U8)(wl->normalMapTexture[13]), + (U8)(wl->normalMapTexture[14]), + (U8)(wl->normalMapTexture[15])); + + mNormalMapTexture.set(out); + LLWaterParamManager::getInstance()->mCurParams = mWater; + LLWaterParamManager::getInstance()->setNormalMapID(mNormalMapTexture); + LLWaterParamManager::getInstance()->propagateParameters(); + + LLWLParamManager::getInstance()->mAnimator.deactivate(); + + LLWLParamManager::getInstance()->getParamSet(LLWLParamKey("Default", LLWLParamKey::SCOPE_LOCAL), mWindlight); + + mWindlight.setSunAngle(F_TWO_PI * wl->sunMoonPosiiton); + mWindlight.setEastAngle(F_TWO_PI * wl->eastAngle); + mWindlight.set("sunlight_color", wl->sunMoonColor.red * 3.0f, wl->sunMoonColor.green * 3.0f, wl->sunMoonColor.blue * 3.0f, wl->sunMoonColor.alpha * 3.0f); + mWindlight.set("ambient", wl->ambient.red * 3.0f, wl->ambient.green * 3.0f, wl->ambient.blue * 3.0f, wl->ambient.alpha * 3.0f); + mWindlight.set("blue_horizon", wl->horizon.red * 2.0f, wl->horizon.green *2.0f, wl->horizon.blue * 2.0f, wl->horizon.alpha * 2.0f); + mWindlight.set("blue_density", wl->blueDensity.red * 2.0f, wl->blueDensity.green * 2.0f, wl->blueDensity.blue * 2.0f, wl->blueDensity.alpha * 2.0f); + mWindlight.set("haze_horizon", wl->hazeHorizon, wl->hazeHorizon, wl->hazeHorizon, 1.f); + mWindlight.set("haze_density", wl->hazeDensity, wl->hazeDensity, wl->hazeDensity, 1.f); + mWindlight.set("cloud_shadow", wl->cloudCoverage, wl->cloudCoverage, wl->cloudCoverage, wl->cloudCoverage); + mWindlight.set("density_multiplier", wl->densityMultiplier / 1000.0f); + mWindlight.set("distance_multiplier", wl->distanceMultiplier, wl->distanceMultiplier, wl->distanceMultiplier, wl->distanceMultiplier); + mWindlight.set("max_y",(F32)wl->maxAltitude); + mWindlight.set("cloud_color", wl->cloudColor.red, wl->cloudColor.green, wl->cloudColor.blue, wl->cloudColor.alpha); + mWindlight.set("cloud_pos_density1", wl->cloudXYDensity.X, wl->cloudXYDensity.Y, wl->cloudXYDensity.Z); + mWindlight.set("cloud_pos_density2", wl->cloudDetailXYDensity.X, wl->cloudDetailXYDensity.Y, wl->cloudDetailXYDensity.Z); + mWindlight.set("cloud_scale", wl->cloudScale, 0.f, 0.f, 1.f); + mWindlight.set("gamma", wl->sceneGamma, wl->sceneGamma, wl->sceneGamma, 0.0f); + mWindlight.set("glow",(2 - wl->sunGlowSize) * 20 , 0.f, -wl->sunGlowFocus * 5); + mWindlight.setCloudScrollX(wl->cloudScrollX + 10.0f); + mWindlight.setCloudScrollY(wl->cloudScrollY + 10.0f); + mWindlight.setEnableCloudScrollX(!wl->cloudScrollXLock); + mWindlight.setEnableCloudScrollY(!wl->cloudScrollYLock); + mWindlight.setStarBrightness(wl->starBrightness); + + LLWLParamManager::getInstance()->mCurParams = mWindlight; + LLWLParamManager::getInstance()->propagateParameters(); + } + } +} + +void M7WindlightInterface::receiveReset() +{ + mHasOverride = false; + LLEnvManagerNew::getInstance()->usePrefs(); +} diff --git a/indra/newview/m7wlinterface.h b/indra/newview/m7wlinterface.h new file mode 100644 index 000000000..d6c45ff83 --- /dev/null +++ b/indra/newview/m7wlinterface.h @@ -0,0 +1,41 @@ +/* Copyright (C) 2012 Siana Gearz + * + * 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; either + * version 2.1 of the License, or (at your option) any later version. + * + * 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 */ + +#ifndef M7WLINTERFACE_H +#define M7WLINTERFACE_H + +#include "llsingleton.h" +#include "message.h" +#include "llwlparamset.h" +#include "llwaterparamset.h" + +class M7WindlightInterface: public LLSingleton +{ +public: + M7WindlightInterface(); + void receiveMessage(LLMessageSystem* msg); + void receiveReset(); + bool hasOverride() {return mHasOverride;} +private: + LLWaterParamSet mWater; + LLWLParamSet mWindlight; + LLUUID mNormalMapTexture; + bool mHasOverride; +}; + + +#endif 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 77c25b02b..4148e326d 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/skins/default/xui/en-us/floater_chat_history.xml b/indra/newview/skins/default/xui/en-us/floater_chat_history.xml index 3d685ebee..d49ae6213 100644 --- a/indra/newview/skins/default/xui/en-us/floater_chat_history.xml +++ b/indra/newview/skins/default/xui/en-us/floater_chat_history.xml @@ -1,136 +1,48 @@ - - - Connecting to in-world Voice Chat... - - - Connected - - - Voice not available at your current location - - - Disconnected from in-world Voice Chat - - - icn_voice-localchat.tga - - - -- Instant message logging enabled -- - - - -- End of Log -- - - - -'[OBJECTNAME]', an object owned by '[OWNERNAME]', located in [REGIONNAME] at [REGIONPOS], has been granted permission to: [PERMISSIONS]. - - -'[OBJECTNAME]', an object owned by '[OWNERNAME]', located in [REGIONNAME] at [REGIONPOS], has been denied permission to: [PERMISSIONS]. - - - Take in-world money ([CURRENCY]) from you - - - Act on your control inputs - - - Remap your control inputs - - - Animate your avatar - - - Attach to your avatar - - - Release ownership and become public - - - Link and delink from other objects - - - Add and remove joints with other objects - - - Change its permissions - - - Track your camera - - - Control your camera - - - - - - - Gestures - + + Connecting to in-world Voice Chat... + Connected + Voice not available at your current location + Disconnected from in-world Voice Chat + icn_voice-localchat.tga + -- Instant message logging enabled -- + -- End of Log -- + '[OBJECTNAME]', an object owned by '[OWNERNAME]', located in [REGIONNAME] at [REGIONPOS], has been granted permission to: [PERMISSIONS]. + '[OBJECTNAME]', an object owned by '[OWNERNAME]', located in [REGIONNAME] at [REGIONPOS], has been denied permission to: [PERMISSIONS]. + Take in-world money ([CURRENCY]) from you + Act on your control inputs + Remap your control inputs + Animate your avatar + Attach to your avatar + Release ownership and become public + Link and delink from other objects + Add and remove joints with other objects + Change its permissions + Track your camera + Control your camera + + + + Gestures - - - -