llwlskyparammgr.cpp 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603
  1. /**
  2. * @file llwlskyparammgr.cpp
  3. * @brief Implementation for the LLWLSkyParamMgr 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 "llwlskyparammgr.h"
  34. #include "lldate.h"
  35. #include "lldir.h"
  36. #include "lldiriterator.h"
  37. #include "llfasttimer.h"
  38. #include "llgl.h"
  39. #include "llmessage.h"
  40. #include "llsdserialize.h"
  41. #include "llsdutil.h"
  42. #include "lluri.h"
  43. #include "llagent.h"
  44. #include "llenvironment.h"
  45. #include "llenvsettings.h"
  46. #include "llfloaterwindlight.h"
  47. //MK
  48. #include "mkrlinterface.h"
  49. //mk
  50. #include "llsky.h"
  51. #include "hbviewerautomation.h"
  52. #include "llviewercontrol.h"
  53. #include "llviewerparcelmgr.h"
  54. #include "llwlwaterparammgr.h"
  55. LLWLSkyParamMgr gWLSkyParamMgr;
  56. ///////////////////////////////////////////////////////////////////////////////
  57. // Structures used for Lightshare only
  58. //
  59. // Note: using the LightsharePacket structure to mirror the binary bucket data
  60. // layout is a really dirty hack since there is no guarantee about what padding
  61. // or byte alignment might be used by various C++ compilers between the various
  62. // structure members. It *happens* to work, at least for now, with gcc, clang
  63. // and Visual C++ thanks to #pragma pack which they all happen to understand...
  64. ///////////////////////////////////////////////////////////////////////////////
  65. #pragma pack(push)
  66. #pragma pack(1)
  67. struct LSColor3
  68. {
  69. F32 red;
  70. F32 green;
  71. F32 blue;
  72. };
  73. struct LSVector3
  74. {
  75. F32 X;
  76. F32 Y;
  77. F32 Z;
  78. };
  79. struct LSVector2
  80. {
  81. F32 X;
  82. F32 Y;
  83. };
  84. struct LSColor4
  85. {
  86. F32 red;
  87. F32 green;
  88. F32 blue;
  89. F32 alpha;
  90. };
  91. struct LightsharePacket
  92. {
  93. LSColor3 waterColor;
  94. F32 waterFogDensityExponent;
  95. F32 underwaterFogModifier;
  96. LSVector3 reflectionWaveletScale;
  97. F32 fresnelScale;
  98. F32 fresnelOffset;
  99. F32 refractScaleAbove;
  100. F32 refractScaleBelow;
  101. F32 blurMultiplier;
  102. LSVector2 littleWaveDirection;
  103. LSVector2 bigWaveDirection;
  104. U8 normalMapTexture[16];
  105. LSColor4 horizon;
  106. F32 hazeHorizon;
  107. LSColor4 blueDensity;
  108. F32 hazeDensity;
  109. F32 densityMultiplier;
  110. F32 distanceMultiplier;
  111. LSColor4 sunMoonColor;
  112. F32 sunMoonPosition;
  113. LSColor4 ambient;
  114. F32 eastAngle;
  115. F32 sunGlowFocus;
  116. F32 sunGlowSize;
  117. F32 sceneGamma;
  118. F32 starBrightness;
  119. LSColor4 cloudColor;
  120. LSVector3 cloudXYDensity;
  121. F32 cloudCoverage;
  122. F32 cloudScale;
  123. LSVector3 cloudDetailXYDensity;
  124. F32 cloudScrollX;
  125. F32 cloudScrollY;
  126. U16 maxAltitude;
  127. U8 cloudScrollXLock;
  128. U8 cloudScrollYLock;
  129. U8 drawClassicClouds;
  130. };
  131. #pragma pack(pop)
  132. ///////////////////////////////////////////////////////////////////////////////
  133. // LLWLParamSet class
  134. ///////////////////////////////////////////////////////////////////////////////
  135. static LLStaticHashedString sStarBrightness("star_brightness");
  136. static LLStaticHashedString sPresetNum("preset_num");
  137. static LLStaticHashedString sSunAngle("sun_angle");
  138. static LLStaticHashedString sEastAngle("east_angle");
  139. static LLStaticHashedString sEnableCloudScroll("enable_cloud_scroll");
  140. static LLStaticHashedString sCloudScrollRate("cloud_scroll_rate");
  141. static LLStaticHashedString sLightNorm("lightnorm");
  142. static LLStaticHashedString sCloudDensity("cloud_pos_density1");
  143. static LLStaticHashedString sCloudScale("cloud_scale");
  144. static LLStaticHashedString sCloudShadow("cloud_shadow");
  145. static LLStaticHashedString sDensityMultiplier("density_multiplier");
  146. static LLStaticHashedString sDistanceMultiplier("distance_multiplier");
  147. static LLStaticHashedString sHazeDensity("haze_density");
  148. static LLStaticHashedString sHazeHorizon("haze_horizon");
  149. static LLStaticHashedString sMaxY("max_y");
  150. LLWLParamSet::LLWLParamSet()
  151. : mName("Unnamed Preset"),
  152. mSunAngle(0.f),
  153. mEastAngle(0.f),
  154. mStartBrightness(0.f),
  155. mCloudScrollXOffset(0.f),
  156. mCloudScrollYOffset(0.f),
  157. mCloudScrollRateX(0.f),
  158. mCloudScrollRateY(0.f),
  159. mCloudScrollEnableX(false),
  160. mCloudScrollEnableY(false)
  161. {
  162. }
  163. void LLWLParamSet::updateHashedNames()
  164. {
  165. mParamHashedNames.clear();
  166. // Iterate through values
  167. for (LLSD::map_iterator iter = mParamValues.beginMap(),
  168. end = mParamValues.endMap();
  169. iter != end; ++iter)
  170. {
  171. mParamHashedNames.emplace_back(iter->first);
  172. }
  173. }
  174. void LLWLParamSet::setAll(const LLSD& val)
  175. {
  176. if (val.isMap())
  177. {
  178. mParamValues = val;
  179. mSunAngle = mParamValues["sun_angle"].asReal();
  180. mEastAngle = mParamValues["east_angle"].asReal();
  181. mStartBrightness = mParamValues["star_brightness"].asReal();
  182. mCloudScrollRateX = mParamValues["cloud_scroll_rate"][0].asReal();
  183. mCloudScrollRateY = mParamValues["cloud_scroll_rate"][1].asReal();
  184. mCloudScrollEnableX =
  185. mParamValues["enable_cloud_scroll"][0].asBoolean();
  186. mCloudScrollEnableY =
  187. mParamValues["enable_cloud_scroll"][1].asBoolean();
  188. }
  189. updateHashedNames();
  190. }
  191. void LLWLParamSet::setSunAngle(F32 val)
  192. {
  193. // Keep in range [0 - 2*PI]
  194. if (val > F_TWO_PI || val < 0)
  195. {
  196. F32 num = val / F_TWO_PI;
  197. num -= floor(num);
  198. val = F_TWO_PI * num;
  199. }
  200. mParamValues["sun_angle"] = val;
  201. mSunAngle = val;
  202. }
  203. void LLWLParamSet::setEastAngle(F32 val)
  204. {
  205. // Keep in range [0 - 2*PI]
  206. if (val > F_TWO_PI || val < 0)
  207. {
  208. F32 num = val / F_TWO_PI;
  209. num -= floor(num);
  210. val = F_TWO_PI * num;
  211. }
  212. mParamValues["east_angle"] = val;
  213. mEastAngle = val;
  214. }
  215. void LLWLParamSet::setStarBrightness(F32 val)
  216. {
  217. mParamValues["star_brightness"] = val;
  218. mStartBrightness = val;
  219. }
  220. void LLWLParamSet::setCloudScrollX(F32 val)
  221. {
  222. mParamValues["cloud_scroll_rate"][0] = val;
  223. mCloudScrollRateX = val;
  224. }
  225. void LLWLParamSet::setCloudScrollY(F32 val)
  226. {
  227. mParamValues["cloud_scroll_rate"][1] = val;
  228. mCloudScrollRateY = val;
  229. }
  230. void LLWLParamSet::setEnableCloudScrollX(bool val)
  231. {
  232. mParamValues["enable_cloud_scroll"][0] = val;
  233. mCloudScrollEnableX = val;
  234. }
  235. void LLWLParamSet::setEnableCloudScrollY(bool val)
  236. {
  237. mParamValues["enable_cloud_scroll"][1] = val;
  238. mCloudScrollEnableY = val;
  239. }
  240. void LLWLParamSet::set(const std::string& param_name, F32 x)
  241. {
  242. // Handle case where no array
  243. LLSD::Type type = mParamValues[param_name].type();
  244. if (type == LLSD::TypeReal)
  245. {
  246. mParamValues[param_name] = x;
  247. if (param_name == "star_brightness")
  248. {
  249. mStartBrightness = x;
  250. }
  251. }
  252. // Handle array
  253. else if (type == LLSD::TypeArray &&
  254. mParamValues[param_name][0].isReal())
  255. {
  256. mParamValues[param_name][0] = x;
  257. if (param_name == "cloud_scroll_rate")
  258. {
  259. mCloudScrollRateX = mCloudScrollRateY = x;
  260. mParamValues[param_name][1] = x;
  261. }
  262. }
  263. }
  264. void LLWLParamSet::set(const std::string& param_name, F32 x, F32 y)
  265. {
  266. mParamValues[param_name][0] = x;
  267. mParamValues[param_name][1] = y;
  268. if (param_name == "cloud_scroll_rate")
  269. {
  270. mCloudScrollRateX = x;
  271. mCloudScrollRateY = y;
  272. }
  273. }
  274. void LLWLParamSet::set(const std::string& param_name, F32 x, F32 y, F32 z)
  275. {
  276. mParamValues[param_name][0] = x;
  277. mParamValues[param_name][1] = y;
  278. mParamValues[param_name][2] = z;
  279. }
  280. void LLWLParamSet::set(const std::string& param_name, F32 x, F32 y, F32 z,
  281. F32 w)
  282. {
  283. mParamValues[param_name][0] = x;
  284. mParamValues[param_name][1] = y;
  285. mParamValues[param_name][2] = z;
  286. mParamValues[param_name][3] = w;
  287. }
  288. void LLWLParamSet::set(const std::string& param_name, const F32* val)
  289. {
  290. mParamValues[param_name][0] = val[0];
  291. mParamValues[param_name][1] = val[1];
  292. mParamValues[param_name][2] = val[2];
  293. mParamValues[param_name][3] = val[3];
  294. }
  295. void LLWLParamSet::set(const std::string& param_name, const LLVector4& val)
  296. {
  297. mParamValues[param_name][0] = val.mV[0];
  298. mParamValues[param_name][1] = val.mV[1];
  299. mParamValues[param_name][2] = val.mV[2];
  300. mParamValues[param_name][3] = val.mV[3];
  301. }
  302. void LLWLParamSet::set(const std::string& param_name, const LLColor4& val)
  303. {
  304. mParamValues[param_name][0] = val.mV[0];
  305. mParamValues[param_name][1] = val.mV[1];
  306. mParamValues[param_name][2] = val.mV[2];
  307. mParamValues[param_name][3] = val.mV[3];
  308. }
  309. LLVector4 LLWLParamSet::getVector(const std::string& param_name, bool& error)
  310. {
  311. if (!mParamValues.has(param_name))
  312. {
  313. error = true;
  314. return LLVector4();
  315. }
  316. // Test to see if right type
  317. LLSD cur_val = mParamValues.get(param_name);
  318. if (!cur_val.isArray())
  319. {
  320. error = true;
  321. return LLVector4();
  322. }
  323. error = false;
  324. return LLVector4(cur_val[0].asReal(), cur_val[1].asReal(),
  325. cur_val[2].asReal(), cur_val[3].asReal());
  326. }
  327. F32 LLWLParamSet::getFloat(const std::string& param_name, bool& error)
  328. {
  329. if (!mParamValues.has(param_name))
  330. {
  331. error = true;
  332. return 0.f;
  333. }
  334. // Test to see if right type
  335. LLSD cur_val = mParamValues.get(param_name);
  336. LLSD::Type type = cur_val.type();
  337. if (type == LLSD::TypeArray && cur_val.size())
  338. {
  339. error = false;
  340. return cur_val[0].asReal();
  341. }
  342. if (type == LLSD::TypeReal)
  343. {
  344. error = false;
  345. return cur_val.asReal();
  346. }
  347. error = true;
  348. return 0.f;
  349. }
  350. void LLWLParamSet::mix(LLWLParamSet& src, LLWLParamSet& dest, F32 weight)
  351. {
  352. #if 1
  353. // Keep cloud positions and coverage the same
  354. // *TODO: masking will do this later
  355. F32 cloud_pos1x = (F32)mParamValues["cloud_pos_density1"][0].asReal();
  356. F32 cloud_pos1y = (F32)mParamValues["cloud_pos_density1"][1].asReal();
  357. F32 cloud_pos2x = (F32)mParamValues["cloud_pos_density2"][0].asReal();
  358. F32 cloud_pos2y = (F32)mParamValues["cloud_pos_density2"][1].asReal();
  359. F32 cloud_cover = (F32)mParamValues["cloud_shadow"][0].asReal();
  360. #endif
  361. // Do the interpolation for all the ones saved as vectors and skip the
  362. // weird ones
  363. LLSD src_val;
  364. LLSD dst_val;
  365. for (LLSD::map_iterator it = mParamValues.beginMap(),
  366. end = mParamValues.endMap();
  367. it != end; ++it)
  368. {
  369. // Check params to make sure they're actually there
  370. if (src.mParamValues.has(it->first))
  371. {
  372. src_val = src.mParamValues[it->first];
  373. }
  374. else
  375. {
  376. continue;
  377. }
  378. if (dest.mParamValues.has(it->first))
  379. {
  380. dst_val = dest.mParamValues[it->first];
  381. }
  382. else
  383. {
  384. continue;
  385. }
  386. // Skip if not a vector
  387. if (!it->second.isArray())
  388. {
  389. continue;
  390. }
  391. // Only Real vectors allowed
  392. if (!it->second[0].isReal())
  393. {
  394. continue;
  395. }
  396. // Make sure all the same size
  397. if (it->second.size() != src_val.size() ||
  398. it->second.size() != dst_val.size())
  399. {
  400. continue;
  401. }
  402. // More error checking might be necessary;
  403. for (S32 i = 0, count = it->second.size(); i < count; ++i)
  404. {
  405. it->second[i] = (1.f - weight) * (F32)src_val[i].asReal() +
  406. weight * (F32)dst_val[i].asReal();
  407. }
  408. }
  409. // Now mix the extra parameters
  410. setStarBrightness((1 - weight) * (F32)src.getStarBrightness() +
  411. weight * (F32)dest.getStarBrightness());
  412. // Sun angle and east angle require some handling to make sure they go in
  413. // circles. Yes quaternions would work better.
  414. F32 src_sun_angle = src.getSunAngle();
  415. F32 dst_sun_angle = dest.getSunAngle();
  416. F32 src_east_angle = src.getEastAngle();
  417. F32 dst_east_angle = dest.getEastAngle();
  418. if (fabsf(src_sun_angle - dst_sun_angle) > F_PI)
  419. {
  420. if (src_sun_angle > dst_sun_angle)
  421. {
  422. dst_sun_angle += 2.f * F_PI;
  423. }
  424. else
  425. {
  426. src_sun_angle += 2.f * F_PI;
  427. }
  428. }
  429. if (fabsf(src_east_angle - dst_east_angle) > F_PI)
  430. {
  431. if (src_east_angle > dst_east_angle)
  432. {
  433. dst_east_angle += 2.f * F_PI;
  434. }
  435. else
  436. {
  437. src_east_angle += 2.f * F_PI;
  438. }
  439. }
  440. setSunAngle((1.f - weight) * src_sun_angle + weight * dst_sun_angle);
  441. setEastAngle((1.f - weight) * src_east_angle + weight * dst_east_angle);
  442. #if 1
  443. // Reset those cloud positions
  444. mParamValues["cloud_pos_density1"][0] = cloud_pos1x;
  445. mParamValues["cloud_pos_density1"][1] = cloud_pos1y;
  446. mParamValues["cloud_pos_density2"][0] = cloud_pos2x;
  447. mParamValues["cloud_pos_density2"][1] = cloud_pos2y;
  448. mParamValues["cloud_shadow"][0] = cloud_cover;
  449. #endif
  450. }
  451. void LLWLParamSet::updateCloudScrolling()
  452. {
  453. static LLTimer s_cloud_timer;
  454. F32 delta_t = (F32)s_cloud_timer.getElapsedTimeAndResetF64();
  455. if (mCloudScrollEnableX)
  456. {
  457. mCloudScrollXOffset += delta_t * (mCloudScrollRateX - 10.f) * 0.01f;
  458. }
  459. if (mCloudScrollEnableY)
  460. {
  461. mCloudScrollYOffset += delta_t * (mCloudScrollRateY - 10.f) * 0.01f;
  462. }
  463. }
  464. ///////////////////////////////////////////////////////////////////////////////
  465. // LLWLAnimator class
  466. ///////////////////////////////////////////////////////////////////////////////
  467. //static
  468. F32 LLWLAnimator::sSunPhase = 0.f;
  469. LLWLAnimator::LLWLAnimator()
  470. : mDayOffset(LLSettingsDay::DEFAULT_DAYOFFSET),
  471. mDayLenth(LLSettingsDay::DEFAULT_DAYLENGTH),
  472. mDayTime(0.0),
  473. mIsRunning(false)
  474. {
  475. }
  476. void LLWLAnimator::update(LLWLParamSet& cur_params)
  477. {
  478. // Do not do anything if empty
  479. if (mTimeTrack.empty())
  480. {
  481. return;
  482. }
  483. F64 cur_time = getDayTime();
  484. // Start it off
  485. mFirstIt = mTimeTrack.begin();
  486. mSecondIt = mTimeTrack.begin();
  487. ++mSecondIt;
  488. // Grab the two tween iterators
  489. while (mSecondIt != mTimeTrack.end() && cur_time > (F64)mSecondIt->first)
  490. {
  491. ++mFirstIt;
  492. ++mSecondIt;
  493. }
  494. // Scroll it around when you get to the end
  495. if (mSecondIt == mTimeTrack.end() || (F64)mFirstIt->first > cur_time)
  496. {
  497. mSecondIt = mTimeTrack.begin();
  498. mFirstIt = mTimeTrack.end();
  499. --mFirstIt;
  500. }
  501. F64 first = mFirstIt->first;
  502. F64 second = mSecondIt->first;
  503. F32 weight;
  504. if (first < second)
  505. {
  506. // Get the delta time and the proper weight
  507. weight = (F32)((cur_time - first) / (second - first));
  508. }
  509. else if (first > second)
  510. {
  511. // Handle the ends
  512. if (cur_time >= first)
  513. {
  514. // Right edge of time line
  515. weight = (F32)((cur_time - first) / (1.0 + second - first));
  516. }
  517. else
  518. {
  519. // Left edge of time line
  520. weight = (F32)((1.f + cur_time - first) / (1.0 + second - first));
  521. }
  522. }
  523. else
  524. {
  525. // Handle same as whatever the last one is
  526. weight = 1.f;
  527. }
  528. // Do the interpolation and set the parameters
  529. cur_params.mix(gWLSkyParamMgr.mParamList[mFirstIt->second],
  530. gWLSkyParamMgr.mParamList[mSecondIt->second], weight);
  531. }
  532. F64 LLWLAnimator::getDayTime()
  533. {
  534. if (!mIsRunning)
  535. {
  536. return mDayTime;
  537. }
  538. static LLCachedControl<bool> estate(gSavedSettings, "UseWLEstateTime");
  539. if (estate)
  540. {
  541. mDayTime = getEstateTime();
  542. LL_DEBUGS("Windlight") << "Linden time: " << mDayTime << LL_ENDL;
  543. return mDayTime;
  544. }
  545. if (mDayLenth <= 0)
  546. {
  547. llwarns << "Invalid day length ! Changing it to default day length."
  548. << llendl;
  549. mDayLenth = LLSettingsDay::DEFAULT_DAYLENGTH;
  550. }
  551. F64 len = F64(mDayLenth);
  552. // Get the time (changed to match EE's way to compute time)
  553. F64 time = LLTimer::getEpochSeconds() + F64(mDayOffset);
  554. mDayTime = fmod(time, len) / len;
  555. LL_DEBUGS("Windlight") << "Day time: " << mDayTime << LL_ENDL;
  556. return mDayTime;
  557. }
  558. void LLWLAnimator::setDayTime(F64 day_time)
  559. {
  560. LL_DEBUGS("Windlight") << "Day time: " << day_time << LL_ENDL;
  561. static LLCachedControl<bool> estate(gSavedSettings, "UseWLEstateTime");
  562. if (estate)
  563. {
  564. gSavedSettings.setBool("UseWLEstateTime", false);
  565. }
  566. mDayTime = llclamp(day_time, 0.0, 1.0);
  567. }
  568. // This is only called from LLEnvironment::setEnvironment(), when overriding
  569. // Windlight with EE translated settings.
  570. void LLWLAnimator::setDayRateAndOffset(S32 day_length, S32 day_offset)
  571. {
  572. static LLCachedControl<bool> estate(gSavedSettings, "UseWLEstateTime");
  573. if (day_length > 0 && estate)
  574. {
  575. gSavedSettings.setBool("UseWLEstateTime", false);
  576. mDayLenth = 0; // Force an update
  577. }
  578. if (day_length <= 0 ||
  579. (day_length == mDayLenth && day_offset == mDayOffset))
  580. {
  581. return;
  582. }
  583. mDayLenth = day_length;
  584. mDayOffset = day_offset;
  585. LL_DEBUGS("Windlight") << "Day length: " << day_length << " - Offset: "
  586. << day_offset << LL_ENDL;
  587. S64 now = LLTimer::getEpochSeconds() + day_offset;
  588. mDayTime = F64(now % day_length) / (F64)day_length;
  589. // Clamp it
  590. if (mDayTime < 0.0)
  591. {
  592. mDayTime = 0.0;
  593. }
  594. else if (mDayTime > 1.0)
  595. {
  596. mDayTime -= (F64)((S64)mDayTime);
  597. }
  598. }
  599. //static
  600. F64 LLWLAnimator::getEstateTime()
  601. {
  602. constexpr F64 ONE_THIRD = 1.0 / 3.0;
  603. F64 day_time;
  604. // We do not solve the non-linear equation that determines Sun phase, we
  605. // just linearly interpolate between the major points
  606. F32 phase = sSunPhase / F_PI;
  607. if (phase <= 5.f / 4.f)
  608. {
  609. day_time = ONE_THIRD + ONE_THIRD * (F64)phase;
  610. }
  611. else if (phase > 7.f / 4.f)
  612. {
  613. day_time = ONE_THIRD - ONE_THIRD * (F64)(2.f - phase);
  614. }
  615. else
  616. {
  617. day_time = (F64)(phase - 0.5f);
  618. if (day_time > 1.0)
  619. {
  620. day_time -= 1.0;
  621. }
  622. }
  623. return day_time;
  624. }
  625. ///////////////////////////////////////////////////////////////////////////////
  626. // LLWLDayCycle class
  627. ///////////////////////////////////////////////////////////////////////////////
  628. //static
  629. LLWLDayCycle::names_list_t LLWLDayCycle::sPresetNames;
  630. LLWLDayCycle::LLWLDayCycle()
  631. : mDayLenth(LLSettingsDay::DEFAULT_DAYLENGTH)
  632. {
  633. }
  634. //static
  635. std::string LLWLDayCycle::getSysDir(const std::string& subdir)
  636. {
  637. return gDirUtil.getFullPath(LL_PATH_APP_SETTINGS, "windlight", subdir, "");
  638. }
  639. //static
  640. std::string LLWLDayCycle::getUserDir(const std::string& subdir)
  641. {
  642. return gDirUtil.getFullPath(LL_PATH_USER_SETTINGS, "windlight", subdir,
  643. "");
  644. }
  645. //static
  646. std::string LLWLDayCycle::makeFileName(const std::string& name,
  647. bool escape_dash)
  648. {
  649. std::string filename = name;
  650. LLStringUtil::toLower(filename);
  651. size_t pos = filename.rfind(".xml");
  652. if (pos != std::string::npos && pos == filename.length() - 4)
  653. {
  654. filename = LLURI::escape(name.substr(0, pos));
  655. }
  656. else
  657. {
  658. filename = LLURI::escape(name);
  659. }
  660. if (escape_dash)
  661. {
  662. LLStringUtil::replaceString(filename, "-", "%2D");
  663. LLStringUtil::replaceString(filename, ".", "%2E");
  664. }
  665. return filename + ".xml";
  666. }
  667. //static
  668. bool LLWLDayCycle::findPresetFile(const std::string& name,
  669. const std::string& subdir,
  670. const std::string& base_path,
  671. std::string& filename, std::string& path)
  672. {
  673. // Search for file names with (filename) or without (filename2) dash
  674. // conversion...
  675. filename = makeFileName(name);
  676. std::string filename2 = makeFileName(name, false);
  677. if (!base_path.empty())
  678. {
  679. path = gDirUtil.getDirName(base_path) + LL_DIR_DELIM_STR;
  680. // Loading a sky or water settings file from a days cycle base path ?
  681. if (subdir != "days")
  682. {
  683. size_t i = path.rfind(LL_DIR_DELIM_STR "days" LL_DIR_DELIM_STR);
  684. if (i != std::string::npos)
  685. {
  686. // Remove the "days/" subdir from the path
  687. path = path.substr(0, i + 1);
  688. }
  689. }
  690. if (LLFile::isfile(path + filename))
  691. {
  692. return true;
  693. }
  694. if (LLFile::isfile(path + filename2))
  695. {
  696. filename = filename2;
  697. return true;
  698. }
  699. // If the subdir was not part of the base path, add it now and check
  700. size_t i = path.rfind(LL_DIR_DELIM_STR + subdir + LL_DIR_DELIM_STR);
  701. if (i == std::string::npos && !subdir.empty())
  702. {
  703. path += subdir + LL_DIR_DELIM_STR;
  704. if (LLFile::isfile(path + filename))
  705. {
  706. return true;
  707. }
  708. if (LLFile::isfile(path + filename2))
  709. {
  710. filename = filename2;
  711. return true;
  712. }
  713. }
  714. }
  715. path = getUserDir(subdir);
  716. if (LLFile::isfile(path + filename))
  717. {
  718. return true;
  719. }
  720. if (LLFile::isfile(path + filename2))
  721. {
  722. filename = filename2;
  723. return true;
  724. }
  725. path = getSysDir(subdir);
  726. if (LLFile::isfile(path + filename))
  727. {
  728. return true;
  729. }
  730. if (LLFile::isfile(path + filename2))
  731. {
  732. filename = filename2;
  733. return true;
  734. }
  735. path = base_path;
  736. return false;
  737. }
  738. //static
  739. void LLWLDayCycle::findPresets()
  740. {
  741. std::string name;
  742. sPresetNames.clear();
  743. std::string path_name = getSysDir("days");
  744. llinfos << "Finding WindLight day settings in " << path_name << llendl;
  745. {
  746. LLDirIterator iter(path_name, "*.xml");
  747. while (iter.next(name))
  748. {
  749. name = LLURI::unescape(name.erase(name.length() - 4));
  750. LL_DEBUGS("Windlight") << "Name: " << name << LL_ENDL;
  751. sPresetNames.insert(name);
  752. }
  753. } // Destroys LLDirIterator iter
  754. // And repeat for user presets, note the user presets will override any
  755. // system presets
  756. path_name = getUserDir("days");
  757. llinfos << "Loading User WindLight sky settings from " << path_name
  758. << llendl;
  759. {
  760. LLDirIterator iter(path_name, "*.xml");
  761. while (iter.next(name))
  762. {
  763. name = LLURI::unescape(name.erase(name.length() - 4));
  764. LL_DEBUGS("Windlight") << "Name: " << name << LL_ENDL;
  765. sPresetNames.insert(name);
  766. }
  767. } // Destroys LLDirIterator iter
  768. }
  769. //static
  770. std::vector<std::string> LLWLDayCycle::getLoadedPresetsList()
  771. {
  772. if (sPresetNames.empty())
  773. {
  774. findPresets();
  775. }
  776. std::vector<std::string> result;
  777. for (names_list_t::const_iterator it = sPresetNames.begin(),
  778. end = sPresetNames.end();
  779. it != end; ++it)
  780. {
  781. result.emplace_back(*it);
  782. }
  783. return result;
  784. }
  785. bool LLWLDayCycle::loadDayCycle(const std::string& name, bool alert)
  786. {
  787. // Clear the first few things
  788. mTimeMap.clear();
  789. // Escape the filename
  790. std::string filename = makeFileName(name);
  791. // Now load the file, first trying the user_settings sub-directory
  792. std::string fullname = getUserDir("days") + filename;
  793. llifstream day_cycle_xml(fullname.c_str());
  794. if (!day_cycle_xml.is_open())
  795. {
  796. // Try the viewer installation directory instead
  797. fullname = getSysDir("days") + filename;
  798. day_cycle_xml.open(fullname.c_str());
  799. }
  800. if (!day_cycle_xml.is_open())
  801. {
  802. llwarns << "Could not open setting file '" << name << "' for reading."
  803. << llendl;
  804. return false;
  805. }
  806. llinfos << "Loading day cycle settings from: " << fullname << llendl;
  807. // Load and parse it
  808. LLSD day_data(LLSD::emptyArray());
  809. LLPointer<LLSDParser> parser = new LLSDXMLParser();
  810. if (parser->parse(day_cycle_xml, day_data,
  811. LLSDSerialize::SIZE_UNLIMITED) == LLSDParser::PARSE_FAILURE)
  812. {
  813. llwarns << "Could not parse setting file: " << name << llendl;
  814. day_cycle_xml.close();
  815. return false;
  816. }
  817. bool success = false;
  818. LLWLParamSet pset;
  819. // Add each key
  820. for (size_t i = 0; i < day_data.size(); ++i)
  821. {
  822. // Make sure it is a two array
  823. if (day_data[i].size() != 2)
  824. {
  825. continue;
  826. }
  827. // Check each param name exists in param manager
  828. bool exists = gWLSkyParamMgr.getParamSet(day_data[i][1].asString(),
  829. pset);
  830. if (!exists && alert)
  831. {
  832. // Alert the user
  833. LLSD args;
  834. args["SKY"] = day_data[i][1].asString();
  835. gNotifications.add("WLMissingSky", args);
  836. continue;
  837. }
  838. // Then add the key
  839. addKey((F32)day_data[i][0].asReal(), day_data[i][1].asString());
  840. success = true; // At least one key was added...
  841. }
  842. day_cycle_xml.close();
  843. if (success && gAutomationp)
  844. {
  845. gAutomationp->onWindlightChange("", "", name);
  846. }
  847. return success;
  848. }
  849. void LLWLDayCycle::saveDayCycle(const std::string& name)
  850. {
  851. std::string fullname = getUserDir("days") + makeFileName(name);
  852. llofstream day_cycle_xml(fullname.c_str());
  853. if (!day_cycle_xml.is_open())
  854. {
  855. llwarns << "Could not open file '" << fullname << "' for writing."
  856. << llendl;
  857. return;
  858. }
  859. LLSD day_data(LLSD::emptyArray());
  860. for (time_map_t::const_iterator it = mTimeMap.begin(),
  861. end = mTimeMap.end();
  862. it != end; ++it)
  863. {
  864. LLSD key(LLSD::emptyArray());
  865. key.append(it->first);
  866. key.append(it->second);
  867. day_data.append(key);
  868. }
  869. LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
  870. formatter->format(day_data, day_cycle_xml, LLSDFormatter::OPTIONS_PRETTY);
  871. day_cycle_xml.close();
  872. }
  873. //static
  874. void LLWLDayCycle::removeDayCycle(const std::string& name)
  875. {
  876. LLDirIterator::deleteFilesInDir(getUserDir("days"),
  877. makeFileName(name).c_str());
  878. }
  879. void LLWLDayCycle::clearKeys()
  880. {
  881. mTimeMap.clear();
  882. }
  883. bool LLWLDayCycle::addKey(F32 new_time, const std::string& param_name)
  884. {
  885. // Negative time not allowed
  886. if (new_time < 0.f)
  887. {
  888. new_time = 0.f;
  889. }
  890. // If time not being used, add it and return true
  891. if (!mTimeMap.count(new_time))
  892. {
  893. mTimeMap[new_time] = param_name;
  894. return true;
  895. }
  896. // Otherwise, do not add, and return error
  897. return false;
  898. }
  899. bool LLWLDayCycle::changeKeyTime(F32 old_time, F32 new_time)
  900. {
  901. // Just remove and add back
  902. if (!removeKey(old_time))
  903. {
  904. return false;
  905. }
  906. return addKey(new_time, mTimeMap[old_time]);
  907. }
  908. bool LLWLDayCycle::changeKeyParam(F32 time, const std::string& name)
  909. {
  910. // Just remove and add back but make sure param exists
  911. LLWLParamSet tmp;
  912. if (!gWLSkyParamMgr.getParamSet(name, tmp))
  913. {
  914. return false;
  915. }
  916. mTimeMap[time] = name;
  917. return true;
  918. }
  919. bool LLWLDayCycle::removeKey(F32 time)
  920. {
  921. // Look for the time and if there, erase it
  922. time_map_t::iterator it = mTimeMap.find(time);
  923. if (it == mTimeMap.end())
  924. {
  925. return false;
  926. }
  927. mTimeMap.erase(it);
  928. return true;
  929. }
  930. bool LLWLDayCycle::getKey(const std::string& name, F32& key)
  931. {
  932. for (time_map_t::iterator it = mTimeMap.begin(), end = mTimeMap.end();
  933. it != end; ++it)
  934. {
  935. if (name == it->second)
  936. {
  937. key = it->first;
  938. return true;
  939. }
  940. }
  941. return false;
  942. }
  943. bool LLWLDayCycle::getKeyedParam(F32 time, LLWLParamSet& param)
  944. {
  945. // Just scroll on through till we find it
  946. time_map_t::iterator it = mTimeMap.find(time);
  947. if (it == mTimeMap.end())
  948. {
  949. // Return error if not found
  950. return false;
  951. }
  952. return gWLSkyParamMgr.getParamSet(it->second, param);
  953. }
  954. bool LLWLDayCycle::getKeyedParamName(F32 time, std::string& name)
  955. {
  956. // Just scroll on through till you find it
  957. time_map_t::iterator it = mTimeMap.find(time);
  958. if (it == mTimeMap.end())
  959. {
  960. // Return error if not found
  961. return false;
  962. }
  963. name = mTimeMap[time];
  964. return true;
  965. }
  966. ////////////////////////////////////////////////////////////////////////////////
  967. // LLWLSkyParamMgr class proper
  968. ///////////////////////////////////////////////////////////////////////////////
  969. LLWLSkyParamMgr::LLWLSkyParamMgr()
  970. : mHasLightshareOverride(false),
  971. mCurrentParamsDirty(true),
  972. // Sun Delta Terrain tweak variables.
  973. mSceneLightStrength(2.f),
  974. mWLGamma(1.f, "gamma"),
  975. mBlueHorizon(0.25f, 0.25f, 1.f, 1.f, "blue_horizon", "WLBlueHorizon"),
  976. mHazeDensity(1.f, 1.f, 1.f, 0.5f, "haze_density"),
  977. mBlueDensity(0.25f, 0.25f, 0.25f, 1.f, "blue_density", "WLBlueDensity"),
  978. mDensityMult(1.f, "density_multiplier", 1000),
  979. mHazeHorizon(1.f, 1.f, 1.f, 0.5f, "haze_horizon"),
  980. mMaxAlt(4000.f, "max_y"),
  981. // Lighting
  982. mLightnorm(0.f, 0.707f, -0.707f, 1.f, "lightnorm"),
  983. mSunlight(0.5f, 0.5f, 0.5f, 1.f, "sunlight_color", "WLSunlight"),
  984. mAmbient(0.5f, 0.75f, 1.f, 1.19f, "ambient", "WLAmbient"),
  985. mGlow(18.f, 0.f, -0.01f, 1.f, "glow"),
  986. // Clouds
  987. mCloudColor(0.5f, 0.5f, 0.5f, 1.f, "cloud_color", "WLCloudColor"),
  988. mCloudMain(0.5f, 0.5f, 0.125f, 1.f, "cloud_pos_density1"),
  989. mCloudCoverage(0.f, "cloud_shadow"),
  990. mCloudDetail(0.f, 0.f, 0.f, 1.f, "cloud_pos_density2"),
  991. mDistanceMult(1.f, "distance_multiplier"),
  992. mCloudScale(0.42f, "cloud_scale")
  993. {
  994. }
  995. void LLWLSkyParamMgr::initClass()
  996. {
  997. llinfos << "Initializing." << llendl;
  998. loadPresets();
  999. // Load the day
  1000. mDay.loadDayCycle("Default.xml");
  1001. // *HACK/FIXME: set cloud scrolling to what we want.
  1002. getParamSet("Default", mCurParams);
  1003. // Set it to noon
  1004. resetAnimator(0.5f, true);
  1005. }
  1006. void LLWLSkyParamMgr::loadPresets()
  1007. {
  1008. std::string name;
  1009. std::string path_name = LLWLDayCycle::getSysDir("skies");
  1010. llinfos << "Loading Default WindLight sky settings from " << path_name
  1011. << llendl;
  1012. {
  1013. LLDirIterator iter(path_name, "*.xml");
  1014. while (iter.next(name))
  1015. {
  1016. name = LLURI::unescape(name.erase(name.length() - 4));
  1017. LL_DEBUGS("Windlight") << "Name: " << name << LL_ENDL;
  1018. loadPreset(name, false);
  1019. }
  1020. } // Destroys LLDirIterator iter
  1021. // And repeat for user presets, note the user presets will modify any
  1022. // system presets already loaded
  1023. path_name = LLWLDayCycle::getUserDir("skies");
  1024. llinfos << "Loading User WindLight sky settings from " << path_name
  1025. << llendl;
  1026. {
  1027. LLDirIterator iter(path_name, "*.xml");
  1028. while (iter.next(name))
  1029. {
  1030. name = LLURI::unescape(name.erase(name.length() - 4));
  1031. LL_DEBUGS("Windlight") << "Name: " << name << LL_ENDL;
  1032. loadPreset(name, false);
  1033. }
  1034. } // Destroys LLDirIterator iter
  1035. }
  1036. bool LLWLSkyParamMgr::loadPreset(const std::string& name, bool propagate)
  1037. {
  1038. std::string filename = LLWLDayCycle::makeFileName(name);
  1039. // First try as if filename contains a full path
  1040. std::string fullname = filename;
  1041. llifstream presets_xml(fullname.c_str());
  1042. if (!presets_xml.is_open())
  1043. {
  1044. // That failed, try loading from the user settings instead.
  1045. fullname = LLWLDayCycle::getUserDir("skies") + filename;
  1046. presets_xml.open(fullname.c_str());
  1047. }
  1048. if (!presets_xml.is_open())
  1049. {
  1050. // That failed, try loading from the viewer installation instead.
  1051. fullname = LLWLDayCycle::getSysDir("skies") + filename;
  1052. presets_xml.open(fullname.c_str());
  1053. }
  1054. if (presets_xml.is_open())
  1055. {
  1056. llinfos << "Loading WindLight sky setting from " << fullname << llendl;
  1057. LLSD params_data(LLSD::emptyMap());
  1058. LLPointer<LLSDParser> parser = new LLSDXMLParser();
  1059. parser->parse(presets_xml, params_data, LLSDSerialize::SIZE_UNLIMITED);
  1060. if (mParamList.count(name))
  1061. {
  1062. setParamSet(name, params_data);
  1063. }
  1064. else
  1065. {
  1066. addParamSet(name, params_data);
  1067. }
  1068. presets_xml.close();
  1069. }
  1070. else
  1071. {
  1072. llwarns << "Cannot find preset '" << name << "'" << llendl;
  1073. return false;
  1074. }
  1075. //MK
  1076. if (gRLenabled)
  1077. {
  1078. gRLInterface.setLastLoadedPreset(name);
  1079. }
  1080. //mk
  1081. if (propagate)
  1082. {
  1083. getParamSet(name, mCurParams);
  1084. propagateParameters();
  1085. if (gAutomationp && name != "current parcel environment")
  1086. {
  1087. gAutomationp->onWindlightChange(name, "", "");
  1088. }
  1089. }
  1090. return true;
  1091. }
  1092. void LLWLSkyParamMgr::savePreset(const std::string& name)
  1093. {
  1094. // Make an empty llsd
  1095. LLSD params_data(LLSD::emptyMap());
  1096. // Fill it with LLSD windlight params
  1097. params_data = mParamList[name].getAll();
  1098. // Write to file
  1099. std::string filename = LLWLDayCycle::getUserDir("skies") +
  1100. LLWLDayCycle::makeFileName(name);
  1101. llofstream presets_xml(filename.c_str());
  1102. if (presets_xml.is_open())
  1103. {
  1104. LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
  1105. formatter->format(params_data, presets_xml,
  1106. LLSDFormatter::OPTIONS_PRETTY);
  1107. presets_xml.close();
  1108. }
  1109. else
  1110. {
  1111. llwarns << "Could not open file '" << filename << "' for writing."
  1112. << llendl;
  1113. }
  1114. propagateParameters();
  1115. }
  1116. //static
  1117. std::vector<std::string> LLWLSkyParamMgr::getLoadedPresetsList()
  1118. {
  1119. std::vector<std::string> result;
  1120. const paramset_map_t& presets = gWLSkyParamMgr.mParamList;
  1121. for (paramset_map_t::const_iterator it = presets.begin(),
  1122. end = presets.end();
  1123. it != end; ++it)
  1124. {
  1125. result.emplace_back(it->first);
  1126. }
  1127. return result;
  1128. }
  1129. void LLWLSkyParamMgr::propagateParameters()
  1130. {
  1131. // Set the sun direction from SunAngle and EastAngle
  1132. F32 theta = mCurParams.getEastAngle();
  1133. F32 phi = mCurParams.getSunAngle();
  1134. F32 sin_phi = sinf(phi);
  1135. F32 cos_phi = cosf(phi);
  1136. LLVector4 sun_dir;
  1137. sun_dir.mV[0] = -sinf(theta) * cos_phi;
  1138. sun_dir.mV[1] = sin_phi;
  1139. sun_dir.mV[2] = cosf(theta) * cos_phi;
  1140. sun_dir.mV[3] = 0.f;
  1141. // Is the normal from the Sun or the Moon ?
  1142. if (sin_phi >= 0.f)
  1143. {
  1144. mLightDir = sun_dir;
  1145. }
  1146. else if (sin_phi >= NIGHTTIME_ELEVATION_COS)
  1147. {
  1148. // Clamp v1 to 0 so Sun never points up and causes weirdness on some
  1149. // machines
  1150. LLVector3 vec(sun_dir.mV[0], 0.f, sun_dir.mV[2]);
  1151. vec.normalize();
  1152. mLightDir = LLVector4(vec, 0.f);
  1153. }
  1154. else
  1155. {
  1156. // *HACK: Sun and Moon are always on opposite side of SL...
  1157. mLightDir = -sun_dir;
  1158. }
  1159. // Calculate the clamp lightnorm for sky (to prevent ugly banding in sky
  1160. // when haze goes below the horizon
  1161. mClampedLightDir = sun_dir;
  1162. if (mClampedLightDir.mV[1] < -0.1f)
  1163. {
  1164. mClampedLightDir.mV[1] = -0.1f;
  1165. }
  1166. mCurParams.set("lightnorm", mLightDir);
  1167. // Get the cfr version of the Sun's direction
  1168. LLVector3 cfr_sun_dir(sun_dir.mV[2], sun_dir.mV[0], sun_dir.mV[1]);
  1169. // Set direction, overriding Sun position
  1170. gSky.setOverrideSun(true);
  1171. gSky.setSunDirection(cfr_sun_dir, LLVector3::zero);
  1172. // Translate current Windlight sky settings into their Extended Environment
  1173. // equivalent
  1174. LLSD msg;
  1175. LLSettingsSky::ptr_t skyp =
  1176. LLEnvSettingsSky::buildFromLegacyPreset(mCurParams.mName,
  1177. mCurParams.getAll(), msg);
  1178. // Apply the translated settings to the local environment
  1179. if (skyp)
  1180. {
  1181. gEnvironment.setEnvironment(LLEnvironment::ENV_LOCAL, skyp);
  1182. }
  1183. gEnvironment.setSelectedEnvironment(LLEnvironment::ENV_LOCAL,
  1184. LLEnvironment::TRANSITION_FAST);
  1185. }
  1186. void LLWLSkyParamMgr::animate(bool enable)
  1187. {
  1188. mAnimator.mIsRunning = enable;
  1189. if (enable)
  1190. {
  1191. gSky.setOverrideSun(false);
  1192. }
  1193. static LLCachedControl<bool> parcel_env(gSavedSettings,
  1194. "UseParcelEnvironment");
  1195. if (enable && parcel_env)
  1196. {
  1197. gSavedSettings.setBool("UseParcelEnvironment", false);
  1198. }
  1199. static LLCachedControl<bool> local_env(gSavedSettings,
  1200. "UseLocalEnvironment");
  1201. if (enable && local_env)
  1202. {
  1203. gSavedSettings.setBool("UseLocalEnvironment", false);
  1204. }
  1205. }
  1206. void LLWLSkyParamMgr::resetAnimator(F32 cur_time, bool run)
  1207. {
  1208. mAnimator.setTrack(mDay.mTimeMap, mDay.mDayLenth, cur_time, run);
  1209. }
  1210. bool LLWLSkyParamMgr::addParamSet(const std::string& name,
  1211. LLWLParamSet& param)
  1212. {
  1213. // Add a new one if not one there already
  1214. if (mParamList.count(name))
  1215. {
  1216. return false;
  1217. }
  1218. LL_DEBUGS("Windlight") << "Name: " << name << LL_ENDL;
  1219. mParamList[name] = param;
  1220. return true;
  1221. }
  1222. bool LLWLSkyParamMgr::addParamSet(const std::string& name, const LLSD& param)
  1223. {
  1224. // Add a new one if not one there already
  1225. if (mParamList.count(name))
  1226. {
  1227. return false;
  1228. }
  1229. LL_DEBUGS("Windlight") << "Name: " << name << LL_ENDL;
  1230. mParamList[name].setAll(param);
  1231. return true;
  1232. }
  1233. bool LLWLSkyParamMgr::getParamSet(const std::string& name, LLWLParamSet& param)
  1234. {
  1235. // Find it and set it
  1236. paramset_map_t::iterator it = mParamList.find(name);
  1237. if (it != mParamList.end())
  1238. {
  1239. LL_DEBUGS("Windlight") << "Name: " << name << LL_ENDL;
  1240. param = it->second;
  1241. param.mName = name;
  1242. return true;
  1243. }
  1244. return false;
  1245. }
  1246. bool LLWLSkyParamMgr::setParamSet(const std::string& name, const LLSD& param)
  1247. {
  1248. // Quick, non robust (we would not be working with files, but assets) check
  1249. if (param.isMap())
  1250. {
  1251. LL_DEBUGS("Windlight") << "Name: " << name << LL_ENDL;
  1252. mParamList[name].setAll(param);
  1253. return true;
  1254. }
  1255. return false;
  1256. }
  1257. bool LLWLSkyParamMgr::removeParamSet(const std::string& name,
  1258. bool delete_from_disk)
  1259. {
  1260. paramset_map_t::iterator it = mParamList.find(name);
  1261. if (it == mParamList.end())
  1262. {
  1263. llwarns << "No Windlight sky preset named '" << name << "'" << llendl;
  1264. return false;
  1265. }
  1266. LL_DEBUGS("Windlight") << "Name: " << name << LL_ENDL;
  1267. // Remove from param list
  1268. mParamList.erase(it);
  1269. // Remove all references
  1270. F32 key;
  1271. bool stat = true;
  1272. do
  1273. {
  1274. // Get it...
  1275. stat = mDay.getKey(name, key);
  1276. if (!stat)
  1277. {
  1278. break;
  1279. }
  1280. // And remove
  1281. stat = mDay.removeKey(key);
  1282. }
  1283. while (stat);
  1284. if (delete_from_disk)
  1285. {
  1286. LLDirIterator::deleteFilesInDir(LLWLDayCycle::getUserDir("skies"),
  1287. LLWLDayCycle::makeFileName(name).c_str());
  1288. }
  1289. return true;
  1290. }
  1291. void LLWLSkyParamMgr::processLightshareMessage(LLMessageSystem* msg)
  1292. {
  1293. static LLCachedControl<bool> enabled(gSavedSettings, "LightshareEnabled");
  1294. if (!enabled)
  1295. {
  1296. LL_DEBUGS("Windlight") << "Mesage received from sim, but Lightshare is disabled."
  1297. << LL_ENDL;
  1298. return;
  1299. }
  1300. static const char wdefault[] =
  1301. "\x00\x00\x80\x40\x00\x00\x18\x42\x00\x00\x80\x42\x00\x00\x80\x40\x00\x00\x80\x3e\x00\x00\x00\x40\x00\x00\x00\x40\x00\x00\x00\x40\xcd\xcc\xcc\x3e\x00\x00\x00\x3f\x8f\xc2\xf5\x3c\xcd\xcc\x4c\x3e\x0a\xd7\x23\x3d\x66\x66\x86\x3f\x3d\x0a\xd7\xbe\x7b\x14\x8e\x3f\xe1\x7a\x94\xbf\x82\x2d\xed\x49\x9a\x6c\xf6\x1c\xcb\x89\x6d\xf5\x4f\x42\xcd\xf4\x00\x00\x80\x3e\x00\x00\x80\x3e\x0a\xd7\xa3\x3e\x0a\xd7\xa3\x3e\x5c\x8f\x42\x3e\x8f\xc2\xf5\x3d\xae\x47\x61\x3e\x5c\x8f\xc2\x3e\x5c\x8f\xc2\x3e\x33\x33\x33\x3f\xec\x51\x38\x3e\xcd\xcc\x4c\x3f\x8f\xc2\x75\x3e\xb8\x1e\x85\x3e\x9a\x99\x99\x3e\x9a\x99\x99\x3e\xd3\x4d\xa2\x3e\x33\x33\xb3\x3e\x33\x33\xb3\x3e\x33\x33\xb3\x3e\x33\x33\xb3\x3e\x00\x00\x00\x00\xcd\xcc\xcc\x3d\x00\x00\xe0\x3f\x00\x00\x80\x3f\x00\x00\x00\x00\x85\xeb\xd1\x3e\x85\xeb\xd1\x3e\x85\xeb\xd1\x3e\x85\xeb\xd1\x3e\x00\x00\x80\x3f\x14\xae\x07\x3f\x00\x00\x80\x3f\x71\x3d\x8a\x3e\x3d\x0a\xd7\x3e\x00\x00\x80\x3f\x14\xae\x07\x3f\x8f\xc2\xf5\x3d\xcd\xcc\x4c\x3e\x0a\xd7\x23\x3c\x45\x06\x00";
  1302. char buf[250];
  1303. LLWaterParamSet water;
  1304. LLWLParamSet wl;
  1305. std::string uuid_str;
  1306. S32 count = msg->getNumberOfBlocksFast(_PREHASH_ParamList);
  1307. for (S32 i = 0; i < count; ++i)
  1308. {
  1309. S32 size = msg->getSizeFast(_PREHASH_ParamList, i, _PREHASH_Parameter);
  1310. if (size < 0)
  1311. {
  1312. llwarns << "Received invalid Lightshare data packet with size "
  1313. << size << " in param list #" << i << llendl;
  1314. continue;
  1315. }
  1316. llinfos << "Applying Lightshare settings list #" << i << llendl;
  1317. mHasLightshareOverride = true;
  1318. msg->getBinaryDataFast(_PREHASH_ParamList, _PREHASH_Parameter, buf,
  1319. size, i, 249);
  1320. if (!memcmp(wdefault, buf, sizeof(wdefault)))
  1321. {
  1322. LL_DEBUGS("Windlight") << "LightShare matches default" << LL_ENDL;
  1323. processLightshareReset();
  1324. return;
  1325. }
  1326. LightsharePacket* pkt = (LightsharePacket*)buf;
  1327. // Apply water parameters
  1328. gWLWaterParamMgr.getParamSet("Default", water);
  1329. water.set("waterFogColor", pkt->waterColor.red / 256.f,
  1330. pkt->waterColor.green / 256.f, pkt->waterColor.blue / 256.f);
  1331. water.set("waterFogDensity", powf(2.f, pkt->waterFogDensityExponent));
  1332. water.set("underWaterFogMod", pkt->underwaterFogModifier);
  1333. water.set("normScale", pkt->reflectionWaveletScale.X,
  1334. pkt->reflectionWaveletScale.Y,
  1335. pkt->reflectionWaveletScale.Z);
  1336. water.set("fresnelScale", pkt->fresnelScale);
  1337. water.set("fresnelOffset", pkt->fresnelOffset);
  1338. water.set("scaleAbove", pkt->refractScaleAbove);
  1339. water.set("scaleBelow", pkt->refractScaleBelow);
  1340. water.set("blurMultiplier", pkt->blurMultiplier);
  1341. water.set("wave1Dir", pkt->littleWaveDirection.X,
  1342. pkt->littleWaveDirection.Y);
  1343. water.set("wave2Dir", pkt->bigWaveDirection.X,
  1344. pkt->bigWaveDirection.Y);
  1345. uuid_str =
  1346. llformat("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
  1347. pkt->normalMapTexture[0], pkt->normalMapTexture[1],
  1348. pkt->normalMapTexture[2], pkt->normalMapTexture[3],
  1349. pkt->normalMapTexture[4], pkt->normalMapTexture[5],
  1350. pkt->normalMapTexture[6], pkt->normalMapTexture[7],
  1351. pkt->normalMapTexture[8], pkt->normalMapTexture[9],
  1352. pkt->normalMapTexture[10], pkt->normalMapTexture[11],
  1353. pkt->normalMapTexture[12], pkt->normalMapTexture[13],
  1354. pkt->normalMapTexture[14], pkt->normalMapTexture[15]);
  1355. gWLWaterParamMgr.mCurParams = water;
  1356. gWLWaterParamMgr.setNormalMapID(LLUUID(uuid_str));
  1357. gWLWaterParamMgr.propagateParameters();
  1358. // Apply Windlight parameters
  1359. mAnimator.mIsRunning = false;
  1360. getParamSet("Default", wl);
  1361. wl.setSunAngle(F_TWO_PI * pkt->sunMoonPosition);
  1362. wl.setEastAngle(F_TWO_PI * pkt->eastAngle);
  1363. wl.set("sunlight_color", pkt->sunMoonColor.red * 3.f,
  1364. pkt->sunMoonColor.green * 3.f, pkt->sunMoonColor.blue * 3.f,
  1365. pkt->sunMoonColor.alpha * 3.f);
  1366. wl.set("ambient", pkt->ambient.red * 3.f, pkt->ambient.green * 3.f,
  1367. pkt->ambient.blue * 3.f, pkt->ambient.alpha * 3.f);
  1368. wl.set("blue_horizon", pkt->horizon.red * 2.f,
  1369. pkt->horizon.green * 2.f, pkt->horizon.blue * 2.f,
  1370. pkt->horizon.alpha * 2.f);
  1371. wl.set("blue_density", pkt->blueDensity.red * 2.f,
  1372. pkt->blueDensity.green * 2.f, pkt->blueDensity.blue * 2.f,
  1373. pkt->blueDensity.alpha * 2.f);
  1374. wl.set("haze_horizon", pkt->hazeHorizon, pkt->hazeHorizon,
  1375. pkt->hazeHorizon, 1.f);
  1376. wl.set("haze_density", pkt->hazeDensity, pkt->hazeDensity,
  1377. pkt->hazeDensity, 1.f);
  1378. wl.set("cloud_shadow", pkt->cloudCoverage, pkt->cloudCoverage,
  1379. pkt->cloudCoverage, pkt->cloudCoverage);
  1380. wl.set("density_multiplier", pkt->densityMultiplier / 1000.f);
  1381. wl.set("distance_multiplier", pkt->distanceMultiplier,
  1382. pkt->distanceMultiplier, pkt->distanceMultiplier,
  1383. pkt->distanceMultiplier);
  1384. wl.set("max_y",(F32)pkt->maxAltitude);
  1385. wl.set("cloud_color", pkt->cloudColor.red, pkt->cloudColor.green,
  1386. pkt->cloudColor.blue, pkt->cloudColor.alpha);
  1387. wl.set("cloud_pos_density1", pkt->cloudXYDensity.X,
  1388. pkt->cloudXYDensity.Y, pkt->cloudXYDensity.Z);
  1389. wl.set("cloud_pos_density2", pkt->cloudDetailXYDensity.X,
  1390. pkt->cloudDetailXYDensity.Y, pkt->cloudDetailXYDensity.Z);
  1391. wl.set("cloud_scale", pkt->cloudScale, 0.f, 0.f, 1.f);
  1392. wl.set("gamma", pkt->sceneGamma, pkt->sceneGamma, pkt->sceneGamma, 0.f);
  1393. wl.set("glow", 40.f - 20.f * pkt->sunGlowSize, 0.f,
  1394. -5.f * pkt->sunGlowFocus);
  1395. wl.setCloudScrollX(pkt->cloudScrollX + 10.f);
  1396. wl.setCloudScrollY(pkt->cloudScrollY + 10.f);
  1397. wl.setEnableCloudScrollX(!pkt->cloudScrollXLock);
  1398. wl.setEnableCloudScrollY(!pkt->cloudScrollYLock);
  1399. wl.setStarBrightness(pkt->starBrightness);
  1400. mCurParams = wl;
  1401. propagateParameters();
  1402. }
  1403. }
  1404. void LLWLSkyParamMgr::processLightshareReset(bool force)
  1405. {
  1406. static LLCachedControl<bool> enabled(gSavedSettings, "LightshareEnabled");
  1407. if (!force && !enabled)
  1408. {
  1409. LL_DEBUGS("Windlight") << "Mesage received from sim, but Lightshare is disabled."
  1410. << LL_ENDL;
  1411. return;
  1412. }
  1413. if (mHasLightshareOverride)
  1414. {
  1415. llinfos << "Resetting Lightshare." << llendl;
  1416. mHasLightshareOverride = false;
  1417. getParamSet("Default", mCurParams);
  1418. animate();
  1419. }
  1420. }