Partial port of Phoenix Windlight parts

This commit is contained in:
Siana Gearz
2012-01-31 05:37:31 +01:00
parent b177324058
commit 071745007a
39 changed files with 4281 additions and 1673 deletions

View File

@@ -85,7 +85,9 @@ set(viewer_SOURCE_FILES
floaterao.cpp
floatervoicelicense.cpp
cofmgr.cpp
ascentdaycyclemanager.cpp
lldaycyclemanager.cpp
llenvmanager.cpp
llwlhandlers.cpp
ascentfloatercontactgroups.cpp
ascentkeyword.cpp
ascentprefschat.cpp
@@ -563,7 +565,9 @@ set(viewer_HEADER_FILES
floaterao.h
floatervoicelicense.h
cofmgr.h
ascentdaycyclemanager.h
lldaycyclemanager.h
llenvmanager.h
llwlhandlers.h
ascentfloatercontactgroups.h
ascentkeyword.h
ascentprefschat.h

View File

@@ -9,6 +9,108 @@
<string>settings_rlv.xml</string>
</array>
<key>WaterPresetName</key>
<map>
<key>Comment</key>
<string>Water preset to use. May be superseded by region settings</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<integer>Default</integer>
</map>
<key>SkyPresetName</key>
<map>
<key>Comment</key>
<string>Sky preset to use. May be superseded by region settings</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<integer>Default</integer>
</map>
<key>DayCycleName</key>
<map>
<key>Comment</key>
<string>Day Cycle to use. May be superseded by region settings</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<integer>Default</integer>
</map>
<key>UseEnvironmentFromRegion</key>
<map>
<key>Comment</key>
<string>Choose whether to use the region's environment settings, or override them with the local settings.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>UseEnvironmentFromRegionAlways</key>
<map>
<key>Comment</key>
<string>Choose whether to always use the region's environment settings when they are available
or to allow the manual selections to remain unchanging.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>UseDayCycle</key>
<map>
<key>Comment</key>
<string>Whether to use use a day cycle or a fixed sky.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>PhoenixInterpolateParcelWL</key>
<map>
<key>Comment</key>
<string>PhoenixInterpolateParcelWL</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>PhoenixInterpolateSky</key>
<map>
<key>Comment</key>
<string>PhoenixInterpolateSky</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>PhoenixInterpolateWater</key>
<map>
<key>Comment</key>
<string>PhoenixInterpolateWater</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>SGTextFadeDistance</key>
<map>
<key>Comment</key>

View File

@@ -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<std::string, LLWLDayCycle>::iterator mIt = mParamList.begin();
mIt != mParamList.end();
++mIt)
{
paramsData[mIt->first] = mIt->second.getAll();
}*/
llofstream presetsXML(pathName);
LLPointer<LLSDFormatter> 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<LLSDParser> parser = new LLSDXMLParser();
parser->parse(presetsXML, paramsData, LLSDSerialize::SIZE_UNLIMITED);
std::map<std::string, LLWLDayCycle>::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<LLSDFormatter> 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<std::string, LLWLDayCycle>::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<std::string, LLWLDayCycle>::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<std::string, LLWLDayCycle>::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<std::string, LLWLDayCycle>::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;
}

View File

@@ -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 <vector>
#include <map>
#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<std::string, LLWLDayCycle> mParamList;
private:
// our parameter manager singleton instance
static AscentDayCycleManager * sInstance;
};
#endif

View File

@@ -0,0 +1,232 @@
/**
* @file lldaycyclemanager.cpp
* @brief Implementation for the LLDayCycleManager class.
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llweb.h"
#include "llwlparamset.h"
#include "llwlparammanager.h"
#include "lldaycyclemanager.h"
#include "lldiriterator.h"
void LLDayCycleManager::getPresetNames(preset_name_list_t& names) const
{
names.clear();
for (dc_map_t::const_iterator it = mDayCycleMap.begin(); it != mDayCycleMap.end(); ++it)
{
names.push_back(it->first);
}
}
void LLDayCycleManager::getPresetNames(preset_name_list_t& user, preset_name_list_t& sys) const
{
user.clear();
sys.clear();
for (dc_map_t::const_iterator it = mDayCycleMap.begin(); it != mDayCycleMap.end(); ++it)
{
const std::string& name = it->first;
if (isSystemPreset(name))
{
sys.push_back(name);
}
else
{
user.push_back(name);
}
}
}
void LLDayCycleManager::getUserPresetNames(preset_name_list_t& user) const
{
preset_name_list_t sys; // unused
getPresetNames(user, sys);
}
bool LLDayCycleManager::getPreset(const std::string name, LLWLDayCycle& day_cycle) const
{
dc_map_t::const_iterator it = mDayCycleMap.find(name);
if (it == mDayCycleMap.end())
{
return false;
}
day_cycle = it->second;
return true;
}
bool LLDayCycleManager::getPreset(const std::string name, LLSD& day_cycle) const
{
LLWLDayCycle dc;
if (!getPreset(name, dc))
{
return false;
}
day_cycle = dc.asLLSD();
return true;
}
bool LLDayCycleManager::presetExists(const std::string name) const
{
LLWLDayCycle dummy;
return getPreset(name, dummy);
}
bool LLDayCycleManager::isSystemPreset(const std::string& name) const
{
return gDirUtilp->fileExists(getSysDir() + LLWeb::curlEscape(name) + ".xml");
}
bool LLDayCycleManager::savePreset(const std::string& name, const LLSD& data)
{
// Save given preset.
LLWLDayCycle day;
day.loadDayCycle(data, LLEnvKey::SCOPE_LOCAL);
day.save(getUserDir() + LLWeb::curlEscape(name) + ".xml");
// Add it to our map.
addPreset(name, data);
mModifySignal();
return true;
}
bool LLDayCycleManager::deletePreset(const std::string& name)
{
// Remove it from the map.
dc_map_t::iterator it = mDayCycleMap.find(name);
if (it == mDayCycleMap.end())
{
LL_WARNS("Windlight") << "No day cycle named " << name << LL_ENDL;
return false;
}
mDayCycleMap.erase(it);
// Remove from the filesystem.
std::string filename = LLWeb::curlEscape(name) + ".xml";
if (gDirUtilp->fileExists(getUserDir() + filename))
{
gDirUtilp->deleteFilesInDir(getUserDir(), filename);
}
// Signal interested parties.
mModifySignal();
return true;
}
bool LLDayCycleManager::isSkyPresetReferenced(const std::string& preset_name) const
{
// We're traversing local day cycles, they can only reference local skies.
LLWLParamKey key(preset_name, LLEnvKey::SCOPE_LOCAL);
for (dc_map_t::const_iterator it = mDayCycleMap.begin(); it != mDayCycleMap.end(); ++it)
{
if (it->second.hasReferencesTo(key))
{
return true;
}
}
return false;
}
boost::signals2::connection LLDayCycleManager::setModifyCallback(const modify_signal_t::slot_type& cb)
{
return mModifySignal.connect(cb);
}
// virtual
void LLDayCycleManager::initSingleton()
{
LL_DEBUGS("Windlight") << "Loading all day cycles" << LL_ENDL;
loadAllPresets();
}
void LLDayCycleManager::loadAllPresets()
{
mDayCycleMap.clear();
// First, load system (coming out of the box) day cycles.
loadPresets(getSysDir());
// Then load user presets. Note that user day cycles will modify any system ones already loaded.
loadPresets(getUserDir());
}
void LLDayCycleManager::loadPresets(const std::string& dir)
{
LLDirIterator dir_iter(dir, "*.xml");
while (1)
{
std::string file;
if (!dir_iter.next(file)) break; // no more files
loadPreset(dir + file);
}
}
bool LLDayCycleManager::loadPreset(const std::string& path)
{
LLSD data = LLWLDayCycle::loadDayCycleFromPath(path);
if (data.isUndefined())
{
llwarns << "Error loading day cycle from " << path << llendl;
return false;
}
std::string name(gDirUtilp->getBaseFileName(LLURI::unescape(path), /*strip_exten = */ true));
addPreset(name, data);
return true;
}
bool LLDayCycleManager::addPreset(const std::string& name, const LLSD& data)
{
if (name.empty())
{
llassert(name.empty());
return false;
}
LLWLDayCycle day;
day.loadDayCycle(data, LLEnvKey::SCOPE_LOCAL);
mDayCycleMap[name] = day;
return true;
}
// static
std::string LLDayCycleManager::getSysDir()
{
return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/days", "");
}
// static
std::string LLDayCycleManager::getUserDir()
{
return gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS , "windlight/days", "");
}

View File

@@ -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 <map>
#include <string>
#include "llwldaycycle.h"
#include "llwlparammanager.h"
/**
* WindLight day cycles manager class
*
* Provides interface for accessing, loading and saving day cycles.
*/
class LLDayCycleManager : public LLSingleton<LLDayCycleManager>
{
LOG_CLASS(LLDayCycleManager);
public:
typedef std::list<std::string> preset_name_list_t;
typedef std::map<std::string, LLWLDayCycle> dc_map_t;
typedef boost::signals2::signal<void()> modify_signal_t;
void getPresetNames(preset_name_list_t& names) const;
void getPresetNames(preset_name_list_t& user, preset_name_list_t& sys) const;
void getUserPresetNames(preset_name_list_t& user) const;
bool getPreset(const std::string name, LLWLDayCycle& day_cycle) const;
bool getPreset(const std::string name, 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<LLDayCycleManager>;
/*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

View File

@@ -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())

View File

@@ -0,0 +1,697 @@
/**
* @file llenvmanager.cpp
* @brief Implementation of classes managing WindLight and water settings.
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
*
* Copyright (c) 2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llenvmanager.h"
#include "llagent.h"
#include "lldaycyclemanager.h"
#include "llviewercontrol.h" // for gSavedSettings
#include "llviewerregion.h"
#include "llwaterparammanager.h"
#include "llwlhandlers.h"
#include "llwlparammanager.h"
//#include "kcwlinterface.h"
#include "rlvhandler.h"
std::string LLEnvPrefs::getWaterPresetName() const
{
if (mWaterPresetName.empty())
{
llwarns << "Water preset name is empty" << llendl;
}
return mWaterPresetName;
}
std::string LLEnvPrefs::getSkyPresetName() const
{
if (mSkyPresetName.empty())
{
llwarns << "Sky preset name is empty" << llendl;
}
return mSkyPresetName;
}
std::string LLEnvPrefs::getDayCycleName() const
{
if (mDayCycleName.empty())
{
llwarns << "Day cycle name is empty" << llendl;
}
return mDayCycleName;
}
void LLEnvPrefs::setUseRegionSettings(bool val)
{
mUseRegionSettings = val;
}
void LLEnvPrefs::setUseWaterPreset(const std::string& name)
{
mUseRegionSettings = false;
mWaterPresetName = name;
}
void LLEnvPrefs::setUseSkyPreset(const std::string& name)
{
mUseRegionSettings = false;
mUseDayCycle = false;
mSkyPresetName = name;
}
void LLEnvPrefs::setUseDayCycle(const std::string& name)
{
mUseRegionSettings = false;
mUseDayCycle = true;
mDayCycleName = name;
}
//=============================================================================
LLEnvManagerNew::LLEnvManagerNew()
{
mInterpNextChangeMessage = true;
// Set default environment settings.
mUserPrefs.mUseRegionSettings = true;
mUserPrefs.mUseDayCycle = true;
mUserPrefs.mWaterPresetName = "Default";
mUserPrefs.mSkyPresetName = "Default";
mUserPrefs.mDayCycleName = "Default";
}
bool LLEnvManagerNew::getUseRegionSettings() const
{
return mUserPrefs.getUseRegionSettings();
}
bool LLEnvManagerNew::getUseDayCycle() const
{
return mUserPrefs.getUseDayCycle();
}
bool LLEnvManagerNew::getUseFixedSky() const
{
return mUserPrefs.getUseFixedSky();
}
std::string LLEnvManagerNew::getWaterPresetName() const
{
return mUserPrefs.getWaterPresetName();
}
std::string LLEnvManagerNew::getSkyPresetName() const
{
return mUserPrefs.getSkyPresetName();
}
std::string LLEnvManagerNew::getDayCycleName() const
{
return mUserPrefs.getDayCycleName();
}
const LLEnvironmentSettings& LLEnvManagerNew::getRegionSettings() const
{
return !mNewRegionPrefs.isEmpty() ? mNewRegionPrefs : mCachedRegionPrefs;
}
void LLEnvManagerNew::setRegionSettings(const LLEnvironmentSettings& new_settings)
{
// Set region settings override that will be used locally
// until user either uploads the changes or goes to another region.
mNewRegionPrefs = new_settings;
}
bool LLEnvManagerNew::usePrefs()
{
LL_DEBUGS("Windlight") << "Displaying preferred environment" << LL_ENDL;
updateManagersFromPrefs(false);
return true;
}
bool LLEnvManagerNew::useDefaults()
{
bool rslt;
rslt = useDefaultWater();
rslt &= useDefaultSky();
return rslt;
}
bool LLEnvManagerNew::useRegionSettings()
{
bool rslt;
rslt = useRegionSky();
rslt &= useRegionWater();
return rslt;
}
bool LLEnvManagerNew::useWaterPreset(const std::string& name)
{
LL_DEBUGS("Windlight") << "Displaying water preset " << name << LL_ENDL;
LLWaterParamManager* water_mgr = LLWaterParamManager::getInstance();
bool rslt = water_mgr->getParamSet(name, water_mgr->mCurParams);
llassert(rslt == true);
return rslt;
}
bool LLEnvManagerNew::useWaterParams(const LLSD& params)
{
LL_DEBUGS("Windlight") << "Displaying water params" << LL_ENDL;
LLWaterParamManager::getInstance()->mCurParams.setAll(params);
return true;
}
bool LLEnvManagerNew::useSkyPreset(const std::string& name, bool interpolate /*= false*/)
{
LLWLParamManager* sky_mgr = LLWLParamManager::getInstance();
LLWLParamSet param_set;
if (!sky_mgr->getParamSet(LLWLParamKey(name, LLEnvKey::SCOPE_LOCAL), param_set))
{
llwarns << "No sky preset named " << name << llendl;
return false;
}
LL_DEBUGS("Windlight") << "Displaying sky preset " << name << LL_ENDL;
sky_mgr->applySkyParams(param_set.getAll(), interpolate);
return true;
}
bool LLEnvManagerNew::useSkyParams(const LLSD& params)
{
LL_DEBUGS("Windlight") << "Displaying sky params" << LL_ENDL;
LLWLParamManager::getInstance()->applySkyParams(params);
return true;
}
bool LLEnvManagerNew::useDayCycle(const std::string& name, LLEnvKey::EScope scope)
{
LLSD params;
if (scope == LLEnvKey::SCOPE_REGION)
{
LL_DEBUGS("Windlight") << "Displaying region day cycle " << name << LL_ENDL;
params = getRegionSettings().getWLDayCycle();
}
else
{
LL_DEBUGS("Windlight") << "Displaying local day cycle " << name << LL_ENDL;
if (!LLDayCycleManager::instance().getPreset(name, params))
{
llwarns << "No day cycle named " << name << llendl;
return false;
}
}
bool rslt = LLWLParamManager::getInstance()->applyDayCycleParams(params, scope);
llassert(rslt == true);
return rslt;
}
bool LLEnvManagerNew::useDayCycleParams(const LLSD& params, LLEnvKey::EScope scope, F32 time /* = 0.5*/)
{
LL_DEBUGS("Windlight") << "Displaying day cycle params" << LL_ENDL;
return LLWLParamManager::getInstance()->applyDayCycleParams(params, scope);
}
void LLEnvManagerNew::setUseRegionSettings(bool val, bool interpolate /*= false*/)
{
mUserPrefs.setUseRegionSettings(val);
saveUserPrefs();
updateManagersFromPrefs(interpolate);
}
void LLEnvManagerNew::setUseWaterPreset(const std::string& name, bool interpolate /*= false*/)
{
// *TODO: make sure the preset exists.
if (name.empty())
{
llwarns << "Empty water preset name passed" << llendl;
return;
}
mUserPrefs.setUseWaterPreset(name);
saveUserPrefs();
updateManagersFromPrefs(interpolate);
}
void LLEnvManagerNew::setUseSkyPreset(const std::string& name, bool interpolate /*= false*/)
{
// *TODO: make sure the preset exists.
if (name.empty())
{
llwarns << "Empty sky preset name passed" << llendl;
return;
}
mUserPrefs.setUseSkyPreset(name);
saveUserPrefs();
updateManagersFromPrefs(interpolate);
}
void LLEnvManagerNew::setUseDayCycle(const std::string& name, bool interpolate /*= false*/)
{
if (!LLDayCycleManager::instance().presetExists(name))
{
llwarns << "Invalid day cycle name passed" << llendl;
return;
}
mUserPrefs.setUseDayCycle(name);
saveUserPrefs();
updateManagersFromPrefs(interpolate);
}
void LLEnvManagerNew::loadUserPrefs()
{
// operate on members directly to avoid side effects
mUserPrefs.mWaterPresetName = gSavedSettings.getString("WaterPresetName");
mUserPrefs.mSkyPresetName = gSavedSettings.getString("SkyPresetName");
mUserPrefs.mDayCycleName = gSavedSettings.getString("DayCycleName");
mUserPrefs.mUseRegionSettings = gSavedSettings.getBOOL("UseEnvironmentFromRegion");
mUserPrefs.mUseDayCycle = gSavedSettings.getBOOL("UseDayCycle");
}
void LLEnvManagerNew::saveUserPrefs()
{
gSavedSettings.setString("WaterPresetName", getWaterPresetName());
gSavedSettings.setString("SkyPresetName", getSkyPresetName());
gSavedSettings.setString("DayCycleName", getDayCycleName());
gSavedSettings.setBOOL("UseEnvironmentFromRegion", getUseRegionSettings());
gSavedSettings.setBOOL("UseDayCycle", getUseDayCycle());
mUsePrefsChangeSignal();
}
void LLEnvManagerNew::setUserPrefs(
const std::string& water_preset,
const std::string& sky_preset,
const std::string& day_cycle_preset,
bool use_fixed_sky,
bool use_region_settings)
{
// operate on members directly to avoid side effects
mUserPrefs.mWaterPresetName = water_preset;
mUserPrefs.mSkyPresetName = sky_preset;
mUserPrefs.mDayCycleName = day_cycle_preset;
mUserPrefs.mUseRegionSettings = use_region_settings;
mUserPrefs.mUseDayCycle = !use_fixed_sky;
saveUserPrefs();
updateManagersFromPrefs(false);
}
void LLEnvManagerNew::dumpUserPrefs()
{
LL_DEBUGS("Windlight") << "WaterPresetName: " << gSavedSettings.getString("WaterPresetName") << LL_ENDL;
LL_DEBUGS("Windlight") << "SkyPresetName: " << gSavedSettings.getString("SkyPresetName") << LL_ENDL;
LL_DEBUGS("Windlight") << "DayCycleName: " << gSavedSettings.getString("DayCycleName") << LL_ENDL;
LL_DEBUGS("Windlight") << "UseEnvironmentFromRegion: " << gSavedSettings.getBOOL("UseEnvironmentFromRegion") << LL_ENDL;
LL_DEBUGS("Windlight") << "UseDayCycle: " << gSavedSettings.getBOOL("UseDayCycle") << LL_ENDL;
}
void LLEnvManagerNew::dumpPresets()
{
const LLEnvironmentSettings& region_settings = getRegionSettings();
std::string region_name = gAgent.getRegion() ? gAgent.getRegion()->getName() : "Unknown region";
// Dump water presets.
LL_DEBUGS("Windlight") << "Waters:" << LL_ENDL;
if (region_settings.getWaterParams().size() != 0)
{
LL_DEBUGS("Windlight") << " - " << region_name << LL_ENDL;
}
LLWaterParamManager::preset_name_list_t water_presets;
LLWaterParamManager::getInstance()->getPresetNames(water_presets);
for (LLWaterParamManager::preset_name_list_t::const_iterator it = water_presets.begin(); it != water_presets.end(); ++it)
{
LL_DEBUGS("Windlight") << " - " << *it << LL_ENDL;
}
// Dump sky presets.
LL_DEBUGS("Windlight") << "Skies:" << LL_ENDL;
LLWLParamManager::preset_key_list_t sky_preset_keys;
LLWLParamManager::getInstance()->getPresetKeys(sky_preset_keys);
for (LLWLParamManager::preset_key_list_t::const_iterator it = sky_preset_keys.begin(); it != sky_preset_keys.end(); ++it)
{
std::string preset_name = it->name;
std::string item_title;
if (it->scope == LLEnvKey::SCOPE_LOCAL) // local preset
{
item_title = preset_name;
}
else // region preset
{
item_title = preset_name + " (" + region_name + ")";
}
LL_DEBUGS("Windlight") << " - " << item_title << LL_ENDL;
}
// Dump day cycles.
LL_DEBUGS("Windlight") << "Days:" << LL_ENDL;
const LLSD& cur_region_dc = region_settings.getWLDayCycle();
if (cur_region_dc.size() != 0)
{
LL_DEBUGS("Windlight") << " - " << region_name << LL_ENDL;
}
LLDayCycleManager::preset_name_list_t days;
LLDayCycleManager::instance().getPresetNames(days);
for (LLDayCycleManager::preset_name_list_t::const_iterator it = days.begin(); it != days.end(); ++it)
{
LL_DEBUGS("Windlight") << " - " << *it << LL_ENDL;
}
}
void LLEnvManagerNew::requestRegionSettings()
{
LLEnvironmentRequest::initiate();
}
bool LLEnvManagerNew::sendRegionSettings(const LLEnvironmentSettings& new_settings)
{
LLSD metadata;
metadata["regionID"] = gAgent.getRegion()->getRegionID();
// add last received update ID to outbound message so simulator can handle concurrent updates
metadata["messageID"] = mLastReceivedID;
return LLEnvironmentApply::initiateRequest(new_settings.makePacket(metadata));
}
boost::signals2::connection LLEnvManagerNew::setPreferencesChangeCallback(const prefs_change_signal_t::slot_type& cb)
{
return mUsePrefsChangeSignal.connect(cb);
}
boost::signals2::connection LLEnvManagerNew::setRegionSettingsChangeCallback(const region_settings_change_signal_t::slot_type& cb)
{
return mRegionSettingsChangeSignal.connect(cb);
}
boost::signals2::connection LLEnvManagerNew::setRegionChangeCallback(const region_change_signal_t::slot_type& cb)
{
return mRegionChangeSignal.connect(cb);
}
boost::signals2::connection LLEnvManagerNew::setRegionSettingsAppliedCallback(const region_settings_applied_signal_t::slot_type& cb)
{
return mRegionSettingsAppliedSignal.connect(cb);
}
// static
bool LLEnvManagerNew::canEditRegionSettings()
{
LLViewerRegion* region = gAgent.getRegion();
BOOL owner_or_god = gAgent.isGodlike() || (region && region->getOwner() == gAgent.getID());
BOOL owner_or_god_or_manager = owner_or_god || (region && region->isEstateManager());
LL_DEBUGS("Windlight") << "Can edit region settings: " << (bool) owner_or_god_or_manager << LL_ENDL;
return owner_or_god_or_manager;
}
// static
const std::string LLEnvManagerNew::getScopeString(LLEnvKey::EScope scope)
{
switch(scope)
{
case LLEnvKey::SCOPE_LOCAL:
return LLTrans::getString("LocalSettings");
case LLEnvKey::SCOPE_REGION:
return LLTrans::getString("RegionSettings");
default:
return " (?)";
}
}
void LLEnvManagerNew::onRegionCrossing()
{
LL_DEBUGS("Windlight") << "Crossed region" << LL_ENDL;
onRegionChange(true);
}
void LLEnvManagerNew::onTeleport()
{
LL_DEBUGS("Windlight") << "Teleported" << LL_ENDL;
onRegionChange(false);
}
void LLEnvManagerNew::onRegionSettingsResponse(const LLSD& content)
{
// If the message was valid, grab the UUID from it and save it for next outbound update message.
mLastReceivedID = content[0]["messageID"].asUUID();
// Refresh cached region settings.
LL_DEBUGS("Windlight") << "Caching region environment settings: " << content << LL_ENDL;
F32 sun_hour = 0; // *TODO
LLEnvironmentSettings new_settings(content[1], content[2], content[3], sun_hour);
mCachedRegionPrefs = new_settings;
// Load region sky presets.
LLWLParamManager::getInstance()->refreshRegionPresets();
// Use the region settings if parcel settings didnt override it already -KC
if (true /*KCWindlightInterface::instance().haveParcelOverride(new_settings)*/)
{
// If using server settings, update managers.
if (getUseRegionSettings())
{
updateManagersFromPrefs(mInterpNextChangeMessage);
}
//bit of a hacky override since I've repurposed many of the settings and methods here -KC
//NOTE* It might not be a good idea to do this if under RLV_BHVR_SETENV -KC
else if (gSavedSettings.getBOOL("UseEnvironmentFromRegionAlways")
&& !(rlv_handler_t::isEnabled() && gRlvHandler.hasBehaviour(RLV_BHVR_SETENV)))
{
setUseRegionSettings(true, mInterpNextChangeMessage);
}
}
// Let interested parties know about the region settings update.
mRegionSettingsChangeSignal();
// reset
mInterpNextChangeMessage = false;
}
void LLEnvManagerNew::onRegionSettingsApplyResponse(bool ok)
{
LL_DEBUGS("Windlight") << "Applying region settings " << (ok ? "succeeded" : "failed") << LL_ENDL;
// Clear locally modified region settings because they have just been uploaded.
mNewRegionPrefs.clear();
mRegionSettingsAppliedSignal(ok);
}
//-- private methods ----------------------------------------------------------
// virtual
void LLEnvManagerNew::initSingleton()
{
LL_DEBUGS("Windlight") << "Initializing LLEnvManagerNew" << LL_ENDL;
loadUserPrefs();
}
void LLEnvManagerNew::updateSkyFromPrefs(bool interpolate /*= false*/)
{
bool success = true;
// Sync sky with user prefs.
if (getUseRegionSettings()) // apply region-wide settings
{
success = useRegionSky();
}
else // apply user-specified settings
{
if (getUseDayCycle())
{
success = useDayCycle(getDayCycleName(), LLEnvKey::SCOPE_LOCAL);
}
else
{
success = useSkyPreset(getSkyPresetName(), interpolate);
}
}
// If something went wrong, fall back to defaults.
if (!success)
{
// *TODO: fix user prefs
useDefaultSky();
}
}
void LLEnvManagerNew::updateWaterFromPrefs(bool interpolate)
{
LLWaterParamManager* water_mgr = LLWaterParamManager::getInstance();
LLSD target_water_params;
// Determine new water settings based on user prefs.
{
// Fall back to default water.
LLWaterParamSet default_water;
water_mgr->getParamSet("Default", default_water);
target_water_params = default_water.getAll();
}
if (getUseRegionSettings())
{
// *TODO: make sure whether region settings belong to the current region?
const LLSD& region_water_params = getRegionSettings().getWaterParams();
if (region_water_params.size() != 0) // region has no water settings
{
LL_DEBUGS("Windlight") << "Applying region water" << LL_ENDL;
target_water_params = region_water_params;
}
else
{
LL_DEBUGS("Windlight") << "Applying default water" << LL_ENDL;
}
}
else
{
std::string water = getWaterPresetName();
LL_DEBUGS("Windlight") << "Applying water preset [" << water << "]" << LL_ENDL;
LLWaterParamSet params;
if (!water_mgr->getParamSet(water, params))
{
llwarns << "No water preset named " << water << ", falling back to defaults" << llendl;
water_mgr->getParamSet("Default", params);
// *TODO: Fix user preferences accordingly.
}
target_water_params = params.getAll();
}
// Sync water with user prefs.
water_mgr->applyParams(target_water_params, interpolate);
}
void LLEnvManagerNew::updateManagersFromPrefs(bool interpolate)
{
// Apply water settings.
updateWaterFromPrefs(interpolate);
// Apply sky settings.
updateSkyFromPrefs(interpolate);
}
bool LLEnvManagerNew::useRegionSky()
{
const LLEnvironmentSettings& region_settings = getRegionSettings();
// If region is set to defaults,
if (region_settings.getSkyMap().size() == 0)
{
// well... apply the default sky settings.
useDefaultSky();
return true;
}
// *TODO: Support fixed sky from region.
// Otherwise apply region day cycle.
LL_DEBUGS("Windlight") << "Applying region sky" << LL_ENDL;
return useDayCycleParams(
region_settings.getWLDayCycle(),
LLEnvKey::SCOPE_REGION,
region_settings.getDayTime());
}
bool LLEnvManagerNew::useRegionWater()
{
const LLEnvironmentSettings& region_settings = getRegionSettings();
const LLSD& region_water = region_settings.getWaterParams();
// If region is set to defaults,
if (region_water.size() == 0)
{
// well... apply the default water settings.
return useDefaultWater();
}
// Otherwise apply region water.
LL_DEBUGS("Windlight") << "Applying region sky" << LL_ENDL;
return useWaterParams(region_water);
}
bool LLEnvManagerNew::useDefaultSky()
{
return useDayCycle("Default", LLEnvKey::SCOPE_LOCAL);
}
bool LLEnvManagerNew::useDefaultWater()
{
return useWaterPreset("Default");
}
void LLEnvManagerNew::onRegionChange(bool interpolate)
{
// Avoid duplicating region setting requests
// by checking whether the region is actually changing.
LLViewerRegion* regionp = gAgent.getRegion();
LLUUID region_uuid = regionp ? regionp->getRegionID() : LLUUID::null;
if (region_uuid == mCurRegionUUID)
{
return;
}
// Clear locally modified region settings.
mNewRegionPrefs.clear();
// *TODO: clear environment settings of the previous region?
// Request environment settings of the new region.
LL_DEBUGS("Windlight") << "New viewer region: " << region_uuid << LL_ENDL;
mCurRegionUUID = region_uuid;
mInterpNextChangeMessage = interpolate;
requestRegionSettings();
// Let interested parties know agent region has been changed.
mRegionChangeSignal();
}

View File

@@ -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 <boost/signals2.hpp>
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: <water preset> + <fixed_sky>|<day_cycle>
*/
class LLEnvManagerNew : public LLSingleton<LLEnvManagerNew>
{
LOG_CLASS(LLEnvManagerNew);
public:
typedef boost::signals2::signal<void()> prefs_change_signal_t;
typedef boost::signals2::signal<void()> region_settings_change_signal_t;
typedef boost::signals2::signal<void()> region_change_signal_t;
typedef boost::signals2::signal<void(bool)> 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<LLEnvManagerNew>;
/*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

View File

@@ -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<std::string> LLFloaterDayCycle::sDefaultPresets;
std::map<std::string, LLWLSkyKey> 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<std::string, LLWLParamSet>::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<LLComboBox>("DayCyclePresetsCombo");
if(comboBox != NULL) {
std::map<std::string, LLWLDayCycle>::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<char>(":"));
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<LLComboBox>("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<F32, std::string>::iterator mIt =
std::map<F32, LLWLParamKey>::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<std::string, LLWLSkyKey>::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<LLComboBox>(
"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<std::string>::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<LLComboBox>("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<LLComboBox>(
"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<LLComboBox>(
"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<LLComboBox>(
"WLKeyPresets");
mult_sldr = day_cycle->getChild<LLMultiSliderCtrl>("WLDayCycleKeys");
}
std::string name(combo_box->getSelectedValue().asString());
// check to see if it's a default and shouldn't be deleted
std::set<std::string>::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<LLComboBox>(
"DayCyclePresetsCombo");
LLFloaterDayCycle* sDayCycle = NULL;
LLComboBox* keyCombo = NULL;
if(LLFloaterDayCycle::isOpen())
{
sDayCycle = LLFloaterDayCycle::instance();
keyCombo = sDayCycle->getChild<LLComboBox>(
"WLKeyPresets");
}
// add the current parameters to the list
// see if it's there first
std::map<std::string, LLWLDayCycle>::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<LLComboBox*>(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<LLMultiSliderCtrl>(
"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<LLMultiSliderCtrl>("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<LLComboBox>("DayCyclePresetsCombo");
LLFloaterWindLight* wl = LLFloaterWindLight::instance();
LLComboBox* box = wl->getChild<LLComboBox>("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(

View File

@@ -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<std::string, LLWLSkyKey> sSliderToKey;
//Presets default
static std::set<std::string> sDefaultPresets;
static const F32 sHoursPerDay;
};

View File

@@ -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<LLSliderCtrl>("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)

View File

@@ -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<LLComboBox>("WaterPresetsCombo");
mWaterPresetCombo = getChild<LLComboBox>("WaterPresetsCombo");
if(comboBox != NULL) {
std::map<std::string, LLWaterParamSet>::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, &param_mgr->mBlurMultiplier);
// Load/save
LLComboBox* comboBox = getChild<LLComboBox>("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, &param_mgr->mWave1Dir);
@@ -165,11 +161,13 @@ void LLFloaterWater::initCallbacks(void) {
childSetCommitCallback("WaterWave2DirX", onVector2ControlXMoved, &param_mgr->mWave2Dir);
childSetCommitCallback("WaterWave2DirY", onVector2ControlYMoved, &param_mgr->mWave2Dir);
comboBox->setCommitCallback(onChangePresetName);
LLTextureCtrl* textCtrl = getChild<LLTextureCtrl>("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<LLComboBox>( "WaterPresetsCombo");
LLWaterParamManager * param_mgr = LLWaterParamManager::getInstance();
// add the current parameters to the list
// see if it's there first
std::map<std::string, LLWaterParamSet>::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<LLComboBox>("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<std::string>::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<std::string>::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<LLComboBox>("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<LLComboBox>("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<LLMultiSliderCtrl>("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<std::string>::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<std::string> presets;
LLWaterParamManager::getInstance()->getPresetNames(presets);
for (std::list<std::string>::const_iterator it = presets.begin(); it != presets.end(); ++it)
{
mWaterPresetCombo->add(*it);
}
mWaterPresetCombo->selectByValue(LLEnvManagerNew::instance().getWaterPresetName());
}

View File

@@ -41,10 +41,13 @@
#include <vector>
#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<std::string> sDefaultPresets;
static void onClickNext(void* user_data);
static void onClickPrev(void* user_data);
void populateWaterPresetsList();
LLComboBox* mWaterPresetCombo;
};

View File

@@ -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<LLComboBox>("WLPresetsCombo");
mSkyPresetCombo = getChild<LLComboBox>("WLPresetsCombo");
if(comboBox != NULL) {
std::map<std::string, LLWLParamSet>::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<LLComboBox>("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, &param_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<LLComboBox>(
"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<std::string, LLWLParamSet>::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<LLComboBox>("WLPresetsCombo");
if (comboBox->getSelectedItemLabel() != currentParams.mName)
if (mSkyPresetCombo->getSelectedItemLabel() != LLEnvManagerNew::instance().getSkyPresetName())
{
comboBox->setSimple(currentParams.mName);
mSkyPresetCombo->selectByValue(LLEnvManagerNew::instance().getSkyPresetName());
}
// [/RLVa:KB]
@@ -415,7 +411,7 @@ void LLFloaterWindLight::syncMenu()
bool lockY = !param_mgr->mCurParams.getEnableCloudScrollY();
childSetValue("WLCloudLockX", lockX);
childSetValue("WLCloudLockY", lockY);
childSetValue("DrawClassicClouds", gSavedSettings.getBOOL("SkyUseClassicClouds"));
childSetValue("DrawClassicClouds", gSavedSettings.getBOOL("SkyUseClassicClouds2"));
// disable if locked, enable if not
if(lockX)
@@ -460,19 +456,32 @@ LLFloaterWindLight* LLFloaterWindLight::instance()
}
void LLFloaterWindLight::show()
{
LLFloaterWindLight* windLight = instance();
windLight->syncMenu();
if (!sWindLight)
{
LLFloaterWindLight* windLight = instance();
windLight->syncMenu();
// comment in if you want the menu to rebuild each time
//LLUICtrlFactory::getInstance()->buildFloater(windLight, "floater_windlight_options.xml");
//windLight->initCallbacks();
windLight->open();
// comment in if you want the menu to rebuild each time
//LLUICtrlFactory::getInstance()->buildFloater(windLight, "floater_windlight_options.xml");
//windLight->initCallbacks();
}
else
{
if (sWindLight->getVisible())
{
sWindLight->close();
}
else
{
sWindLight->open();
}
}
}
bool LLFloaterWindLight::isOpen()
{
if (sWindLight != NULL) {
if (sWindLight != NULL)
{
return sWindLight->getVisible();
}
return false;
@@ -790,34 +799,50 @@ void LLFloaterWindLight::onStarAlphaMoved(LLUICtrl* ctrl, void* userData)
void LLFloaterWindLight::onNewPreset(void* userData)
{
LLNotificationsUtil::add("NewSkyPreset", LLSD(), LLSD(), newPromptCallback);
LLNotifications::instance().add("NewSkyPreset", LLSD(), LLSD(), newPromptCallback);
}
void LLFloaterWindLight::onSavePreset(void* userData)
void LLFloaterWindLight::onSavePreset(LLUICtrl* ctrl, void* userData)
{
// get the name
LLComboBox* comboBox = sWindLight->getChild<LLComboBox>(
"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<std::string>::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<std::string>::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<LLComboBox>(
"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<LLComboBox>(
"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<LLMultiSliderCtrl>("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<std::string>::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<LLComboBox*>(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<LLTabContainer>("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());
}

View File

@@ -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<std::string> sDefaultPresets;
static void onClickNext(void* user_data);
static void onClickPrev(void* user_data);
void populateSkyPresetsList();
LLComboBox* mSkyPresetCombo;
};

View File

@@ -77,6 +77,25 @@ LLPreviewAnim::LLPreviewAnim(const std::string& name, const LLRect& rect, const
if(item)
{
gAgentAvatarp->createMotion(item->getAssetUUID());
const LLPermissions& perm = item->getPermissions();
U32 mask = PERM_NONE;
if(perm.getOwner() == gAgent.getID())
{
mask = perm.getMaskBase();
}
else if(gAgent.isInGroup(perm.getGroup()))
{
mask = perm.getMaskGroup();
}
else
{
mask = perm.getMaskEveryone();
}
if((mask & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED)
{
mIsCopyable = true;
}
}
switch ( activate )
@@ -334,7 +353,7 @@ void LLPreviewAnim::copyAnimID(void *userdata)
// virtual
BOOL LLPreviewAnim::canSaveAs() const
{
return TRUE;
return mIsCopyable;
}
// virtual

View File

@@ -81,6 +81,7 @@ protected:
LLUUID mObjectID;
LLButton* mPlayBtn;
LLButton* mAuditionBtn;
bool mIsCopyable;
};
#endif // LL_LLPREVIEWSOUND_H

View File

@@ -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

View File

@@ -92,6 +92,7 @@ void process_generic_message(LLMessageSystem* msg, void**)
//This needs to be handled by a dispatcher really, but I'm not sure where is the best place to put it
if (method == "Windlight")
{
#if 0
//Meta7 WindLight packet
//We are delivering with an agentID of NULL_KEY so as to be
//friendly and not trigger a warning for unsupporting clients.
@@ -192,6 +193,7 @@ void process_generic_message(LLMessageSystem* msg, void**)
wl_param_mgr->loadPreset( "LightShare-CurrentRegion",true);
}
}
#endif
}
else if (agent_id != gAgent.getID())
{

View File

@@ -9267,7 +9267,6 @@ class LLWorldEnvSettings : public view_listener_t
// [/RLVa:KB]
std::string tod = userdata.asString();
LLVector3 sun_direction;
if (tod == "editor")
{
@@ -9287,53 +9286,25 @@ class LLWorldEnvSettings : public view_listener_t
if (tod == "sunrise")
{
// set the value, turn off animation
LLWLParamManager::getInstance()->mAnimator.setDayTime(0.25);
LLWLParamManager::getInstance()->mAnimator.mIsRunning = false;
LLWLParamManager::getInstance()->mAnimator.mUseLindenTime = false;
// then call update once
LLWLParamManager::getInstance()->mAnimator.update(
LLWLParamManager::getInstance()->mCurParams);
LLEnvManagerNew::instance().setUseSkyPreset("Sunrise", gSavedSettings.getBOOL("PhoenixInterpolateSky"));
}
else if (tod == "noon")
{
// set the value, turn off animation
LLWLParamManager::getInstance()->mAnimator.setDayTime(0.567);
LLWLParamManager::getInstance()->mAnimator.mIsRunning = false;
LLWLParamManager::getInstance()->mAnimator.mUseLindenTime = false;
// then call update once
LLWLParamManager::getInstance()->mAnimator.update(
LLWLParamManager::getInstance()->mCurParams);
LLEnvManagerNew::instance().setUseSkyPreset("Midday", gSavedSettings.getBOOL("PhoenixInterpolateSky"));
}
else if (tod == "sunset")
{
// set the value, turn off animation
LLWLParamManager::getInstance()->mAnimator.setDayTime(0.75);
LLWLParamManager::getInstance()->mAnimator.mIsRunning = false;
LLWLParamManager::getInstance()->mAnimator.mUseLindenTime = false;
// then call update once
LLWLParamManager::getInstance()->mAnimator.update(
LLWLParamManager::getInstance()->mCurParams);
LLEnvManagerNew::instance().setUseSkyPreset("Sunset", gSavedSettings.getBOOL("PhoenixInterpolateSky"));
}
else if (tod == "midnight")
{
// set the value, turn off animation
LLWLParamManager::getInstance()->mAnimator.setDayTime(0.0);
LLWLParamManager::getInstance()->mAnimator.mIsRunning = false;
LLWLParamManager::getInstance()->mAnimator.mUseLindenTime = false;
// then call update once
LLWLParamManager::getInstance()->mAnimator.update(
LLWLParamManager::getInstance()->mCurParams);
LLEnvManagerNew::instance().setUseSkyPreset("Midnight", gSavedSettings.getBOOL("PhoenixInterpolateSky"));
}
else
else // Use Region Environment Settings
{
LLWLParamManager::getInstance()->mAnimator.mIsRunning = true;
LLWLParamManager::getInstance()->mAnimator.mUseLindenTime = true;
LLEnvManagerNew::instance().setUseRegionSettings(true, gSavedSettings.getBOOL("PhoenixInterpolateSky"));
}
return true;
}
};

View File

@@ -3815,6 +3815,7 @@ void process_teleport_finish(LLMessageSystem* msg, void**)
//Reset the windlight profile to default
//LLWLParamManager::getInstance()->mAnimator.mIsRunning = false;
//LLWLParamManager::getInstance()->mAnimator.mUseLindenTime = false;
/*
LLWLParamSet wl_backup;
if(LLWLParamManager::getInstance()->getParamSet("LightShare-Backup", wl_backup)) {
LLWLParamManager::getInstance()->propagateParameters();
@@ -3824,7 +3825,7 @@ void process_teleport_finish(LLMessageSystem* msg, void**)
if(LLWaterParamManager::getInstance()->getParamSet("LightShare-Backup", backup)) {
LLWaterParamManager::getInstance()->propagateParameters();
LLWaterParamManager::getInstance()->removeParamSet("LightShare-Backup", true);
}
}*/
// now, use the circuit info to tell simulator about us!
LL_INFOS("Messaging") << "process_teleport_finish() Enabling "

View File

@@ -50,13 +50,23 @@
#include "lllineeditor.h"
#include "llsdserialize.h"
// For notecard loading
#include "llvfile.h"
#include "llnotecard.h"
#include "llmemorystream.h"
#include "llnotify.h"
#include "llagent.h"
#include "llinventorymodel.h"
#include "llviewerinventory.h"
#include "llviewerregion.h"
#include "llassetuploadresponders.h"
#include "v4math.h"
#include "llviewerdisplay.h"
#include "llviewercontrol.h"
#include "llviewerwindow.h"
#include "lldrawpoolwater.h"
#include "llagent.h"
#include "llagentcamera.h"
#include "llviewerregion.h"
#include "llwlparammanager.h"
@@ -64,6 +74,8 @@
#include "llpostprocess.h"
#include "llfloaterwater.h"
#include "llagentcamera.h"
#include "curl/curl.h"
LLWaterParamManager::LLWaterParamManager() :
@@ -87,124 +99,133 @@ LLWaterParamManager::~LLWaterParamManager()
{
}
void LLWaterParamManager::loadAllPresets(const std::string& file_name)
void LLWaterParamManager::loadAllPresets()
{
std::string path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/water", ""));
LL_INFOS2("AppInit", "Shaders") << "Loading Default water settings from " << path_name << LL_ENDL;
bool found = true;
LLDirIterator app_settings_iter(path_name, "*.xml");
while(found)
{
std::string name;
found = app_settings_iter.next(name);
if(found)
{
name=name.erase(name.length()-4);
// bugfix for SL-46920: preventing filenames that break stuff.
char * curl_str = curl_unescape(name.c_str(), name.size());
std::string unescaped_name(curl_str);
curl_free(curl_str);
curl_str = NULL;
LL_DEBUGS2("AppInit", "Shaders") << "name: " << name << LL_ENDL;
loadPreset(unescaped_name,FALSE);
}
}
// And repeat for user presets, note the user presets will modify any system presets already loaded
std::string path_name2(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/water", ""));
LL_INFOS2("AppInit", "Shaders") << "Loading User water settings from " << path_name2 << LL_ENDL;
found = true;
LLDirIterator user_settings_iter(path_name2, "*.xml");
while(found)
{
std::string name;
found = user_settings_iter.next(name);
if(found)
{
name=name.erase(name.length()-4);
// bugfix for SL-46920: preventing filenames that break stuff.
char * curl_str = curl_unescape(name.c_str(), name.size());
std::string unescaped_name(curl_str);
curl_free(curl_str);
curl_str = NULL;
LL_DEBUGS2("AppInit", "Shaders") << "name: " << name << LL_ENDL;
loadPreset(unescaped_name,FALSE);
}
}
// First, load system (coming out of the box) water presets.
loadPresetsFromDir(getSysDir());
// Then load user presets. Note that user day presets will modify any system ones already loaded.
loadPresetsFromDir(getUserDir());
}
void LLWaterParamManager::loadPreset(const std::string & name,bool propagate)
void LLWaterParamManager::loadPresetsFromDir(const std::string& dir)
{
// bugfix for SL-46920: preventing filenames that break stuff.
std::string escaped_filename = LLWeb::curlEscape(name);
LL_INFOS2("AppInit", "Shaders") << "Loading water presets from " << dir << LL_ENDL;
escaped_filename += ".xml";
std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/water", escaped_filename));
llinfos << "Loading water settings from " << pathName << llendl;
std::ifstream presetsXML;
presetsXML.open(pathName.c_str());
// That failed, try loading from the users area instead.
if(!presetsXML)
LLDirIterator dir_iter(dir, "*.xml");
while (1)
{
pathName=gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/water", escaped_filename);
llinfos << "Loading User water setting from " << pathName << llendl;
presetsXML.open(pathName.c_str());
std::string file;
if (!dir_iter.next(file))
{
break; // no more files
}
std::string path = dir + file;
if (!loadPreset(path))
{
llwarns << "Error loading water preset from " << path << llendl;
}
}
}
bool LLWaterParamManager::loadPreset(const std::string& path)
{
llifstream xml_file;
std::string name(gDirUtilp->getBaseFileName(LLWeb::curlEscape(path), /*strip_exten = */ true));
xml_file.open(path.c_str());
if (!xml_file)
{
return false;
}
if (presetsXML)
LL_DEBUGS2("AppInit", "Shaders") << "Loading water " << name << LL_ENDL;
LLSD params_data;
LLPointer<LLSDParser> 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<LLSDParser> 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<LLSDParser> parser = new LLSDXMLParser();
if(parser->parse(preset_stream, paramsData, LLSDSerialize::SIZE_UNLIMITED) == LLSDParser::PARSE_FAILURE)
{
return false;
}
std::map<std::string, LLWaterParamSet>::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<LLSDFormatter> 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<std::string, LLWaterParamSet>::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<std::string, LLWaterParamSet>::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<std::string, LLWaterParamSet>::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<std::string, LLWaterParamSet>::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<char> 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);
}
}
}

View File

@@ -33,11 +33,16 @@
#ifndef LL_WATER_PARAMMANAGER_H
#define LL_WATER_PARAMMANAGER_H
#include <vector>
#include <list>
#include <map>
#include "llwaterparamset.h"
#include "llviewercamera.h"
#include "v4color.h"
#include <boost/signals2.hpp>
#include "llassettype.h" // Ugh.
class LLVFS;
const F32 WATER_FOG_LIGHT_CLAMP = 0.3f;
@@ -222,17 +227,34 @@ class LLWaterParamManager : public LLSingleton<LLWaterParamManager>
{
LOG_CLASS(LLWaterParamManager);
public:
typedef std::list<std::string> preset_name_list_t;
typedef std::map<std::string, LLWaterParamSet> preset_map_t;
typedef boost::signals2::signal<void()> preset_list_signal_t;
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<LLWaterParamManager>;
/*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<LLGLSLShader *> mShaderList;
// list of all the parameters, listed by name
preset_map_t mParamList;
std::vector<LLGLSLShader *> 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)

View File

@@ -48,7 +48,8 @@ class LLWaterParamSet
friend class LLWaterParamManager;
public:
std::string mName;
std::string mName;
LLUUID mInventoryID;
private:

View File

@@ -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<F32, std::string>& curTrack,
void LLWLAnimator::setTrack(std::map<F32, LLWLParamKey>& curTrack,
F32 dayRate, F64 dayTime, bool run)
{
mTimeTrack = curTrack;
@@ -185,3 +235,103 @@ void LLWLAnimator::setTrack(std::map<F32, std::string>& 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;
}

View File

@@ -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 <string>
#include <map>
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<F32, std::string> mTimeTrack;
std::map<F32, std::string>::iterator mFirstIt, mSecondIt;
// params to use
//std::map<std::string, LLWLParamSet> mParamList;
bool mIsRunning;
bool mUseLindenTime;
std::map<F32, LLWLParamKey> mTimeTrack;
std::map<F32, LLWLParamKey>::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<F32, std::string>& track,
void setTrack(std::map<F32, LLWLParamKey>& track,
F32 dayRate, F64 dayTime = 0, bool run = true);
void deactivate()
{
mIsRunning = false;
}
void activate(ETime time)
{
mIsRunning = true;
mTimeType = time;
}
void startInterpolation(const LLSD& targetWater);
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

View File

@@ -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 <map>
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<LLSDParser> 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<F32, std::string>::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<LLSDFormatter> 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<F32, LLWLParamKey>::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<LLWLParamKey, LLWLParamSet>& refs) const
{
bool result = true;
LLWLParamManager* wl_mgr = LLWLParamManager::getInstance();
refs.clear();
for (std::map<F32, LLWLParamKey>::const_iterator iter = mTimeMap.begin(); iter != mTimeMap.end(); ++iter)
{
const LLWLParamKey& key = iter->second;
if (!wl_mgr->getParamSet(key, refs[key]))
{
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<LLWLParamKey, LLWLParamSet> 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<F32, std::string>(newTime, paramName));
mTimeMap.insert(std::pair<F32, LLWLParamKey>(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<F32, std::string>::iterator mIt = mTimeMap.find(time);
std::map<F32, LLWLParamKey>::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<F32, std::string>::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<F32, LLWLParamKey>::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<F32, std::string>::iterator mIt = mTimeMap.find(time);
if(mIt != mTimeMap.end())
std::map<F32, LLWLParamKey>::iterator mIt = mTimeMap.find(time);
if(mIt != mTimeMap.end())
{
return LLWLParamManager::getInstance()->getParamSet(mIt->second, param);
}
// return error if not found
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<F32, std::string>::iterator mIt = mTimeMap.find(time);
std::map<F32, LLWLParamKey>::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
}

View File

@@ -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 <vector>
#include <map>
#include <string>
#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<F32, std::string> mTimeMap;
std::map<F32, LLWLParamKey> 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<LLWLParamKey, LLWLParamSet>& 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);
};

View File

@@ -0,0 +1,203 @@
/**
* @file llwlhandlers.cpp
* @brief Various classes which handle Windlight-related messaging
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
*
* Copyright (c) 2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llwlhandlers.h"
#include "llagent.h"
#include "llviewerregion.h"
#include "llenvmanager.h"
#include "llnotifications.h"
/****
* LLEnvironmentRequest
****/
// static
bool LLEnvironmentRequest::initiate()
{
LLViewerRegion* cur_region = gAgent.getRegion();
if (!cur_region)
{
LL_WARNS("WindlightCaps") << "Viewer region not set yet, skipping env. settings request" << LL_ENDL;
return false;
}
if (!cur_region->capabilitiesReceived())
{
LL_INFOS("WindlightCaps") << "Deferring windlight settings request until we've got region caps" << LL_ENDL;
cur_region->setCapabilitiesReceivedCallback(boost::bind(&LLEnvironmentRequest::onRegionCapsReceived, _1));
return false;
}
return doRequest();
}
// static
void LLEnvironmentRequest::onRegionCapsReceived(const LLUUID& region_id)
{
if (region_id != gAgent.getRegion()->getRegionID())
{
LL_INFOS("WindlightCaps") << "Got caps for a non-current region" << LL_ENDL;
return;
}
LL_DEBUGS("WindlightCaps") << "Received region capabilities" << LL_ENDL;
doRequest();
}
// static
bool LLEnvironmentRequest::doRequest()
{
std::string url = gAgent.getRegion()->getCapability("EnvironmentSettings");
if (url.empty())
{
LL_INFOS("WindlightCaps") << "Skipping windlight setting request - we don't have this capability" << LL_ENDL;
// region is apparently not capable of this; don't respond at all
return false;
}
LL_INFOS("WindlightCaps") << "Requesting region windlight settings via " << url << LL_ENDL;
LLHTTPClient::get(url, new LLEnvironmentRequestResponder());
return true;
}
/****
* LLEnvironmentRequestResponder
****/
int LLEnvironmentRequestResponder::sCount = 0; // init to 0
LLEnvironmentRequestResponder::LLEnvironmentRequestResponder()
{
mID = ++sCount;
}
/*virtual*/ void LLEnvironmentRequestResponder::result(const LLSD& unvalidated_content)
{
LL_INFOS("WindlightCaps") << "Received region windlight settings" << LL_ENDL;
if (mID != sCount)
{
LL_INFOS("WindlightCaps") << "Got superseded by another responder; ignoring..." << LL_ENDL;
return;
}
if (unvalidated_content[0]["regionID"].asUUID() != gAgent.getRegion()->getRegionID())
{
LL_WARNS("WindlightCaps") << "Not in the region from where this data was received (wanting "
<< gAgent.getRegion()->getRegionID() << " but got " << unvalidated_content[0]["regionID"].asUUID()
<< ") - ignoring..." << LL_ENDL;
return;
}
LLEnvManagerNew::getInstance()->onRegionSettingsResponse(unvalidated_content);
}
/*virtual*/ void LLEnvironmentRequestResponder::error(U32 status, const std::string& reason)
{
LL_INFOS("WindlightCaps") << "Got an error, not using region windlight..." << LL_ENDL;
LLEnvManagerNew::getInstance()->onRegionSettingsResponse(LLSD());
}
/****
* LLEnvironmentApply
****/
clock_t LLEnvironmentApply::UPDATE_WAIT_SECONDS = clock_t(3.f);
clock_t LLEnvironmentApply::sLastUpdate = clock_t(0.f);
// static
bool LLEnvironmentApply::initiateRequest(const LLSD& content)
{
clock_t current = clock();
// Make sure we don't update too frequently.
if (current < sLastUpdate + (UPDATE_WAIT_SECONDS * CLOCKS_PER_SEC))
{
LLSD args(LLSD::emptyMap());
args["WAIT"] = (F64)UPDATE_WAIT_SECONDS;
LLNotifications::instance().add("EnvUpdateRate", args);
return false;
}
sLastUpdate = current;
// Send update request.
std::string url = gAgent.getRegion()->getCapability("EnvironmentSettings");
if (url.empty())
{
LL_WARNS("WindlightCaps") << "Applying windlight settings not supported" << LL_ENDL;
return false;
}
LL_INFOS("WindlightCaps") << "Sending windlight settings to " << url << LL_ENDL;
LL_DEBUGS("WindlightCaps") << "content: " << content << LL_ENDL;
LLHTTPClient::post(url, content, new LLEnvironmentApplyResponder());
return true;
}
/****
* LLEnvironmentApplyResponder
****/
/*virtual*/ void LLEnvironmentApplyResponder::result(const LLSD& content)
{
if (content["regionID"].asUUID() != gAgent.getRegion()->getRegionID())
{
LL_WARNS("WindlightCaps") << "No longer in the region where data was sent (currently "
<< gAgent.getRegion()->getRegionID() << ", reply is from " << content["regionID"].asUUID()
<< "); ignoring..." << LL_ENDL;
return;
}
else if (content["success"].asBoolean())
{
LL_DEBUGS("WindlightCaps") << "Success in applying windlight settings to region " << content["regionID"].asUUID() << LL_ENDL;
LLEnvManagerNew::instance().onRegionSettingsApplyResponse(true);
}
else
{
LL_WARNS("WindlightCaps") << "Region couldn't apply windlight settings! Reason from sim: " << content["fail_reason"].asString() << LL_ENDL;
LLSD args(LLSD::emptyMap());
args["FAIL_REASON"] = content["fail_reason"].asString();
LLNotifications::instance().add("WLRegionApplyFail", args);
LLEnvManagerNew::instance().onRegionSettingsApplyResponse(false);
}
}
/*virtual*/ void LLEnvironmentApplyResponder::error(U32 status, const std::string& reason)
{
std::stringstream msg;
msg << reason << " (Code " << status << ")";
LL_WARNS("WindlightCaps") << "Couldn't apply windlight settings to region! Reason: " << msg << LL_ENDL;
LLSD args(LLSD::emptyMap());
args["FAIL_REASON"] = msg.str();
LLNotifications::instance().add("WLRegionApplyFail", args);
}

View File

@@ -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

View File

@@ -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

View File

@@ -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<std::string, LLWLParamSet>::iterator mIt = mParamList.begin();
mIt != mParamList.end();
++mIt)
{
paramsData[mIt->first] = mIt->second.getAll();
}
llofstream presetsXML(pathName);
LLPointer<LLSDFormatter> 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<LLSDParser> parser = new LLSDXMLParser();
parser->parse(presetsXML, paramsData, LLSDSerialize::SIZE_UNLIMITED);
std::map<std::string, LLWLParamSet>::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<LLWLParamKey> to_remove;
for(std::map<LLWLParamKey, LLWLParamSet>::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<LLWLParamKey>::iterator iter = to_remove.begin(); iter != to_remove.end(); ++iter)
{
mParamList.erase(*iter);
}
}
// returns all skies referenced by the day cycle, with their final names
// side effect: applies changes to all internal structures!
std::map<LLWLParamKey, LLWLParamSet> LLWLParamManager::finalizeFromDayCycle(LLWLParamKey::EScope scope)
{
// bugfix for SL-46920: preventing filenames that break stuff.
std::string escaped_filename = LLWeb::curlEscape(name);
lldebugs << "mDay before finalizing:" << llendl;
{
for (std::map<F32, LLWLParamKey>::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<LLWLParamKey, LLWLParamSet> final_references;
// Move all referenced to desired scope, renaming if necessary
// First, save skies referenced
std::map<LLWLParamKey, LLWLParamSet> current_references; // all skies referenced by the day cycle, with their current names
// guard against skies with same name and different scopes
std::set<std::string> inserted_names;
std::map<std::string, unsigned int> conflicted_names; // integer later used as a count, for uniquely renaming conflicts
LLWLDayCycle& cycle = mDay;
for(std::map<F32, LLWLParamKey>::iterator iter = cycle.mTimeMap.begin();
iter != cycle.mTimeMap.end();
++iter)
{
LLWLParamKey& key = iter->second;
std::string desired_name = key.name;
replace_newlines_with_whitespace(desired_name); // already shouldn't have newlines, but just in case
if(inserted_names.find(desired_name) == inserted_names.end())
{
inserted_names.insert(desired_name);
}
else
{
// make exist in map
conflicted_names[desired_name] = 0;
}
current_references[key] = mParamList[key];
}
// forget all old skies in target scope, and rebuild, renaming as needed
clearParamSetsOfScope(scope);
for(std::map<LLWLParamKey, LLWLParamSet>::iterator iter = current_references.begin(); iter != current_references.end(); ++iter)
{
const LLWLParamKey& old_key = iter->first;
std::string desired_name(old_key.name);
replace_newlines_with_whitespace(desired_name);
LLWLParamKey new_key(desired_name, scope); // name will be replaced later if necessary
// if this sky is one with a non-unique name, rename via appending a number
// an existing preset of the target scope gets to keep its name
if (scope != old_key.scope && conflicted_names.find(desired_name) != conflicted_names.end())
{
std::string& new_name = new_key.name;
do
{
// if this executes more than once, this is an absurdly pathological case
// (e.g. "x" repeated twice, but "x 1" already exists, so need to use "x 2")
std::stringstream temp;
temp << desired_name << " " << (++conflicted_names[desired_name]);
new_name = temp.str();
} while (inserted_names.find(new_name) != inserted_names.end());
// yay, found one that works
inserted_names.insert(new_name); // track names we consume here; shouldn't be necessary due to ++int? but just in case
// *TODO factor out below into a rename()?
LL_INFOS("Windlight") << "Renamed " << old_key.name << " (scope" << old_key.scope << ") to "
<< new_key.name << " (scope " << new_key.scope << ")" << LL_ENDL;
// update name in sky
iter->second.mName = new_name;
// update keys in day cycle
for(std::map<F32, LLWLParamKey>::iterator frame = cycle.mTimeMap.begin(); frame != cycle.mTimeMap.end(); ++frame)
{
if (frame->second == old_key)
{
frame->second = new_key;
}
}
// add to master sky map
mParamList[new_key] = iter->second;
}
final_references[new_key] = iter->second;
}
lldebugs << "mDay after finalizing:" << llendl;
{
for (std::map<F32, LLWLParamKey>::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<LLWLParamKey, LLWLParamSet> refs)
{
LLSD skies = LLSD::emptyMap();
for(std::map<LLWLParamKey, LLWLParamSet>::iterator iter = refs.begin(); iter != refs.end(); ++iter)
{
skies.insert(iter->first.name, iter->second.getAll());
}
return skies;
}
void LLWLParamManager::addAllSkies(const LLWLParamKey::EScope scope, const LLSD& sky_presets)
{
for(LLSD::map_const_iterator iter = sky_presets.beginMap(); iter != sky_presets.endMap(); ++iter)
{
LLWLParamSet set;
set.setAll(iter->second);
mParamList[LLWLParamKey(iter->first, scope)] = set;
}
}
void LLWLParamManager::refreshRegionPresets()
{
// Remove all region sky presets because they may belong to a previously visited region.
clearParamSetsOfScope(LLEnvKey::SCOPE_REGION);
// Add all sky presets belonging to the current region.
addAllSkies(LLEnvKey::SCOPE_REGION, LLEnvManagerNew::instance().getRegionSettings().getSkyMap());
}
void LLWLParamManager::loadAllPresets()
{
// First, load system (coming out of the box) sky presets.
loadPresetsFromDir(getSysDir());
// Then load user presets. Note that user day presets will modify any system ones already loaded.
loadPresetsFromDir(getUserDir());
}
void LLWLParamManager::loadPresetsFromDir(const std::string& dir)
{
LL_INFOS2("AppInit", "Shaders") << "Loading sky presets from " << dir << LL_ENDL;
LLDirIterator dir_iter(dir, "*.xml");
while (1)
{
std::string file;
if (!dir_iter.next(file))
{
break; // no more files
}
std::string path = dir + file;
if (!loadPreset(path))
{
llwarns << "Error loading sky preset from " << path << llendl;
}
}
}
bool LLWLParamManager::loadPreset(const std::string& path)
{
llifstream xml_file;
std::string name(gDirUtilp->getBaseFileName(LLURI::unescape(path), /*strip_exten = */ true));
xml_file.open(path.c_str());
if (!xml_file)
{
return false;
}
LL_DEBUGS2("AppInit", "Shaders") << "Loading sky " << name << LL_ENDL;
LLSD params_data;
LLPointer<LLSDParser> parser = new LLSDXMLParser();
parser->parse(xml_file, params_data, LLSDSerialize::SIZE_UNLIMITED);
xml_file.close();
LLWLParamKey key(name, LLEnvKey::SCOPE_LOCAL);
if (hasParamSet(key))
{
setParamSet(key, params_data);
}
else
{
addParamSet(key, params_data);
}
return true;
}
void LLWLParamManager::savePreset(LLWLParamKey key)
{
llassert(key.scope == LLEnvKey::SCOPE_LOCAL && !key.name.empty());
// make an empty llsd
LLSD paramsData(LLSD::emptyMap());
std::string pathName(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<std::string, LLWLParamSet>::iterator mIt = mParamList.find(name);
std::map<LLWLParamKey, LLWLParamSet>::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<std::string, LLWLParamSet>::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<std::string, LLWLParamSet>::iterator mIt = mParamList.find(name);
std::map<LLWLParamKey, LLWLParamSet>::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<std::string, LLWLParamSet>::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<LLWLParamKey, LLWLParamSet>::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<LLWLParamKey, LLWLParamSet>::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<LLWLParamKey, LLWLParamSet>::const_iterator it = mParamList.begin(); it != mParamList.end(); it++)
{
const LLWLParamKey& key = it->first;
const std::string& name = key.name;
if (key.scope != LLEnvKey::SCOPE_REGION)
{
local.push_back(name);
}
}
}
void LLWLParamManager::getPresetKeys(preset_key_list_t& keys) const
{
keys.clear();
for (std::map<LLWLParamKey, LLWLParamSet>::const_iterator it = mParamList.begin(); it != mParamList.end(); it++)
{
keys.push_back(it->first);
}
}
boost::signals2::connection LLWLParamManager::setPresetListChangeCallback(const preset_list_signal_t::slot_type& cb)
{
return mPresetListChangeSignal.connect(cb);
}
// 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<LLSDParser> 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<LLSDFormatter> 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<char> 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);
}
}
}

View File

@@ -33,14 +33,28 @@
#ifndef LL_WLPARAMMANAGER_H
#define LL_WLPARAMMANAGER_H
#include <vector>
#include <list>
#include <map>
#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<LLWLParamManager>
LOG_CLASS(LLWLParamManager);
public:
typedef std::list<std::string> preset_name_list_t;
typedef std::list<LLWLParamKey> preset_key_list_t;
typedef boost::signals2::signal<void()> preset_list_signal_t;
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<LLWLParamKey, LLWLParamSet> finalizeFromDayCycle(LLWLParamKey::EScope scope);
// returns all skies in map (intended to be called with output from a finalize)
static LLSD createSkyMap(std::map<LLWLParamKey, LLWLParamSet> map);
/// @return all named windlight presets.
const std::map<LLWLParamKey, LLWLParamSet>& 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<std::string, LLWLParamSet>& 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<LLGLSLShader *> mShaderList;
friend class LLSingleton<LLWLParamManager>;
/*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<std::string, LLWLParamSet> mParamList;
std::vector<LLGLSLShader *> mShaderList;
std::map<LLWLParamKey, LLWLParamSet> mParamList;
preset_list_signal_t mPresetListChangeSignal;
};
inline F32 LLWLParamManager::getDomeOffset(void) const

View File

@@ -48,7 +48,8 @@ class LLWLParamSet {
friend class LLWLParamManager;
public:
std::string mName;
std::string mName;
LLUUID mInventoryID;
private:

View File

@@ -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

View File

@@ -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;

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2009
/* Copyright (c) 2010
*
* Modular Systems All rights reserved.
*
@@ -16,7 +16,7 @@
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY MODULAR SYSTEMS AND CONTRIBUTORS <EFBFBD>AS IS<EFBFBD>
* THIS SOFTWARE IS PROVIDED BY MODULAR SYSTEMS AND CONTRIBUTORS “AS IS”
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MODULAR SYSTEMS OR CONTRIBUTORS
@@ -40,15 +40,26 @@
#include "lloverlaybar.h"
#include "lltextbox.h"
#include "llcombobox.h"
#include "llwlparammanager.h"
#include "llwaterparammanager.h"
#include "llsliderctrl.h"
#include "llcheckboxctrl.h"
#include "llstartup.h"
#include "llfloaterwindlight.h"
#include "llfloaterwater.h"
#include "lldaycyclemanager.h"
#include "llenvmanager.h"
#include "llwaterparammanager.h"
#include "llwlparamset.h"
#include "llwlparammanager.h"
// [RLVa:KB]
#include "rlvhandler.h"
// [/RLVa:KB]
BOOL firstBuildDone;
void* fixPointer;
std::string ButtonState;
std::string current_preset = "Default";
wlfPanel_AdvSettings::wlfPanel_AdvSettings()
{
@@ -73,11 +84,49 @@ void wlfPanel_AdvSettings::build()
void wlfPanel_AdvSettings::refresh()
{
if (gSavedSettings.getBOOL("wlfAdvSettingsPopup"))
// [RLVa:KB] - Checked: 2009-09-19
if ( (rlv_handler_t::isEnabled()) && (gSavedSettings.getBOOL("wlfAdvSettingsPopup")) )
{
childSetEnabled("WLSkyPresetsCombo", true);
childSetEnabled("WLWaterPresetsCombo", true);
childSetEnabled("use_estate_wl", !gRlvHandler.hasBehaviour(RLV_BHVR_SETENV));
childSetEnabled("EnvAdvancedWaterButton", !gRlvHandler.hasBehaviour(RLV_BHVR_SETENV));
childSetEnabled("WWPresetsCombo", !gRlvHandler.hasBehaviour(RLV_BHVR_SETENV));
childSetEnabled("WWprev", !gRlvHandler.hasBehaviour(RLV_BHVR_SETENV));
childSetEnabled("WWnext", !gRlvHandler.hasBehaviour(RLV_BHVR_SETENV));
childSetEnabled("EnvAdvancedSkyButton", !gRlvHandler.hasBehaviour(RLV_BHVR_SETENV));
childSetEnabled("WLPresetsCombo", !gRlvHandler.hasBehaviour(RLV_BHVR_SETENV));
childSetEnabled("WLprev", !gRlvHandler.hasBehaviour(RLV_BHVR_SETENV));
childSetEnabled("WLnext", !gRlvHandler.hasBehaviour(RLV_BHVR_SETENV));
childSetEnabled("EnvTimeSlider", !gRlvHandler.hasBehaviour(RLV_BHVR_SETENV));
}
// [/RLVa:KB]
}
void wlfPanel_AdvSettings::refreshLists()
{
LLEnvManagerNew& env_mgr = LLEnvManagerNew::instance();
// Populate the combo boxes with appropriate lists of available presets.
//actually, dont do this, its laggy and not needed to just refresh the selections
// populateWaterPresetsList();
// populateSkyPresetsList();
// populateDayCyclePresetsList();
//populate the combos with "Default" if using region settings
if (gSavedSettings.getBOOL("UseEnvironmentFromRegion"))
{
mWaterPresetCombo->selectByValue("Default");
mSkyPresetCombo->selectByValue("Default");
//mDayCyclePresetCombo->selectByValue("Default");
}
else
{
// Select the current presets in combo boxes.
mWaterPresetCombo->selectByValue(env_mgr.getWaterPresetName());
mSkyPresetCombo->selectByValue(env_mgr.getSkyPresetName());
//mDayCyclePresetCombo->selectByValue(env_mgr.getDayCycleName());
}
updateTimeSlider();
}
void wlfPanel_AdvSettings::fixPanel()
@@ -89,46 +138,52 @@ void wlfPanel_AdvSettings::fixPanel()
onClickExpandBtn(fixPointer);
}
}
BOOL wlfPanel_AdvSettings::postBuild()
{
childSetAction("expand", onClickExpandBtn, this);
LLComboBox* comboBoxSky = getChild<LLComboBox>("WLSkyPresetsCombo");
if(comboBoxSky != NULL)
{
std::map<std::string, LLWLParamSet>::const_iterator mIt = LLWLParamManager::getInstance()->getPresets().begin();
for(; mIt != LLWLParamManager::getInstance()->getPresets().end(); mIt++)
{
if (mIt->first.length() > 0)
comboBoxSky->add(mIt->first);
}
comboBoxSky->add(LLStringUtil::null);
comboBoxSky->selectByValue(LLSD(current_preset));
}
comboBoxSky->setCommitCallback(onChangePresetName);
LLComboBox* comboBoxWater = getChild<LLComboBox>("WLWaterPresetsCombo");
if(comboBoxWater != NULL)
{
std::map<std::string, LLWaterParamSet>::const_iterator mIt = LLWaterParamManager::getInstance()->getPresets().begin();
for(; mIt != LLWaterParamManager::getInstance()->getPresets().end(); mIt++)
{
if (mIt->first.length() > 0)
comboBoxWater->add(mIt->first);
}
comboBoxWater->add(LLStringUtil::null);
comboBoxWater->selectByValue(LLSD(current_preset));
}
comboBoxWater->setCommitCallback(onChangePresetName);
getChild<LLCheckBoxCtrl>("use_estate_wl")->setCommitCallback(onUseRegionSettings);
mWaterPresetCombo = getChild<LLComboBox>("WWPresetsCombo");
mWaterPresetCombo->setCommitCallback(onChangeWWPresetName);
mSkyPresetCombo = getChild<LLComboBox>("WLPresetsCombo");
mSkyPresetCombo->setCommitCallback(onChangeWLPresetName);
// mDayCyclePresetCombo = getChild<LLComboBox>("DCPresetsCombo");
// mDayCyclePresetCombo->setCommitCallback(onChangeDCPresetName);
LLEnvManagerNew::instance().setPreferencesChangeCallback(boost::bind(&wlfPanel_AdvSettings::refreshLists, this));
LLWaterParamManager::getInstance()->setPresetListChangeCallback(boost::bind(&wlfPanel_AdvSettings::populateWaterPresetsList, this));
LLWLParamManager::getInstance()->setPresetListChangeCallback(boost::bind(&wlfPanel_AdvSettings::populateSkyPresetsList, this));
// LLDayCycleManager::instance().setModifyCallback(boost::bind(&wlfPanel_AdvSettings::populateDayCyclePresetsList, this));
populateWaterPresetsList();
populateSkyPresetsList();
//populateDayCyclePresetsList();
// next/prev buttons
childSetAction("WWnext", onClickWWNext, this);
childSetAction("WWprev", onClickWWPrev, this);
childSetAction("WLnext", onClickWLNext, this);
childSetAction("WLprev", onClickWLPrev, this);
childSetAction("EnvAdvancedSkyButton", onOpenAdvancedSky, NULL);
childSetAction("EnvAdvancedWaterButton", onOpenAdvancedWater, NULL);
mTimeSlider = getChild<LLSliderCtrl>("EnvTimeSlider");
mTimeSlider->setCommitCallback(onChangeDayTime);
updateTimeSlider();
fixPointer = this;
/*onClickExpandBtn(fixPointer);
onClickExpandBtn(fixPointer);*/
return TRUE;
}
void wlfPanel_AdvSettings::draw()
{
LLButton* expand_button = getChild<LLButton>("expand");
/*if (expand_button)
/* if (expand_button)
{
if (expand_button->getToggleState())
{
@@ -138,14 +193,16 @@ void wlfPanel_AdvSettings::draw()
{
expand_button->setImageOverlay("arrow_up.tga");
}
}*/
expand_button->setImageOverlay(ButtonState);
} */
expand_button->setImageOverlay(ButtonState);
refresh();
LLPanel::draw();
}
wlfPanel_AdvSettings::~wlfPanel_AdvSettings ()
{
}
void wlfPanel_AdvSettings::onClickExpandBtn(void* user_data)
{
gSavedSettings.setBOOL("wlfAdvSettingsPopup",!gSavedSettings.getBOOL("wlfAdvSettingsPopup"));
@@ -153,29 +210,229 @@ void wlfPanel_AdvSettings::onClickExpandBtn(void* user_data)
remotep->build();
gOverlayBar->layoutButtons();
}
void wlfPanel_AdvSettings::onChangePresetName(LLUICtrl* ctrl, void * userData)
{
LLWLParamManager::getInstance()->mAnimator.mIsRunning = false;
LLWLParamManager::getInstance()->mAnimator.mUseLindenTime = false;
void wlfPanel_AdvSettings::onUseRegionSettings(LLUICtrl* ctrl, void* userdata)
{
LLEnvManagerNew::instance().setUseRegionSettings(gSavedSettings.getBOOL("UseEnvironmentFromRegion"), gSavedSettings.getBOOL("PhoenixInterpolateSky"));
}
void wlfPanel_AdvSettings::onChangeWWPresetName(LLUICtrl* ctrl, void * userData)
{
LLComboBox * combo_box = static_cast<LLComboBox*>(ctrl);
llinfos << "Combobox is " << combo_box->getControlName() << " aka " << combo_box->getName() << llendl;
if (combo_box->getName() == "WLSkyPresetsCombo")
if(combo_box->getSimple() == "")
{
if(combo_box->getSimple() == "")
{
return;
}
current_preset = combo_box->getSelectedValue().asString();
LLWLParamManager::getInstance()->loadPreset(current_preset);
return;
}
else if (combo_box->getName() == "WLWaterPresetsCombo")
const std::string& wwset = combo_box->getSelectedValue().asString();
if (LLWaterParamManager::getInstance()->hasParamSet(wwset))
{
if(combo_box->getSimple() == "")
{
return;
}
current_preset = combo_box->getSelectedValue().asString();
LLWaterParamManager::getInstance()->loadPreset(current_preset);
LLEnvManagerNew::instance().setUseWaterPreset(wwset, gSavedSettings.getBOOL("PhoenixInterpolateWater"));
}
else
{
//if that failed, use region's
// LLEnvManagerNew::instance().useRegionWater();
LLEnvManagerNew::instance().setUseWaterPreset("Default", gSavedSettings.getBOOL("PhoenixInterpolateWater"));
}
}
void wlfPanel_AdvSettings::onChangeWLPresetName(LLUICtrl* ctrl, void * userData)
{
LLComboBox * combo_box = static_cast<LLComboBox*>(ctrl);
if(combo_box->getSimple() == "")
{
return;
}
const LLWLParamKey key(combo_box->getSelectedValue().asString(), LLEnvKey::SCOPE_LOCAL);
if (LLWLParamManager::getInstance()->hasParamSet(key))
{
LLEnvManagerNew::instance().setUseSkyPreset(key.name, gSavedSettings.getBOOL("PhoenixInterpolateSky"));
}
else
{
//if that failed, use region's
// LLEnvManagerNew::instance().useRegionSky();
LLEnvManagerNew::instance().setUseSkyPreset("Default", gSavedSettings.getBOOL("PhoenixInterpolateSky"));
}
}
void wlfPanel_AdvSettings::onClickWWNext(void* user_data)
{
wlfPanel_AdvSettings* self = (wlfPanel_AdvSettings*) user_data;
S32 index = self->mWaterPresetCombo->getCurrentIndex();
index++;
if (index == self->mWaterPresetCombo->getItemCount())
index = 0;
self->mWaterPresetCombo->setCurrentByIndex(index);
wlfPanel_AdvSettings::onChangeWWPresetName(self->mWaterPresetCombo, self);
}
void wlfPanel_AdvSettings::onClickWWPrev(void* user_data)
{
wlfPanel_AdvSettings* self = (wlfPanel_AdvSettings*) user_data;
S32 index = self->mWaterPresetCombo->getCurrentIndex();
if (index == 0)
index = self->mWaterPresetCombo->getItemCount();
index--;
self->mWaterPresetCombo->setCurrentByIndex(index);
wlfPanel_AdvSettings::onChangeWWPresetName(self->mWaterPresetCombo, self);
}
void wlfPanel_AdvSettings::onClickWLNext(void* user_data)
{
wlfPanel_AdvSettings* self = (wlfPanel_AdvSettings*) user_data;
S32 index = self->mSkyPresetCombo->getCurrentIndex();
index++;
if (index == self->mSkyPresetCombo->getItemCount())
index = 0;
self->mSkyPresetCombo->setCurrentByIndex(index);
wlfPanel_AdvSettings::onChangeWLPresetName(self->mSkyPresetCombo, self);
}
void wlfPanel_AdvSettings::onClickWLPrev(void* user_data)
{
wlfPanel_AdvSettings* self = (wlfPanel_AdvSettings*) user_data;
S32 index = self->mSkyPresetCombo->getCurrentIndex();
if (index == 0)
index = self->mSkyPresetCombo->getItemCount();
index--;
self->mSkyPresetCombo->setCurrentByIndex(index);
wlfPanel_AdvSettings::onChangeWLPresetName(self->mSkyPresetCombo, self);
}
void wlfPanel_AdvSettings::onOpenAdvancedSky(void* userData)
{
LLFloaterWindLight::show();
}
void wlfPanel_AdvSettings::onOpenAdvancedWater(void* userData)
{
LLFloaterWater::show();
}
void wlfPanel_AdvSettings::onChangeDayTime(LLUICtrl* ctrl, void* userData)
{
LLSliderCtrl* sldr = static_cast<LLSliderCtrl*>(ctrl);
if (sldr) {
// deactivate animator
LLWLParamManager::getInstance()->mAnimator.deactivate();
F32 val = sldr->getValueF32() + 0.25f;
if(val > 1.0)
{
val--;
}
LLWLParamManager::getInstance()->mAnimator.setDayTime((F64)val);
LLWLParamManager::getInstance()->mAnimator.update(
LLWLParamManager::getInstance()->mCurParams);
}
}
void wlfPanel_AdvSettings::populateWaterPresetsList()
{
mWaterPresetCombo->removeall();
std::list<std::string> presets;
LLWaterParamManager::getInstance()->getPresetNames(presets);
for (std::list<std::string>::const_iterator it = presets.begin(); it != presets.end(); ++it)
{
mWaterPresetCombo->add(*it);
}
//populate the combos with "Default" if using region settings
if (gSavedSettings.getBOOL("UseEnvironmentFromRegion"))
{
mWaterPresetCombo->selectByValue("Default");
}
else
{
// Select the current presets in combo boxes.
mWaterPresetCombo->selectByValue(LLEnvManagerNew::instance().getWaterPresetName());
}
}
void wlfPanel_AdvSettings::populateSkyPresetsList()
{
mSkyPresetCombo->removeall();
LLWLParamManager::preset_name_list_t local_presets;
LLWLParamManager::getInstance()->getLocalPresetNames(local_presets);
for (LLWLParamManager::preset_name_list_t::const_iterator it = local_presets.begin(); it != local_presets.end(); ++it)
{
mSkyPresetCombo->add(*it);
}
//populate the combos with "Default" if using region settings
if (gSavedSettings.getBOOL("UseEnvironmentFromRegion"))
{
mSkyPresetCombo->selectByValue("Default");
}
else
{
// Select the current presets in combo boxes.
mSkyPresetCombo->selectByValue(LLEnvManagerNew::instance().getSkyPresetName());
}
}
// void wlfPanel_AdvSettings::populateDayCyclePresetsList()
// {
// mDayCyclePresetCombo->removeall();
// LLDayCycleManager::preset_name_list_t user_days, sys_days;
// LLDayCycleManager::instance().getPresetNames(user_days, sys_days);
// // Add user days.
// for (LLDayCycleManager::preset_name_list_t::const_iterator it = user_days.begin(); it != user_days.end(); ++it)
// {
// mDayCyclePresetCombo->add(*it);
// }
// if (user_days.size() > 0)
// {
// mDayCyclePresetCombo->addSeparator();
// }
// // Add system days.
// for (LLDayCycleManager::preset_name_list_t::const_iterator it = sys_days.begin(); it != sys_days.end(); ++it)
// {
// mDayCyclePresetCombo->add(*it);
// }
//populate the combos with "Default" if using region settings
// if (gSavedSettings.getBOOL("UseEnvironmentFromRegion"))
// {
// mDayCyclePresetCombo->selectByValue("Default");
// }
// else
// {
// Select the current presets in combo boxes.
// mDayCyclePresetCombo->selectByValue(LLEnvManagerNew::instance().getDayCycleName());
// }
// }
void wlfPanel_AdvSettings::updateTimeSlider()
{
F32 val = LLWLParamManager::getInstance()->mAnimator.getDayTime() - 0.25f;
if(val < 0.0)
{
val++;
}
mTimeSlider->setValue(val);
}

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2009
/* Copyright (c) 2010
*
* Modular Systems All rights reserved.
*
@@ -16,7 +16,7 @@
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY MODULAR SYSTEMS AND CONTRIBUTORS <EFBFBD>AS IS<EFBFBD>
* THIS SOFTWARE IS PROVIDED BY MODULAR SYSTEMS AND CONTRIBUTORS “AS IS”
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MODULAR SYSTEMS OR CONTRIBUTORS
@@ -34,6 +34,9 @@
#include "llpanel.h"
class LLComboBox;
class LLSliderCtrl;
class wlfPanel_AdvSettings : public LLPanel
{
public:
@@ -46,11 +49,32 @@ public:
static void fixPanel();
static void onClickExpandBtn(void* user_data);
static void onChangePresetName(LLUICtrl* ctrl, void* userData);
static void onChangeWWPresetName(LLUICtrl* ctrl, void* userData);
static void onChangeWLPresetName(LLUICtrl* ctrl, void* userData);
protected:
void build();
static void onUseRegionSettings(LLUICtrl* ctrl, void* userdata);
static void onClickWWNext(void* user_data);
static void onClickWWPrev(void* user_data);
static void onClickWLNext(void* user_data);
static void onClickWLPrev(void* user_data);
static void onOpenAdvancedSky(void* userData);
static void onOpenAdvancedWater(void* userData);
static void onChangeDayTime(LLUICtrl* ctrl, void* userData);
void refreshLists(); /// update controls with user prefs
void populateWaterPresetsList();
void populateSkyPresetsList();
// void populateDayCyclePresetsList();
void updateTimeSlider();
LLComboBox* mWaterPresetCombo;
LLComboBox* mSkyPresetCombo;
// LLComboBox* mDayCyclePresetCombo;
LLSliderCtrl* mTimeSlider;
};
#endif // LL_wlfPanel_AdvSettings_H