summaryrefslogtreecommitdiff
path: root/indra/newview/llwlparammanager.cpp
diff options
context:
space:
mode:
authorBrad Kittenbrink <brad@lindenlab.com>2008-02-27 18:58:14 +0000
committerBrad Kittenbrink <brad@lindenlab.com>2008-02-27 18:58:14 +0000
commit6d52efe452aa8469e0343da1c7d108f3f52ab651 (patch)
treea87be48e9840d7fc1f7ee514d7c7f994e71fdb3c /indra/newview/llwlparammanager.cpp
parent6027ad2630b8650cabcf00628ee9b0d25bedd67f (diff)
Merge of windlight into release (QAR-286). This includes all changes in
windlight14 which have passed QA (up through r79932). svn merge -r 80831:80833 svn+ssh://svn.lindenlab.com/svn/linden/branches/merge_windlight14_r80620
Diffstat (limited to 'indra/newview/llwlparammanager.cpp')
-rw-r--r--indra/newview/llwlparammanager.cpp572
1 files changed, 572 insertions, 0 deletions
diff --git a/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp
new file mode 100644
index 0000000000..b1c1f5e2d0
--- /dev/null
+++ b/indra/newview/llwlparammanager.cpp
@@ -0,0 +1,572 @@
+/**
+ * @file llwlparammanager.cpp
+ * @brief Implementation for the LLWLParamManager class.
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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 "llwlparammanager.h"
+
+#include "pipeline.h"
+#include "llsky.h"
+
+#include "llsliderctrl.h"
+#include "llspinctrl.h"
+#include "llcheckboxctrl.h"
+#include "llvieweruictrlfactory.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 "llwlparamset.h"
+#include "llpostprocess.h"
+#include "llfloaterwindlight.h"
+#include "llfloaterdaycycle.h"
+#include "llfloaterenvsettings.h"
+
+#include "curl/curl.h"
+
+LLWLParamManager * LLWLParamManager::sInstance = NULL;
+
+LLWLParamManager::LLWLParamManager() :
+
+ //set the defaults for the controls
+ // index is from sWLUniforms in pipeline.cpp line 979
+
+ /// Sun Delta Terrain tweak variables.
+ mSunDeltaYaw(180.0f),
+ mSceneLightStrength(2.0f),
+ mWLGamma(1.0f, "gamma"),
+
+ mBlueHorizon(0.25f, 0.25f, 1.0f, 1.0f, "blue_horizon", "WLBlueHorizon"),
+ mHazeDensity(1.0f, 1.0f, 1.0f, 0.5f, "haze_density"),
+ mBlueDensity(0.25f, 0.25f, 0.25f, 1.0f, "blue_density", "WLBlueDensity"),
+ mDensityMult(1.0f, "density_multiplier", 1000),
+ mHazeHorizon(1.0f, 1.0f, 1.0f, 0.5f, "haze_horizon"),
+ mMaxAlt(4000.0f, "max_y"),
+
+ // Lighting
+ mLightnorm(0.f, 0.707f, -0.707f, 1.f, "lightnorm"),
+ mSunlight(0.5f, 0.5f, 0.5f, 1.0f, "sunlight_color", "WLSunlight"),
+ mAmbient(0.5f, 0.75f, 1.0f, 1.19f, "ambient", "WLAmbient"),
+ mGlow(18.0f, 0.0f, -0.01f, 1.0f, "glow"),
+
+ // Clouds
+ mCloudColor(0.5f, 0.5f, 0.5f, 1.0f, "cloud_color", "WLCloudColor"),
+ mCloudMain(0.5f, 0.5f, 0.125f, 1.0f, "cloud_pos_density1"),
+ mCloudCoverage(0.0f, "cloud_shadow"),
+ mCloudDetail(0.0f, 0.0f, 0.0f, 1.0f, "cloud_pos_density2"),
+ mDistanceMult(1.0f, "distance_multiplier"),
+ mCloudScale(0.42f, "cloud_scale"),
+
+ // sky dome
+ mDomeOffset(0.96f),
+ mDomeRadius(15000.f)
+{
+}
+
+LLWLParamManager::~LLWLParamManager()
+{
+}
+
+void LLWLParamManager::loadPresets(const LLString& file_name)
+{
+ // if fileName exists, use legacy loading form the big file, otherwise, search the sky
+ // directory, and add the list
+ if(file_name != "")
+ {
+ LLString path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", file_name));
+ llinfos << "Loading WindLight settings from " << path_name << llendl;
+
+ llifstream presetsXML(path_name.c_str());
+
+ if (presetsXML)
+ {
+ LLSD paramsData(LLSD::emptyMap());
+
+ LLPointer<LLSDParser> parser = new LLSDXMLParser();
+
+ parser->parse(presetsXML, paramsData, LLSDSerialize::SIZE_UNLIMITED);
+
+ LLSD::map_const_iterator endParams = paramsData.endMap();
+ for(LLSD::map_const_iterator curParams = paramsData.beginMap();
+ curParams != endParams;
+ ++curParams)
+ {
+ addParamSet(curParams->first, curParams->second);
+ }
+ }
+ }
+
+ // otherwise, search the sky directory and find things there
+ else
+ {
+ LLString path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", ""));
+ llinfos << "Loading WindLight settings from " << path_name << llendl;
+
+ //mParamList.clear();
+
+ bool found = true;
+ while(found)
+ {
+ std::string name;
+ found = gDirUtilp->getNextFileInDir(path_name, "*.xml", name, false);
+
+ llinfos << "name: " << name << llendl;
+
+ // if we have one
+ if(found)
+ {
+ // 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;
+
+ // not much error checking here since we're getting rid of this
+ std::string sky_name = unescaped_name.substr(0, unescaped_name.size() - 4);
+
+ LLString cur_path(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", name));
+ llinfos << "Loading sky from " << cur_path << llendl;
+
+ std::ifstream sky_xml(cur_path.c_str());
+ if (sky_xml)
+ {
+ LLSD sky_data(LLSD::emptyMap());
+ LLPointer<LLSDParser> parser = new LLSDXMLParser();
+ parser->parse(sky_xml, sky_data, LLSDSerialize::SIZE_UNLIMITED);
+
+ addParamSet(sky_name, sky_data);
+ }
+ }
+ }
+ }
+}
+
+void LLWLParamManager::savePresets(const LLString & fileName)
+{
+ LLSD paramsData(LLSD::emptyMap());
+
+ LLString pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", fileName));
+
+ for(std::map<std::string, LLWLParamSet>::iterator mIt = mParamList.begin();
+ mIt != mParamList.end();
+ ++mIt)
+ {
+ paramsData[mIt->first] = mIt->second.getAll();
+ }
+
+ std::ofstream presetsXML(pathName.c_str());
+
+ LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
+
+ formatter->format(paramsData, presetsXML, LLSDFormatter::OPTIONS_PRETTY);
+
+ presetsXML.close();
+}
+
+void LLWLParamManager::loadPreset(const LLString & name)
+{
+ // bugfix for SL-46920: preventing filenames that break stuff.
+ char * curl_str = curl_escape(name.c_str(), name.size());
+ std::string escaped_filename(curl_str);
+ curl_free(curl_str);
+ curl_str = NULL;
+
+ escaped_filename += ".xml";
+
+ std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", escaped_filename));
+ llinfos << "Loading WindLight sky setting from " << pathName << llendl;
+
+ std::ifstream presetsXML(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);
+ }
+ }
+ else
+ {
+ llwarns << "Can't find " << name << llendl;
+ return;
+ }
+
+ getParamSet(name, mCurParams);
+
+ propagateParameters();
+}
+
+void LLWLParamManager::savePreset(const LLString & name)
+{
+ // bugfix for SL-46920: preventing filenames that break stuff.
+ char * curl_str = curl_escape(name.c_str(), name.size());
+ std::string escaped_filename(curl_str);
+ curl_free(curl_str);
+ curl_str = NULL;
+
+ escaped_filename += ".xml";
+
+ // make an empty llsd
+ LLSD paramsData(LLSD::emptyMap());
+ std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", escaped_filename));
+
+ // fill it with LLSD windlight params
+ paramsData = mParamList[name].getAll();
+
+ // write to file
+ std::ofstream presetsXML(pathName.c_str());
+ LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
+ formatter->format(paramsData, presetsXML, LLSDFormatter::OPTIONS_PRETTY);
+ presetsXML.close();
+
+ propagateParameters();
+}
+
+void LLWLParamManager::updateShaderUniforms(LLGLSLShader * shader)
+{
+ if (gPipeline.canUseWindLightShaders())
+ {
+ mCurParams.update(shader);
+ }
+
+ if (shader->mShaderGroup == LLGLSLShader::SG_DEFAULT)
+ {
+ shader->uniform4fv(LLShaderMgr::LIGHTNORM, 1, mRotatedLightDir.mV);
+ shader->uniform3fv("camPosLocal", 1, gCamera->getOrigin().mV);
+ }
+
+ else if (shader->mShaderGroup == LLGLSLShader::SG_SKY)
+ {
+ shader->uniform4fv(LLShaderMgr::LIGHTNORM, 1, mClampedLightDir.mV);
+ }
+
+ shader->uniform1f("scene_light_strength", mSceneLightStrength);
+
+}
+
+void LLWLParamManager::propagateParameters(void)
+{
+ LLFastTimer ftm(LLFastTimer::FTM_UPDATE_WLPARAM);
+
+ LLVector4 sunDir;
+ LLVector4 moonDir;
+
+ // set the sun direction from mSunAngle and mEastAngle
+ F32 sinTheta = sin(mCurParams.getEastAngle());
+ F32 cosTheta = cos(mCurParams.getEastAngle());
+
+ F32 sinPhi = sin(mCurParams.getSunAngle());
+ F32 cosPhi = cos(mCurParams.getSunAngle());
+
+ sunDir.mV[0] = -sinTheta * cosPhi;
+ sunDir.mV[1] = sinPhi;
+ sunDir.mV[2] = cosTheta * cosPhi;
+ sunDir.mV[3] = 0;
+
+ moonDir = -sunDir;
+
+ // is the normal from the sun or the moon
+ if(sunDir.mV[1] >= 0)
+ {
+ mLightDir = sunDir;
+ }
+ else if(sunDir.mV[1] < 0 && sunDir.mV[1] > NIGHTTIME_ELEVATION_COS)
+ {
+ // clamp v1 to 0 so sun never points up and causes weirdness on some machines
+ LLVector3 vec(sunDir.mV[0], sunDir.mV[1], sunDir.mV[2]);
+ vec.mV[1] = 0;
+ vec.normVec();
+ mLightDir = LLVector4(vec, 0.f);
+ }
+ else
+ {
+ mLightDir = moonDir;
+ }
+
+ // calculate the clamp lightnorm for sky (to prevent ugly banding in sky
+ // when haze goes below the horizon
+ mClampedLightDir = sunDir;
+
+ if (mClampedLightDir.mV[1] < -0.1f)
+ {
+ mClampedLightDir.mV[1] = -0.1f;
+ }
+
+ mCurParams.set("lightnorm", mLightDir);
+
+ // bind the variables for all shaders only if we're using WindLight
+ LLShaderMgr::shader_iter shaders_iter, end_shaders;
+ end_shaders = LLShaderMgr::endShaders();
+ for(shaders_iter = LLShaderMgr::beginShaders(); shaders_iter != end_shaders; ++shaders_iter)
+ {
+ if (shaders_iter->mProgramObject != 0
+ && (gPipeline.canUseWindLightShaders()
+ || shaders_iter->mShaderGroup == LLGLSLShader::SG_WATER))
+ {
+ shaders_iter->mUniformsDirty = TRUE;
+ }
+ }
+
+ // get the cfr version of the sun's direction
+ LLVector3 cfrSunDir(sunDir.mV[2], sunDir.mV[0], sunDir.mV[1]);
+
+ // set direction and don't allow overriding
+ gSky.setSunDirection(cfrSunDir, LLVector3(0,0,0));
+ gSky.setOverrideSun(TRUE);
+}
+
+void LLWLParamManager::update(LLViewerCamera * cam)
+{
+ LLFastTimer ftm(LLFastTimer::FTM_UPDATE_WLPARAM);
+
+ // update clouds, sun, and general
+ mCurParams.updateCloudScrolling();
+
+ // update only if running
+ if(mAnimator.mIsRunning)
+ {
+ mAnimator.update(mCurParams);
+ }
+
+ // update the shaders and the menu
+ propagateParameters();
+
+ // sync menus if they exist
+ if(LLFloaterWindLight::isOpen())
+ {
+ LLFloaterWindLight::instance()->syncMenu();
+ }
+ if(LLFloaterDayCycle::isOpen())
+ {
+ LLFloaterDayCycle::instance()->syncMenu();
+ }
+ if(LLFloaterEnvSettings::isOpen())
+ {
+ LLFloaterEnvSettings::instance()->syncMenu();
+ }
+
+ F32 camYaw = cam->getYaw();
+
+ stop_glerror();
+
+ // *TODO: potential optimization - this block may only need to be
+ // executed some of the time. For example for water shaders only.
+ {
+ F32 camYawDelta = mSunDeltaYaw * DEG_TO_RAD;
+
+ LLVector3 lightNorm3(mLightDir);
+ lightNorm3 *= LLQuaternion(-(camYaw + camYawDelta), LLVector3(0.f, 1.f, 0.f));
+ mRotatedLightDir = LLVector4(lightNorm3, 0.f);
+
+ LLShaderMgr::shader_iter shaders_iter, end_shaders;
+ end_shaders = LLShaderMgr::endShaders();
+ for(shaders_iter = LLShaderMgr::beginShaders(); shaders_iter != end_shaders; ++shaders_iter)
+ {
+ if (shaders_iter->mProgramObject != 0
+ && (gPipeline.canUseWindLightShaders()
+ || shaders_iter->mShaderGroup == LLGLSLShader::SG_WATER))
+ {
+ shaders_iter->mUniformsDirty = TRUE;
+ }
+ }
+ }
+}
+
+// static
+void LLWLParamManager::initClass(void)
+{
+ instance();
+}
+
+// static
+void LLWLParamManager::cleanupClass()
+{
+ delete sInstance;
+ sInstance = NULL;
+}
+
+void LLWLParamManager::resetAnimator(F32 curTime, bool run)
+{
+ mAnimator.setTrack(mDay.mTimeMap, mDay.mDayRate,
+ curTime, run);
+
+ return;
+}
+bool LLWLParamManager::addParamSet(const std::string& name, LLWLParamSet& param)
+{
+ // add a new one if not one there already
+ std::map<std::string, LLWLParamSet>::iterator mIt = mParamList.find(name);
+ if(mIt == mParamList.end())
+ {
+ mParamList[name] = param;
+ return true;
+ }
+
+ return false;
+}
+
+BOOL LLWLParamManager::addParamSet(const std::string& name, 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;
+ }
+}
+
+bool LLWLParamManager::getParamSet(const std::string& name, LLWLParamSet& param)
+{
+ // find it and set it
+ std::map<std::string, LLWLParamSet>::iterator mIt = mParamList.find(name);
+ if(mIt != mParamList.end())
+ {
+ param = mParamList[name];
+ param.mName = name;
+ return true;
+ }
+
+ return false;
+}
+
+bool LLWLParamManager::setParamSet(const std::string& name, LLWLParamSet& param)
+{
+ mParamList[name] = param;
+
+ return true;
+}
+
+bool LLWLParamManager::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;
+ }
+
+ mParamList[name].setAll(param);
+
+ return true;
+}
+
+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())
+ {
+ 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)
+ {
+ LLString path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", ""));
+
+ // use full curl escaped name
+ char * curl_str = curl_escape(name.c_str(), name.size());
+ std::string escaped_name(curl_str);
+ curl_free(curl_str);
+ curl_str = NULL;
+
+ gDirUtilp->deleteFilesInDir(path_name, escaped_name + ".xml");
+ }
+
+ return true;
+}
+
+
+// static
+LLWLParamManager * LLWLParamManager::instance()
+{
+ if(NULL == sInstance)
+ {
+ sInstance = new LLWLParamManager();
+
+ sInstance->loadPresets("");
+
+ // load the day
+ sInstance->mDay.loadDayCycle("Default.xml");
+
+ // *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;
+}