00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "llwlparammanager.h"
00035
00036 #include "pipeline.h"
00037 #include "llsky.h"
00038
00039 #include "llsliderctrl.h"
00040 #include "llspinctrl.h"
00041 #include "llcheckboxctrl.h"
00042 #include "lluictrlfactory.h"
00043 #include "llviewercamera.h"
00044 #include "llcombobox.h"
00045 #include "lllineeditor.h"
00046 #include "llsdserialize.h"
00047
00048 #include "v4math.h"
00049 #include "llviewerdisplay.h"
00050 #include "llviewercontrol.h"
00051 #include "llviewerwindow.h"
00052 #include "lldrawpoolwater.h"
00053 #include "llagent.h"
00054 #include "llviewerregion.h"
00055
00056 #include "llwlparamset.h"
00057 #include "llpostprocess.h"
00058 #include "llfloaterwindlight.h"
00059 #include "llfloaterdaycycle.h"
00060 #include "llfloaterenvsettings.h"
00061
00062 #include "curl/curl.h"
00063
00064 LLWLParamManager * LLWLParamManager::sInstance = NULL;
00065
00066 LLWLParamManager::LLWLParamManager() :
00067
00068
00069
00070
00072 mSunDeltaYaw(180.0f),
00073 mSceneLightStrength(2.0f),
00074 mWLGamma(1.0f, "gamma"),
00075
00076 mBlueHorizon(0.25f, 0.25f, 1.0f, 1.0f, "blue_horizon", "WLBlueHorizon"),
00077 mHazeDensity(1.0f, 1.0f, 1.0f, 0.5f, "haze_density"),
00078 mBlueDensity(0.25f, 0.25f, 0.25f, 1.0f, "blue_density", "WLBlueDensity"),
00079 mDensityMult(1.0f, "density_multiplier", 1000),
00080 mHazeHorizon(1.0f, 1.0f, 1.0f, 0.5f, "haze_horizon"),
00081 mMaxAlt(4000.0f, "max_y"),
00082
00083
00084 mLightnorm(0.f, 0.707f, -0.707f, 1.f, "lightnorm"),
00085 mSunlight(0.5f, 0.5f, 0.5f, 1.0f, "sunlight_color", "WLSunlight"),
00086 mAmbient(0.5f, 0.75f, 1.0f, 1.19f, "ambient", "WLAmbient"),
00087 mGlow(18.0f, 0.0f, -0.01f, 1.0f, "glow"),
00088
00089
00090 mCloudColor(0.5f, 0.5f, 0.5f, 1.0f, "cloud_color", "WLCloudColor"),
00091 mCloudMain(0.5f, 0.5f, 0.125f, 1.0f, "cloud_pos_density1"),
00092 mCloudCoverage(0.0f, "cloud_shadow"),
00093 mCloudDetail(0.0f, 0.0f, 0.0f, 1.0f, "cloud_pos_density2"),
00094 mDistanceMult(1.0f, "distance_multiplier"),
00095 mCloudScale(0.42f, "cloud_scale"),
00096
00097
00098 mDomeOffset(0.96f),
00099 mDomeRadius(15000.f)
00100 {
00101 }
00102
00103 LLWLParamManager::~LLWLParamManager()
00104 {
00105 }
00106
00107 void LLWLParamManager::loadPresets(const LLString& file_name)
00108 {
00109
00110
00111 if(file_name != "")
00112 {
00113 LLString path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", file_name));
00114 LL_INFOS2("AppInit", "Shaders") << "Loading WindLight settings from " << path_name << LL_ENDL;
00115
00116 llifstream presetsXML(path_name.c_str());
00117
00118 if (presetsXML)
00119 {
00120 LLSD paramsData(LLSD::emptyMap());
00121
00122 LLPointer<LLSDParser> parser = new LLSDXMLParser();
00123
00124 parser->parse(presetsXML, paramsData, LLSDSerialize::SIZE_UNLIMITED);
00125
00126 LLSD::map_const_iterator endParams = paramsData.endMap();
00127 for(LLSD::map_const_iterator curParams = paramsData.beginMap();
00128 curParams != endParams;
00129 ++curParams)
00130 {
00131 addParamSet(curParams->first, curParams->second);
00132 }
00133 }
00134 }
00135
00136
00137 else
00138 {
00139 LLString path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", ""));
00140 LL_INFOS2("AppInit", "Shaders") << "Loading WindLight settings from " << path_name << LL_ENDL;
00141
00142
00143
00144 bool found = true;
00145 while(found)
00146 {
00147 std::string name;
00148 found = gDirUtilp->getNextFileInDir(path_name, "*.xml", name, false);
00149
00150 LL_DEBUGS2("AppInit", "Shaders") << "name: " << name << LL_ENDL;
00151
00152
00153 if(found)
00154 {
00155
00156 char * curl_str = curl_unescape(name.c_str(), name.size());
00157 std::string unescaped_name(curl_str);
00158 curl_free(curl_str);
00159 curl_str = NULL;
00160
00161
00162 std::string sky_name = unescaped_name.substr(0, unescaped_name.size() - 4);
00163
00164 LLString cur_path(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", name));
00165 LL_DEBUGS2("AppInit", "Shaders") << "Loading sky from " << cur_path << LL_ENDL;
00166
00167 std::ifstream sky_xml(cur_path.c_str());
00168 if (sky_xml)
00169 {
00170 LLSD sky_data(LLSD::emptyMap());
00171 LLPointer<LLSDParser> parser = new LLSDXMLParser();
00172 parser->parse(sky_xml, sky_data, LLSDSerialize::SIZE_UNLIMITED);
00173
00174 addParamSet(sky_name, sky_data);
00175 }
00176 }
00177 }
00178 }
00179 }
00180
00181 void LLWLParamManager::savePresets(const LLString & fileName)
00182 {
00183 LLSD paramsData(LLSD::emptyMap());
00184
00185 LLString pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", fileName));
00186
00187 for(std::map<std::string, LLWLParamSet>::iterator mIt = mParamList.begin();
00188 mIt != mParamList.end();
00189 ++mIt)
00190 {
00191 paramsData[mIt->first] = mIt->second.getAll();
00192 }
00193
00194 std::ofstream presetsXML(pathName.c_str());
00195
00196 LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
00197
00198 formatter->format(paramsData, presetsXML, LLSDFormatter::OPTIONS_PRETTY);
00199
00200 presetsXML.close();
00201 }
00202
00203 void LLWLParamManager::loadPreset(const LLString & name)
00204 {
00205
00206 char * curl_str = curl_escape(name.c_str(), name.size());
00207 std::string escaped_filename(curl_str);
00208 curl_free(curl_str);
00209 curl_str = NULL;
00210
00211 escaped_filename += ".xml";
00212
00213 std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", escaped_filename));
00214 llinfos << "Loading WindLight sky setting from " << pathName << llendl;
00215
00216 std::ifstream presetsXML(pathName.c_str());
00217
00218 if (presetsXML)
00219 {
00220 LLSD paramsData(LLSD::emptyMap());
00221
00222 LLPointer<LLSDParser> parser = new LLSDXMLParser();
00223
00224 parser->parse(presetsXML, paramsData, LLSDSerialize::SIZE_UNLIMITED);
00225
00226 std::map<std::string, LLWLParamSet>::iterator mIt = mParamList.find(name);
00227 if(mIt == mParamList.end())
00228 {
00229 addParamSet(name, paramsData);
00230 }
00231 else
00232 {
00233 setParamSet(name, paramsData);
00234 }
00235 }
00236 else
00237 {
00238 llwarns << "Can't find " << name << llendl;
00239 return;
00240 }
00241
00242 getParamSet(name, mCurParams);
00243
00244 propagateParameters();
00245 }
00246
00247 void LLWLParamManager::savePreset(const LLString & name)
00248 {
00249
00250 char * curl_str = curl_escape(name.c_str(), name.size());
00251 std::string escaped_filename(curl_str);
00252 curl_free(curl_str);
00253 curl_str = NULL;
00254
00255 escaped_filename += ".xml";
00256
00257
00258 LLSD paramsData(LLSD::emptyMap());
00259 std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", escaped_filename));
00260
00261
00262 paramsData = mParamList[name].getAll();
00263
00264
00265 std::ofstream presetsXML(pathName.c_str());
00266 LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
00267 formatter->format(paramsData, presetsXML, LLSDFormatter::OPTIONS_PRETTY);
00268 presetsXML.close();
00269
00270 propagateParameters();
00271 }
00272
00273 void LLWLParamManager::updateShaderUniforms(LLGLSLShader * shader)
00274 {
00275 if (gPipeline.canUseWindLightShaders())
00276 {
00277 mCurParams.update(shader);
00278 }
00279
00280 if (shader->mShaderGroup == LLGLSLShader::SG_DEFAULT)
00281 {
00282 shader->uniform4fv(LLShaderMgr::LIGHTNORM, 1, mRotatedLightDir.mV);
00283 shader->uniform3fv("camPosLocal", 1, LLViewerCamera::getInstance()->getOrigin().mV);
00284 }
00285
00286 else if (shader->mShaderGroup == LLGLSLShader::SG_SKY)
00287 {
00288 shader->uniform4fv(LLShaderMgr::LIGHTNORM, 1, mClampedLightDir.mV);
00289 }
00290
00291 shader->uniform1f("scene_light_strength", mSceneLightStrength);
00292
00293 }
00294
00295 void LLWLParamManager::propagateParameters(void)
00296 {
00297 LLFastTimer ftm(LLFastTimer::FTM_UPDATE_WLPARAM);
00298
00299 LLVector4 sunDir;
00300 LLVector4 moonDir;
00301
00302
00303 F32 sinTheta = sin(mCurParams.getEastAngle());
00304 F32 cosTheta = cos(mCurParams.getEastAngle());
00305
00306 F32 sinPhi = sin(mCurParams.getSunAngle());
00307 F32 cosPhi = cos(mCurParams.getSunAngle());
00308
00309 sunDir.mV[0] = -sinTheta * cosPhi;
00310 sunDir.mV[1] = sinPhi;
00311 sunDir.mV[2] = cosTheta * cosPhi;
00312 sunDir.mV[3] = 0;
00313
00314 moonDir = -sunDir;
00315
00316
00317 if(sunDir.mV[1] >= 0)
00318 {
00319 mLightDir = sunDir;
00320 }
00321 else if(sunDir.mV[1] < 0 && sunDir.mV[1] > NIGHTTIME_ELEVATION_COS)
00322 {
00323
00324 LLVector3 vec(sunDir.mV[0], sunDir.mV[1], sunDir.mV[2]);
00325 vec.mV[1] = 0;
00326 vec.normVec();
00327 mLightDir = LLVector4(vec, 0.f);
00328 }
00329 else
00330 {
00331 mLightDir = moonDir;
00332 }
00333
00334
00335
00336 mClampedLightDir = sunDir;
00337
00338 if (mClampedLightDir.mV[1] < -0.1f)
00339 {
00340 mClampedLightDir.mV[1] = -0.1f;
00341 }
00342
00343 mCurParams.set("lightnorm", mLightDir);
00344
00345
00346 LLShaderMgr::shader_iter shaders_iter, end_shaders;
00347 end_shaders = LLShaderMgr::endShaders();
00348 for(shaders_iter = LLShaderMgr::beginShaders(); shaders_iter != end_shaders; ++shaders_iter)
00349 {
00350 if (shaders_iter->mProgramObject != 0
00351 && (gPipeline.canUseWindLightShaders()
00352 || shaders_iter->mShaderGroup == LLGLSLShader::SG_WATER))
00353 {
00354 shaders_iter->mUniformsDirty = TRUE;
00355 }
00356 }
00357
00358
00359 LLVector3 cfrSunDir(sunDir.mV[2], sunDir.mV[0], sunDir.mV[1]);
00360
00361
00362 gSky.setSunDirection(cfrSunDir, LLVector3(0,0,0));
00363 gSky.setOverrideSun(TRUE);
00364 }
00365
00366 void LLWLParamManager::update(LLViewerCamera * cam)
00367 {
00368 LLFastTimer ftm(LLFastTimer::FTM_UPDATE_WLPARAM);
00369
00370
00371 mCurParams.updateCloudScrolling();
00372
00373
00374 if(mAnimator.mIsRunning)
00375 {
00376 mAnimator.update(mCurParams);
00377 }
00378
00379
00380 propagateParameters();
00381
00382
00383 if(LLFloaterWindLight::isOpen())
00384 {
00385 LLFloaterWindLight::instance()->syncMenu();
00386 }
00387 if(LLFloaterDayCycle::isOpen())
00388 {
00389 LLFloaterDayCycle::instance()->syncMenu();
00390 }
00391 if(LLFloaterEnvSettings::isOpen())
00392 {
00393 LLFloaterEnvSettings::instance()->syncMenu();
00394 }
00395
00396 F32 camYaw = cam->getYaw();
00397
00398 stop_glerror();
00399
00400
00401
00402 {
00403 F32 camYawDelta = mSunDeltaYaw * DEG_TO_RAD;
00404
00405 LLVector3 lightNorm3(mLightDir);
00406 lightNorm3 *= LLQuaternion(-(camYaw + camYawDelta), LLVector3(0.f, 1.f, 0.f));
00407 mRotatedLightDir = LLVector4(lightNorm3, 0.f);
00408
00409 LLShaderMgr::shader_iter shaders_iter, end_shaders;
00410 end_shaders = LLShaderMgr::endShaders();
00411 for(shaders_iter = LLShaderMgr::beginShaders(); shaders_iter != end_shaders; ++shaders_iter)
00412 {
00413 if (shaders_iter->mProgramObject != 0
00414 && (gPipeline.canUseWindLightShaders()
00415 || shaders_iter->mShaderGroup == LLGLSLShader::SG_WATER))
00416 {
00417 shaders_iter->mUniformsDirty = TRUE;
00418 }
00419 }
00420 }
00421 }
00422
00423
00424 void LLWLParamManager::initClass(void)
00425 {
00426 instance();
00427 }
00428
00429
00430 void LLWLParamManager::cleanupClass()
00431 {
00432 delete sInstance;
00433 sInstance = NULL;
00434 }
00435
00436 void LLWLParamManager::resetAnimator(F32 curTime, bool run)
00437 {
00438 mAnimator.setTrack(mDay.mTimeMap, mDay.mDayRate,
00439 curTime, run);
00440
00441 return;
00442 }
00443 bool LLWLParamManager::addParamSet(const std::string& name, LLWLParamSet& param)
00444 {
00445
00446 std::map<std::string, LLWLParamSet>::iterator mIt = mParamList.find(name);
00447 if(mIt == mParamList.end())
00448 {
00449 mParamList[name] = param;
00450 return true;
00451 }
00452
00453 return false;
00454 }
00455
00456 BOOL LLWLParamManager::addParamSet(const std::string& name, LLSD const & param)
00457 {
00458
00459 std::map<std::string, LLWLParamSet>::const_iterator finder = mParamList.find(name);
00460 if(finder == mParamList.end())
00461 {
00462 mParamList[name].setAll(param);
00463 return TRUE;
00464 }
00465 else
00466 {
00467 return FALSE;
00468 }
00469 }
00470
00471 bool LLWLParamManager::getParamSet(const std::string& name, LLWLParamSet& param)
00472 {
00473
00474 std::map<std::string, LLWLParamSet>::iterator mIt = mParamList.find(name);
00475 if(mIt != mParamList.end())
00476 {
00477 param = mParamList[name];
00478 param.mName = name;
00479 return true;
00480 }
00481
00482 return false;
00483 }
00484
00485 bool LLWLParamManager::setParamSet(const std::string& name, LLWLParamSet& param)
00486 {
00487 mParamList[name] = param;
00488
00489 return true;
00490 }
00491
00492 bool LLWLParamManager::setParamSet(const std::string& name, const LLSD & param)
00493 {
00494
00495 if(!param.isMap())
00496 {
00497 return false;
00498 }
00499
00500 mParamList[name].setAll(param);
00501
00502 return true;
00503 }
00504
00505 bool LLWLParamManager::removeParamSet(const std::string& name, bool delete_from_disk)
00506 {
00507
00508 std::map<std::string, LLWLParamSet>::iterator mIt = mParamList.find(name);
00509 if(mIt != mParamList.end())
00510 {
00511 mParamList.erase(mIt);
00512 }
00513
00514 F32 key;
00515
00516
00517 bool stat = true;
00518 do
00519 {
00520
00521 stat = mDay.getKey(name, key);
00522 if(stat == false)
00523 {
00524 break;
00525 }
00526
00527
00528 stat = mDay.removeKey(key);
00529
00530 } while(stat == true);
00531
00532 if(delete_from_disk)
00533 {
00534 LLString path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", ""));
00535
00536
00537 char * curl_str = curl_escape(name.c_str(), name.size());
00538 std::string escaped_name(curl_str);
00539 curl_free(curl_str);
00540 curl_str = NULL;
00541
00542 gDirUtilp->deleteFilesInDir(path_name, escaped_name + ".xml");
00543 }
00544
00545 return true;
00546 }
00547
00548
00549
00550 LLWLParamManager * LLWLParamManager::instance()
00551 {
00552 if(NULL == sInstance)
00553 {
00554 sInstance = new LLWLParamManager();
00555
00556 sInstance->loadPresets("");
00557
00558
00559 sInstance->mDay.loadDayCycle("Default.xml");
00560
00561
00562 sInstance->getParamSet("Default", sInstance->mCurParams);
00563
00564
00565 sInstance->resetAnimator(0.5, true);
00566
00567
00568 sInstance->mAnimator.mUseLindenTime = true;
00569 }
00570
00571 return sInstance;
00572 }