llwlwaterparammgr.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  1. /**
  2. * @file llwlwaterparammgr.cpp
  3. * @brief Implementation for the LLWLWaterParamMgr class.
  4. *
  5. * $LicenseInfo:firstyear=2007&license=viewergpl$
  6. *
  7. * Copyright (c) 2007-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #include "llviewerprecompiledheaders.h"
  33. #include "llwlwaterparammgr.h"
  34. #include "imageids.h"
  35. #include "lldir.h"
  36. #include "lldiriterator.h"
  37. #include "llfasttimer.h"
  38. #include "llrender.h"
  39. #include "llsdserialize.h"
  40. #include "llsdutil.h"
  41. #include "llagent.h"
  42. #include "llenvironment.h"
  43. #include "llenvsettings.h"
  44. #include "llfloaterwindlight.h"
  45. #include "llsky.h"
  46. #include "hbviewerautomation.h"
  47. #include "llviewercamera.h"
  48. #include "llviewercontrol.h"
  49. #include "llviewerdisplay.h"
  50. #include "llviewerregion.h"
  51. #include "llwlskyparammgr.h"
  52. LLWLWaterParamMgr gWLWaterParamMgr;
  53. ///////////////////////////////////////////////////////////////////////////////
  54. // LLWaterParamSet class
  55. ///////////////////////////////////////////////////////////////////////////////
  56. LLWaterParamSet::LLWaterParamSet()
  57. : mName("Unnamed Preset")
  58. {
  59. LLSD vec4;
  60. LLSD vec3;
  61. LLSD real(0.0f);
  62. vec4 = LLSD::emptyArray();
  63. vec4.append(22.f / 255.f);
  64. vec4.append(43.f / 255.f);
  65. vec4.append(54.f / 255.f);
  66. vec4.append(0.f / 255.f);
  67. vec3 = LLSD::emptyArray();
  68. vec3.append(2);
  69. vec3.append(2);
  70. vec3.append(2);
  71. LLSD wave1, wave2;
  72. wave1 = LLSD::emptyArray();
  73. wave2 = LLSD::emptyArray();
  74. wave1.append(0.5f);
  75. wave1.append(-.17f);
  76. wave2.append(0.58f);
  77. wave2.append(-.67f);
  78. mParamValues.insert("waterFogColor", vec4);
  79. mParamValues.insert("waterFogDensity", 16.0f);
  80. mParamValues.insert("underWaterFogMod", 0.25f);
  81. mParamValues.insert("normScale", vec3);
  82. mParamValues.insert("fresnelScale", 0.5f);
  83. mParamValues.insert("fresnelOffset", 0.4f);
  84. mParamValues.insert("scaleAbove", 0.025f);
  85. mParamValues.insert("scaleBelow", 0.2f);
  86. mParamValues.insert("blurMultiplier", 0.01f);
  87. mParamValues.insert("wave1Dir", wave1);
  88. mParamValues.insert("wave2Dir", wave2);
  89. mParamValues.insert("normalMap", DEFAULT_WATER_NORMAL);
  90. }
  91. void LLWaterParamSet::updateHashedNames()
  92. {
  93. mParamHashedNames.clear();
  94. // Iterate through values
  95. for (LLSD::map_iterator iter = mParamValues.beginMap(),
  96. end = mParamValues.endMap();
  97. iter != end; ++iter)
  98. {
  99. mParamHashedNames.push_back(LLStaticHashedString(iter->first));
  100. }
  101. }
  102. void LLWaterParamSet::setAll(const LLSD& val)
  103. {
  104. if (val.isMap())
  105. {
  106. for (LLSD::map_const_iterator it = val.beginMap(), end = val.endMap();
  107. it != end; ++it)
  108. {
  109. mParamValues[it->first] = it->second;
  110. }
  111. }
  112. updateHashedNames();
  113. }
  114. void LLWaterParamSet::set(const std::string& param_name, F32 x)
  115. {
  116. // Handle case where no array
  117. LLSD::Type type = mParamValues[param_name].type();
  118. if (type == LLSD::TypeReal)
  119. {
  120. mParamValues[param_name] = x;
  121. }
  122. // Handle array
  123. else if (type == LLSD::TypeArray &&
  124. mParamValues[param_name][0].isReal())
  125. {
  126. mParamValues[param_name][0] = x;
  127. }
  128. }
  129. void LLWaterParamSet::set(const std::string& param_name, F32 x, F32 y)
  130. {
  131. mParamValues[param_name][0] = x;
  132. mParamValues[param_name][1] = y;
  133. }
  134. void LLWaterParamSet::set(const std::string& param_name, F32 x, F32 y, F32 z)
  135. {
  136. mParamValues[param_name][0] = x;
  137. mParamValues[param_name][1] = y;
  138. mParamValues[param_name][2] = z;
  139. }
  140. void LLWaterParamSet::set(const std::string& param_name, F32 x, F32 y, F32 z,
  141. F32 w)
  142. {
  143. mParamValues[param_name][0] = x;
  144. mParamValues[param_name][1] = y;
  145. mParamValues[param_name][2] = z;
  146. mParamValues[param_name][3] = w;
  147. }
  148. void LLWaterParamSet::set(const std::string& param_name, const F32* val)
  149. {
  150. mParamValues[param_name][0] = val[0];
  151. mParamValues[param_name][1] = val[1];
  152. mParamValues[param_name][2] = val[2];
  153. mParamValues[param_name][3] = val[3];
  154. }
  155. void LLWaterParamSet::set(const std::string& param_name, const LLVector4& val)
  156. {
  157. mParamValues[param_name][0] = val.mV[0];
  158. mParamValues[param_name][1] = val.mV[1];
  159. mParamValues[param_name][2] = val.mV[2];
  160. mParamValues[param_name][3] = val.mV[3];
  161. }
  162. void LLWaterParamSet::set(const std::string& param_name, const LLColor4& val)
  163. {
  164. mParamValues[param_name][0] = val.mV[0];
  165. mParamValues[param_name][1] = val.mV[1];
  166. mParamValues[param_name][2] = val.mV[2];
  167. mParamValues[param_name][3] = val.mV[3];
  168. }
  169. LLVector4 LLWaterParamSet::getVector4(const std::string& param_name,
  170. bool& error)
  171. {
  172. // Test to see if right type
  173. LLSD cur_val = mParamValues.get(param_name);
  174. if (!cur_val.isArray() || cur_val.size() != 4)
  175. {
  176. error = true;
  177. return LLVector4();
  178. }
  179. error = false;
  180. return LLVector4(cur_val[0].asReal(), cur_val[1].asReal(),
  181. cur_val[2].asReal(), cur_val[3].asReal());
  182. }
  183. LLVector3 LLWaterParamSet::getVector3(const std::string& param_name,
  184. bool& error)
  185. {
  186. // Test to see if right type
  187. LLSD cur_val = mParamValues.get(param_name);
  188. if (!cur_val.isArray()|| cur_val.size() != 3)
  189. {
  190. error = true;
  191. return LLVector3();
  192. }
  193. error = false;
  194. return LLVector3(cur_val[0].asReal(), cur_val[1].asReal(),
  195. cur_val[2].asReal());
  196. }
  197. LLVector2 LLWaterParamSet::getVector2(const std::string& param_name,
  198. bool& error)
  199. {
  200. LLSD cur_val = mParamValues.get(param_name);
  201. if (!cur_val.isArray() || cur_val.size() != 2)
  202. {
  203. error = true;
  204. return LLVector2();
  205. }
  206. error = false;
  207. return LLVector2(cur_val[0].asReal(), cur_val[1].asReal());
  208. }
  209. F32 LLWaterParamSet::getFloat(const std::string& param_name, bool& error)
  210. {
  211. if (!mParamValues.has(param_name))
  212. {
  213. error = true;
  214. return 0.f;
  215. }
  216. // Test to see if right type
  217. LLSD cur_val = mParamValues.get(param_name);
  218. LLSD::Type type = cur_val.type();
  219. if (type == LLSD::TypeArray && cur_val.size())
  220. {
  221. error = false;
  222. return cur_val[0].asReal();
  223. }
  224. if (type == LLSD::TypeReal)
  225. {
  226. error = false;
  227. return cur_val.asReal();
  228. }
  229. error = true;
  230. return 0.f;
  231. }
  232. ///////////////////////////////////////////////////////////////////////////////
  233. // LLWLWaterParamMgr class proper
  234. ///////////////////////////////////////////////////////////////////////////////
  235. LLWLWaterParamMgr::LLWLWaterParamMgr()
  236. : mFogColor(22.f / 255.f, 43.f / 255.f, 54.f / 255.f, 0.f, 0.f,
  237. "waterFogColor", "WaterFogColor"),
  238. mFogDensity(4, "waterFogDensity", 2),
  239. mUnderWaterFogMod(0.25, "underWaterFogMod"),
  240. mNormalScale(2.f, 2.f, 2.f, "normScale"),
  241. mFresnelScale(0.5f, "fresnelScale"),
  242. mFresnelOffset(0.4f, "fresnelOffset"),
  243. mScaleAbove(0.025f, "scaleAbove"),
  244. mScaleBelow(0.2f, "scaleBelow"),
  245. mBlurMultiplier(0.1f, "blurMultiplier"),
  246. mWave1Dir(.5f, .5f, "wave1Dir"),
  247. mWave2Dir(.5f, .5f, "wave2Dir"),
  248. mDensitySliderValue(1.f),
  249. mWaterFogKS(1.f)
  250. {
  251. }
  252. void LLWLWaterParamMgr::initClass()
  253. {
  254. llinfos << "Initializing." << llendl;
  255. loadAllPresets(LLStringUtil::null);
  256. getParamSet("Default", mCurParams);
  257. }
  258. void LLWLWaterParamMgr::loadAllPresets(const std::string& file_name)
  259. {
  260. std::string name;
  261. std::string path_name = LLWLDayCycle::getSysDir("water");
  262. llinfos << "Loading Default WindLight water settings from " << path_name
  263. << llendl;
  264. {
  265. LLDirIterator iter(path_name, "*.xml");
  266. while (iter.next(name))
  267. {
  268. name = LLURI::unescape(name.erase(name.length() - 4));
  269. LL_DEBUGS("Windlight") << "Name: " << name << LL_ENDL;
  270. loadPreset(name, false);
  271. }
  272. } // Destroys LLDirIterator iter
  273. // And repeat for user presets, note the user presets will modify any
  274. // system presets already loaded
  275. path_name = LLWLDayCycle::getUserDir("water");
  276. llinfos << "Loading User WindLight water settings from " << path_name
  277. << llendl;
  278. {
  279. LLDirIterator iter(path_name, "*.xml");
  280. while (iter.next(name))
  281. {
  282. name = LLURI::unescape(name.erase(name.length() - 4));
  283. LL_DEBUGS("Windlight") << "Name: " << name << LL_ENDL;
  284. loadPreset(name, false);
  285. }
  286. } // Destroys LLDirIterator iter
  287. }
  288. bool LLWLWaterParamMgr::loadPreset(const std::string& name, bool propagate)
  289. {
  290. std::string filename = LLWLDayCycle::makeFileName(name);
  291. // First try as if filename contains a full path
  292. std::string fullname = filename;
  293. llifstream presets_xml(fullname.c_str());
  294. if (!presets_xml.is_open())
  295. {
  296. // That failed, try loading from the user settings instead.
  297. fullname = LLWLDayCycle::getUserDir("water") + filename;
  298. presets_xml.open(fullname.c_str());
  299. }
  300. if (!presets_xml.is_open())
  301. {
  302. // That failed, try loading from the viewer installation instead.
  303. fullname = LLWLDayCycle::getSysDir("water") + filename;
  304. presets_xml.open(fullname.c_str());
  305. }
  306. if (!presets_xml.is_open())
  307. {
  308. llwarns << "Cannot find preset '" << name << "'" << llendl;
  309. return false;
  310. }
  311. llinfos << "Loading WindLight water settings from " << fullname << llendl;
  312. LLSD params_data(LLSD::emptyMap());
  313. LLPointer<LLSDParser> parser = new LLSDXMLParser();
  314. parser->parse(presets_xml, params_data, LLSDSerialize::SIZE_UNLIMITED);
  315. if (mParamList.count(name))
  316. {
  317. setParamSet(name, params_data);
  318. }
  319. else
  320. {
  321. addParamSet(name, params_data);
  322. }
  323. presets_xml.close();
  324. if (propagate)
  325. {
  326. getParamSet(name, mCurParams);
  327. propagateParameters();
  328. if (gAutomationp && name != "current parcel environment")
  329. {
  330. gAutomationp->onWindlightChange("", name, "");
  331. }
  332. }
  333. return true;
  334. }
  335. void LLWLWaterParamMgr::savePreset(const std::string& name)
  336. {
  337. // Make an empty llsd
  338. LLSD params_data(LLSD::emptyMap());
  339. // Fill it with LLSD windlight params
  340. params_data = mParamList[name].getAll();
  341. // Write to file
  342. std::string filename = LLWLDayCycle::getUserDir("water") +
  343. LLWLDayCycle::makeFileName(name);
  344. llofstream presets_xml(filename.c_str());
  345. if (presets_xml.is_open())
  346. {
  347. LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
  348. formatter->format(params_data, presets_xml,
  349. LLSDFormatter::OPTIONS_PRETTY);
  350. presets_xml.close();
  351. }
  352. else
  353. {
  354. llwarns << "Could not open file '" << filename << "' for writing."
  355. << llendl;
  356. }
  357. propagateParameters();
  358. }
  359. //static
  360. std::vector<std::string> LLWLWaterParamMgr::getLoadedPresetsList()
  361. {
  362. std::vector<std::string> result;
  363. const paramset_map_t& presets = gWLWaterParamMgr.mParamList;
  364. for (paramset_map_t::const_iterator it = presets.begin(),
  365. end = presets.end();
  366. it != end; ++it)
  367. {
  368. result.emplace_back(it->first);
  369. }
  370. return result;
  371. }
  372. void LLWLWaterParamMgr::propagateParameters()
  373. {
  374. bool err;
  375. F32 fog_density_slider =
  376. logf(mCurParams.getFloat(mFogDensity.mName, err)) /
  377. logf(mFogDensity.mBase);
  378. setDensitySliderValue(fog_density_slider);
  379. // Translate current Windlight water settings into their Extended Environment
  380. // equivalent
  381. LLSD msg;
  382. LLSettingsWater::ptr_t waterp =
  383. LLEnvSettingsWater::buildFromLegacyPreset(mCurParams.mName,
  384. mCurParams.getAll(), msg);
  385. // Apply the translated settings to the local environment
  386. if (waterp)
  387. {
  388. gEnvironment.setEnvironment(LLEnvironment::ENV_LOCAL, waterp);
  389. }
  390. gEnvironment.setSelectedEnvironment(LLEnvironment::ENV_LOCAL,
  391. LLEnvironment::TRANSITION_FAST);
  392. }
  393. bool LLWLWaterParamMgr::addParamSet(const std::string& name,
  394. LLWaterParamSet& param)
  395. {
  396. // Add a new one if not one there already
  397. if (mParamList.count(name))
  398. {
  399. return false;
  400. }
  401. mParamList[name] = param;
  402. return true;
  403. }
  404. bool LLWLWaterParamMgr::addParamSet(const std::string& name, const LLSD& param)
  405. {
  406. // Add a new one if not one there already
  407. if (mParamList.count(name))
  408. {
  409. return false;
  410. }
  411. mParamList[name].setAll(param);
  412. return true;
  413. }
  414. bool LLWLWaterParamMgr::getParamSet(const std::string& name,
  415. LLWaterParamSet& param)
  416. {
  417. // Find it and set it
  418. paramset_map_t::iterator it = mParamList.find(name);
  419. if (it != mParamList.end())
  420. {
  421. param = it->second;
  422. param.mName = name;
  423. return true;
  424. }
  425. return false;
  426. }
  427. bool LLWLWaterParamMgr::setParamSet(const std::string& name,
  428. const LLSD& param)
  429. {
  430. // Quick, non robust (we would not be working with files, but assets) check
  431. if (!param.isMap())
  432. {
  433. return false;
  434. }
  435. mParamList[name].setAll(param);
  436. return true;
  437. }
  438. bool LLWLWaterParamMgr::removeParamSet(const std::string& name,
  439. bool delete_from_disk)
  440. {
  441. paramset_map_t::iterator it = mParamList.find(name);
  442. if (it == mParamList.end())
  443. {
  444. llwarns << "No Windlight water preset named '" << name << "'"
  445. << llendl;
  446. return false;
  447. }
  448. // Remove from param list
  449. mParamList.erase(it);
  450. if (delete_from_disk)
  451. {
  452. LLDirIterator::deleteFilesInDir(LLWLDayCycle::getUserDir("water"),
  453. LLWLDayCycle::makeFileName(name).c_str());
  454. }
  455. return true;
  456. }
  457. F32 LLWLWaterParamMgr::getFogDensity()
  458. {
  459. bool err;
  460. F32 fog_density = mCurParams.getFloat("waterFogDensity", err);
  461. // Modify if we are underwater
  462. LLViewerRegion* regionp = gAgent.getRegion();
  463. const F32 water_height = regionp ? regionp->getWaterHeight() : 0.01f;
  464. F32 camera_height = gAgent.getCameraPositionAgent().mV[2];
  465. if (camera_height <= water_height)
  466. {
  467. // Raise it to the underwater fog density modifier
  468. fog_density = powf(fog_density,
  469. mCurParams.getFloat("underWaterFogMod", err));
  470. }
  471. return fog_density;
  472. }