llenvsettings.cpp 56 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987
  1. /**
  2. * @file llenvsettings.cpp
  3. * @brief Subclasses for viewer specific settings behaviors.
  4. *
  5. * $LicenseInfo:firstyear=2018&license=viewergpl$
  6. *
  7. * Copyright (c) 2002-2019, Linden Research, Inc.
  8. * Copyright (c) 2019-2023, Henri Beauchamp.
  9. *
  10. * Second Life Viewer Source Code
  11. * The source code in this file ("Source Code") is provided by Linden Lab
  12. * to you under the terms of the GNU General Public License, version 2.0
  13. * ("GPL"), unless you have obtained a separate licensing agreement
  14. * ("Other License"), formally executed by you and Linden Lab. Terms of
  15. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  16. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  17. *
  18. * There are special exceptions to the terms and conditions of the GPL as
  19. * it is applied to this Source Code. View the full text of the exception
  20. * in the file doc/FLOSS-exception.txt in this software distribution, or
  21. * online at
  22. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  23. *
  24. * By copying, modifying or distributing this software, you acknowledge
  25. * that you have read and understood your obligations described above,
  26. * and agree to abide by those obligations.
  27. *
  28. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  29. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  30. * COMPLETENESS OR PERFORMANCE.
  31. * $/LicenseInfo$
  32. */
  33. #include "llviewerprecompiledheaders.h"
  34. #include "llenvsettings.h"
  35. #include "imageids.h"
  36. #include "llassetstorage.h"
  37. #include "lldir.h"
  38. #include "llfilesystem.h"
  39. #include "llnotifications.h"
  40. #include "llpermissions.h"
  41. #include "llsdutil.h"
  42. #include "lltrans.h"
  43. #include "lluri.h"
  44. #include "llagent.h"
  45. #include "lldrawpoolwater.h"
  46. #include "llenvironment.h"
  47. #include "llfloaterperms.h"
  48. #include "llinventorymodel.h"
  49. #include "llpipeline.h"
  50. #include "llsky.h"
  51. #include "llviewerassetupload.h"
  52. #include "hbviewerautomation.h"
  53. #include "llviewercamera.h"
  54. #include "llviewercontrol.h"
  55. #include "llviewerdisplay.h" // For gCubeSnapshot
  56. #include "llviewerinventory.h"
  57. #include "llviewerregion.h"
  58. #include "llviewershadermgr.h"
  59. #include "llwlskyparammgr.h"
  60. #include "llwlwaterparammgr.h"
  61. #include "llworld.h"
  62. constexpr F32 WATER_FOG_LIGHT_CLAMP = 0.3f;
  63. // Helper class
  64. class LLSettingsInventoryCB final : public LLInventoryCallback
  65. {
  66. public:
  67. LLSettingsInventoryCB(LLSettingsBase::ptr_t settings,
  68. LLEnvSettingsBase::inv_result_fn cb)
  69. : mSettings(settings),
  70. mCallback(cb)
  71. {
  72. }
  73. void fire(const LLUUID& inv_item_id) override
  74. {
  75. LLEnvSettingsBase::onInventoryItemCreated(inv_item_id, mSettings,
  76. mCallback);
  77. }
  78. private:
  79. LLSettingsBase::ptr_t mSettings;
  80. LLEnvSettingsBase::inv_result_fn mCallback;
  81. };
  82. ///////////////////////////////////////////////////////////////////////////////
  83. // LLEnvSettingsBase class
  84. ///////////////////////////////////////////////////////////////////////////////
  85. //static
  86. void LLEnvSettingsBase::createNewInventoryItem(LLSettingsType::EType stype,
  87. const LLUUID& parent_id,
  88. inv_result_fn callback)
  89. {
  90. // *TODO: implement Settings default permissions ?
  91. U32 next_owner_perm = LLFloaterPerms::getNextOwnerPerms();
  92. next_owner_perm |= PERM_COPY;
  93. if (!gAgent.hasInventorySettings())
  94. {
  95. gNotifications.add("NoEnvironmentSettings");
  96. return;
  97. }
  98. LLPointer<LLInventoryCallback> cb =
  99. new LLSettingsInventoryCB(LLSettingsBase::ptr_t(), callback);
  100. create_inventory_item(parent_id, LLTransactionID::tnull,
  101. LLSettingsType::getDefaultName(stype), "",
  102. LLAssetType::AT_SETTINGS,
  103. LLInventoryType::IT_SETTINGS, (U8)stype,
  104. next_owner_perm, cb);
  105. }
  106. //static
  107. void LLEnvSettingsBase::createInventoryItem(const LLSettingsBase::ptr_t& settings,
  108. const LLUUID& parent_id,
  109. const std::string& settings_name,
  110. inv_result_fn callback)
  111. {
  112. U32 next_owner_perm = LLPermissions::DEFAULT.getMaskNextOwner();
  113. createInventoryItem(settings, next_owner_perm, parent_id, settings_name,
  114. callback);
  115. }
  116. //static
  117. void LLEnvSettingsBase::createInventoryItem(const LLSettingsBase::ptr_t& settings,
  118. U32 next_owner_perm,
  119. const LLUUID& parent_id,
  120. std::string settings_name,
  121. inv_result_fn callback)
  122. {
  123. if (!gAgent.hasInventorySettings())
  124. {
  125. gNotifications.add("NoEnvironmentSettings");
  126. return;
  127. }
  128. LLTransactionID tid;
  129. tid.generate();
  130. if (settings_name.empty())
  131. {
  132. settings_name = settings->getName();
  133. }
  134. LLPointer<LLInventoryCallback> cb = new LLSettingsInventoryCB(settings,
  135. callback);
  136. create_inventory_item(parent_id, tid, settings_name, "",
  137. LLAssetType::AT_SETTINGS,
  138. LLInventoryType::IT_SETTINGS,
  139. (U8)settings->getSettingsTypeValue(),
  140. next_owner_perm, cb);
  141. }
  142. //static
  143. void LLEnvSettingsBase::onInventoryItemCreated(const LLUUID& inv_id,
  144. LLSettingsBase::ptr_t settings,
  145. inv_result_fn callback)
  146. {
  147. LLViewerInventoryItem* itemp = gInventory.getItem(inv_id);
  148. if (itemp)
  149. {
  150. LLPermissions perm = itemp->getPermissions();
  151. if (perm.getMaskEveryone() != PERM_COPY)
  152. {
  153. perm.setMaskEveryone(PERM_COPY);
  154. itemp->setPermissions(perm);
  155. itemp->updateServer(false);
  156. }
  157. }
  158. if (!settings)
  159. {
  160. // The item was created as new with no settings passed in. The
  161. // simulator should have given it the default for the type...
  162. // Check Id; no need to upload asset.
  163. LLUUID asset_id;
  164. if (itemp)
  165. {
  166. asset_id = itemp->getAssetUUID();
  167. }
  168. if (callback)
  169. {
  170. callback(asset_id, inv_id, LLUUID::null, LLSD());
  171. }
  172. return;
  173. }
  174. // We may need to update some inventory stuff here...
  175. updateInventoryItem(settings, inv_id, callback, false);
  176. }
  177. //static
  178. void LLEnvSettingsBase::updateInventoryItem(const LLSettingsBase::ptr_t& settings,
  179. const LLUUID& inv_item_id,
  180. inv_result_fn callback,
  181. bool update_name)
  182. {
  183. std::string cap_url =
  184. gAgent.getRegionCapability("UpdateSettingsAgentInventory");
  185. if (cap_url.empty())
  186. {
  187. llwarns << "No UpdateSettingsAgentInventory capability available. Cannot save setting."
  188. << llendl;
  189. return;
  190. }
  191. if (!gAgent.hasInventorySettings())
  192. {
  193. gNotifications.add("NoEnvironmentSettings");
  194. return;
  195. }
  196. LLViewerInventoryItem* itemp = gInventory.getItem(inv_item_id);
  197. if (itemp)
  198. {
  199. bool need_update = false;
  200. LLPointer<LLViewerInventoryItem> new_itemp =
  201. new LLViewerInventoryItem(itemp);
  202. if (settings->getFlag(LLSettingsBase::FLAG_NOTRANS) &&
  203. new_itemp->getPermissions().allowTransferBy(gAgentID))
  204. {
  205. LLPermissions perm(itemp->getPermissions());
  206. perm.setBaseBits(LLUUID::null, false, PERM_TRANSFER);
  207. perm.setOwnerBits(LLUUID::null, false, PERM_TRANSFER);
  208. new_itemp->setPermissions(perm);
  209. need_update = true;
  210. }
  211. if (update_name && settings->getName() != new_itemp->getName())
  212. {
  213. new_itemp->rename(settings->getName());
  214. settings->setName(new_itemp->getName()); // Account for corrections
  215. need_update = true;
  216. }
  217. if (need_update)
  218. {
  219. new_itemp->updateServer(false);
  220. gInventory.updateItem(new_itemp);
  221. gInventory.notifyObservers();
  222. }
  223. }
  224. std::stringstream buffer;
  225. LLSD settingdata(settings->getSettings());
  226. LLSDSerialize::serialize(settingdata, buffer,
  227. LLSDSerialize::LLSD_NOTATION);
  228. LLResourceUploadInfo::ptr_t info =
  229. std::make_shared<LLBufferedAssetUploadInfo>(inv_item_id,
  230. LLAssetType::AT_SETTINGS,
  231. buffer.str(),
  232. boost::bind(&LLEnvSettingsBase::onAgentAssetUploadComplete,
  233. _1, _2, _3, _4,
  234. settings,
  235. callback));
  236. LLViewerAssetUpload::enqueueInventoryUpload(cap_url, info);
  237. }
  238. //static
  239. void LLEnvSettingsBase::updateInventoryItem(const LLSettingsBase::ptr_t& settings,
  240. const LLUUID& object_id,
  241. const LLUUID& inv_item_id,
  242. inv_result_fn callback)
  243. {
  244. std::string cap_url =
  245. gAgent.getRegionCapability("UpdateSettingsAgentInventory");
  246. if (cap_url.empty())
  247. {
  248. llwarns << "No UpdateSettingsAgentInventory capability available. Cannot save setting."
  249. << llendl;
  250. return;
  251. }
  252. if (!gAgent.hasInventorySettings())
  253. {
  254. gNotifications.add("NoEnvironmentSettings");
  255. return;
  256. }
  257. std::stringstream buffer;
  258. LLSD settingdata(settings->getSettings());
  259. LLSDSerialize::serialize(settingdata, buffer,
  260. LLSDSerialize::LLSD_NOTATION);
  261. LLResourceUploadInfo::ptr_t info =
  262. std::make_shared<LLBufferedAssetUploadInfo>(object_id, inv_item_id,
  263. LLAssetType::AT_SETTINGS,
  264. buffer.str(),
  265. boost::bind(&LLEnvSettingsBase::onTaskAssetUploadComplete,
  266. _1, _2, _3, _4,
  267. settings,
  268. callback));
  269. LLViewerAssetUpload::enqueueInventoryUpload(cap_url, info);
  270. }
  271. //static
  272. void LLEnvSettingsBase::onAgentAssetUploadComplete(LLUUID item_id,
  273. LLUUID new_asset_id,
  274. LLUUID new_item_id,
  275. LLSD response,
  276. LLSettingsBase::ptr_t psettings,
  277. inv_result_fn callback)
  278. {
  279. llinfos << "Item Id: " << item_id << " - New asset Id: " << new_asset_id
  280. << " - New item Id: " << new_item_id << " - Response: " << response
  281. << llendl;
  282. psettings->setAssetId(new_asset_id);
  283. if (callback)
  284. {
  285. callback(new_asset_id, item_id, LLUUID::null, response);
  286. }
  287. }
  288. //static
  289. void LLEnvSettingsBase::onTaskAssetUploadComplete(LLUUID item_id,
  290. LLUUID task_id,
  291. LLUUID new_asset_id,
  292. LLSD response,
  293. LLSettingsBase::ptr_t settings,
  294. inv_result_fn callback)
  295. {
  296. llinfos << "Item Id: " << item_id << " - Task Id: " << task_id
  297. << " - New asset Id: " << new_asset_id << " - Response: "
  298. << response << " - Upload to task complete." << llendl;
  299. settings->setAssetId(new_asset_id);
  300. if (callback)
  301. {
  302. callback(new_asset_id, item_id, task_id, response);
  303. }
  304. }
  305. struct CallbackPtrStorage
  306. {
  307. LLEnvSettingsBase::asset_download_fn callback;
  308. };
  309. //static
  310. void LLEnvSettingsBase::getSettingsAsset(const LLUUID& asset_id,
  311. asset_download_fn callback)
  312. {
  313. CallbackPtrStorage* storage = new CallbackPtrStorage;
  314. storage->callback = callback;
  315. gAssetStoragep->getAssetData(asset_id, LLAssetType::AT_SETTINGS,
  316. onAssetDownloadComplete, (void*)storage,
  317. true);
  318. }
  319. //static
  320. void LLEnvSettingsBase::onAssetDownloadComplete(const LLUUID& asset_id,
  321. LLAssetType::EType,
  322. void* user_data, S32 status,
  323. LLExtStat ext_status)
  324. {
  325. if (!user_data) return; // Paranoia
  326. CallbackPtrStorage* storage = (CallbackPtrStorage*)user_data;
  327. asset_download_fn callback = storage->callback;
  328. delete storage;
  329. LLSettingsBase::ptr_t settings;
  330. if (!status)
  331. {
  332. LLFileSystem file(asset_id);
  333. S32 size = file.getSize();
  334. std::string buffer(size + 1, '\0');
  335. file.read((U8*)buffer.data(), size);
  336. std::stringstream llsdstream(buffer);
  337. LLSD llsdsettings;
  338. if (LLSDSerialize::deserialize(llsdsettings, llsdstream,
  339. LLSDSerialize::SIZE_UNLIMITED))
  340. {
  341. settings = createFromLLSD(llsdsettings);
  342. }
  343. if (!settings)
  344. {
  345. status = 1;
  346. llwarns << "Unable to create settings object for asset: "
  347. << asset_id << llendl;
  348. }
  349. else
  350. {
  351. settings->setAssetId(asset_id);
  352. }
  353. }
  354. else
  355. {
  356. llwarns << "Error retrieving asset: " << asset_id << ". Status code="
  357. << status << " (" << LLAssetStorage::getErrorString(status)
  358. << ") ext_status=" << (U32)ext_status << llendl;
  359. }
  360. if (callback)
  361. {
  362. callback(asset_id, settings, status, ext_status);
  363. }
  364. }
  365. //static
  366. bool LLEnvSettingsBase::exportFile(const LLSettingsBase::ptr_t& settings,
  367. const std::string& filename,
  368. LLSDSerialize::ELLSD_Serialize format)
  369. {
  370. try
  371. {
  372. std::ofstream file(filename, std::ios::out | std::ios::trunc);
  373. file.exceptions(std::ios_base::failbit | std::ios_base::badbit);
  374. if (!file)
  375. {
  376. llwarns << "Unable to open '" << filename << "' for writing."
  377. << llendl;
  378. return false;
  379. }
  380. LLSDSerialize::serialize(settings->getSettings(), file, format);
  381. }
  382. catch (const std::ios_base::failure& e)
  383. {
  384. llwarns << "Unable to save settings to file '" << filename
  385. << "': " << e.what() << llendl;
  386. return false;
  387. }
  388. return true;
  389. }
  390. //static
  391. LLSettingsBase::ptr_t LLEnvSettingsBase::importFile(const std::string& filename)
  392. {
  393. LLSD settings;
  394. try
  395. {
  396. std::ifstream file(filename, std::ios::in);
  397. file.exceptions(std::ios_base::failbit | std::ios_base::badbit);
  398. if (!file)
  399. {
  400. llwarns << "Unable to open '" << filename << "' for reading."
  401. << llendl;
  402. return LLSettingsBase::ptr_t();
  403. }
  404. if (!LLSDSerialize::deserialize(settings, file,
  405. LLSDSerialize::SIZE_UNLIMITED))
  406. {
  407. llwarns << "Unable to deserialize settings from '" << filename
  408. << "'" << llendl;
  409. return LLSettingsBase::ptr_t();
  410. }
  411. }
  412. catch (const std::ios_base::failure& e)
  413. {
  414. llwarns << "Unable to save settings to file '" << filename << "': "
  415. << e.what() << llendl;
  416. return LLSettingsBase::ptr_t();
  417. }
  418. return createFromLLSD(settings);
  419. }
  420. //static
  421. LLSettingsBase::ptr_t LLEnvSettingsBase::createFromLLSD(const LLSD& settings)
  422. {
  423. if (!settings.has(SETTING_TYPE))
  424. {
  425. llwarns << "No settings type in LLSD" << llendl;
  426. return LLSettingsBase::ptr_t();
  427. }
  428. std::string settingtype = settings[SETTING_TYPE].asString();
  429. if (settingtype == "daycycle")
  430. {
  431. return LLEnvSettingsDay::buildDay(settings);
  432. }
  433. if (settingtype == "sky")
  434. {
  435. return LLEnvSettingsSky::buildSky(settings);
  436. }
  437. if (settingtype == "water")
  438. {
  439. return LLEnvSettingsWater::buildWater(settings);
  440. }
  441. llwarns << "Unable to determine settings type for '" << settingtype
  442. << "'." << llendl;
  443. return LLSettingsBase::ptr_t();
  444. }
  445. //static
  446. LLSD LLEnvSettingsBase::readLegacyPresetData(std::string filename,
  447. std::string path,
  448. LLSD& messages)
  449. {
  450. // Ensure path got a dir delimiter appended
  451. if (!path.empty() && path.back() != LL_DIR_DELIM_CHR)
  452. {
  453. path += LL_DIR_DELIM_STR;
  454. }
  455. // Ensure name does not have dir delimiter prepended
  456. if (!filename.empty() && filename[0] == LL_DIR_DELIM_CHR)
  457. {
  458. filename = filename.substr(1);
  459. }
  460. std::string full_path = path + filename;
  461. llifstream xml_file;
  462. xml_file.open(full_path.c_str());
  463. if (!xml_file)
  464. {
  465. messages["REASONS"] = LLTrans::getString("SettingImportFileError",
  466. LLSDMap("FILE", full_path));
  467. llwarns << "Unable to open Windlight file: " << full_path << llendl;
  468. return LLSD();
  469. }
  470. LLSD params_data;
  471. LLPointer<LLSDParser> parser = new LLSDXMLParser();
  472. if (parser->parse(xml_file, params_data,
  473. LLSDSerialize::SIZE_UNLIMITED) == LLSDParser::PARSE_FAILURE)
  474. {
  475. xml_file.close();
  476. messages["REASONS"] = LLTrans::getString("SettingParseFileError",
  477. LLSDMap("FILE", full_path));
  478. return LLSD();
  479. }
  480. xml_file.close();
  481. LL_DEBUGS("EnvSettings") << "Loaded: " << full_path << LL_ENDL;
  482. return params_data;
  483. }
  484. ///////////////////////////////////////////////////////////////////////////////
  485. // LLEnvSettingsSky class
  486. ///////////////////////////////////////////////////////////////////////////////
  487. LLEnvSettingsSky::LLEnvSettingsSky(const LLSD& data, bool is_advanced)
  488. : LLSettingsSky(data),
  489. mIsAdvanced(is_advanced),
  490. mSceneLightStrength(3.f)
  491. {
  492. }
  493. LLEnvSettingsSky::LLEnvSettingsSky()
  494. : LLSettingsSky(),
  495. mIsAdvanced(false),
  496. mSceneLightStrength(3.f)
  497. {
  498. }
  499. //virtual
  500. LLSettingsSky::ptr_t LLEnvSettingsSky::buildClone() const
  501. {
  502. LLSD settings = cloneSettings();
  503. const validation_list_t& validations = validationList();
  504. LLSD results = settingValidation(settings, validations);
  505. if (!results["success"].asBoolean())
  506. {
  507. llwarns << "Sky setting validation failed:\n" << results << llendl;
  508. return ptr_t();
  509. }
  510. U32 flags = getFlags();
  511. ptr_t skyp = std::make_shared<LLEnvSettingsSky>(settings);
  512. skyp->setFlags(flags);
  513. return skyp;
  514. }
  515. //virtual
  516. void LLEnvSettingsSky::updateSettings()
  517. {
  518. LLSettingsSky::updateSettings();
  519. // Note: calling these also causes an update of the positions in the sky
  520. // settings. It is therefore essential to call them here.
  521. LLVector3 sun_direction = getSunDirection();
  522. LLVector3 moon_direction = getMoonDirection();
  523. LL_DEBUGS("EnvSettings") << "Sun direction: " << sun_direction
  524. << " - Moon direction: " << moon_direction
  525. << LL_ENDL;
  526. #if 1 // Is this still needed at all ?
  527. // Set the extended environment textures
  528. gSky.setSunTextures(getSunTextureId(), getNextSunTextureId());
  529. gSky.setMoonTextures(getMoonTextureId(), getNextMoonTextureId());
  530. gSky.setCloudNoiseTextures(getCloudNoiseTextureId(),
  531. getNextCloudNoiseTextureId());
  532. gSky.setBloomTextures(getBloomTextureId(), getNextBloomTextureId());
  533. #endif
  534. // We want the dot prod of Sun with high noon vector (0,0,1), which is just
  535. // the z component
  536. F32 dp = llmax(sun_direction[2], 0.f); // Clamped to 0 when sun is down
  537. // Since WL scales everything by 2, there should always be at least a 2:1
  538. // brightness ratio between sunlight and point lights in windlight to
  539. // normalize point lights.
  540. static LLCachedControl<F32> dyn_rng(gSavedSettings,
  541. "RenderSunDynamicRange");
  542. F32 sun_dynamic_range = llmax((F32)dyn_rng, 0.0001f);
  543. mSceneLightStrength = 1.5f + 2.f * sun_dynamic_range * dp;
  544. gSky.setSunAndMoonDirectionsCFR(sun_direction, moon_direction);
  545. gSky.setSunScale(getSunScale());
  546. gSky.setMoonScale(getMoonScale());
  547. }
  548. //virtual
  549. void LLEnvSettingsSky::applySpecial(LLShaderUniforms* targetp)
  550. {
  551. LLShaderUniforms* shaderp = &(targetp)[LLGLSLShader::SG_DEFAULT];
  552. if (shaderp)
  553. {
  554. if (gUsePBRShaders)
  555. {
  556. shaderp->uniform3fv(LLShaderMgr::LIGHTNORM,
  557. gEnvironment.getClampedLightNorm().mV);
  558. }
  559. else
  560. {
  561. shaderp->uniform4fv(LLShaderMgr::LIGHTNORM,
  562. gEnvironment.getClampedLightNorm().mV);
  563. }
  564. shaderp->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL,
  565. gViewerCamera.getOrigin());
  566. }
  567. shaderp = &(targetp)[LLGLSLShader::SG_SKY];
  568. if (shaderp)
  569. {
  570. if (gUsePBRShaders)
  571. {
  572. shaderp->uniform3fv(LLShaderMgr::LIGHTNORM,
  573. gEnvironment.getClampedLightNorm().mV);
  574. }
  575. else
  576. {
  577. shaderp->uniform4fv(LLShaderMgr::LIGHTNORM,
  578. gEnvironment.getClampedLightNorm().mV);
  579. }
  580. // Legacy SETTING_CLOUD_SCROLL_RATE("cloud_scroll_rate") ?
  581. const LLColor3& col_c_p_d1 = getCloudPosDensity1();
  582. LLVector4 vect_c_p_d1(col_c_p_d1.mV[0], col_c_p_d1.mV[1],
  583. col_c_p_d1.mV[2], 1.f);
  584. LLVector4 cloud_scroll(gEnvironment.getCloudScrollDelta());
  585. // SL-13084 EEP added support for custom cloud textures: flip them
  586. // horizontally to match the preview of Clouds > Cloud Scroll.
  587. // Keep these shaders in sync:
  588. // - ee/class2/windlight/cloudsV.glsl
  589. // - ee/class1/deferred/cloudsV.glsl
  590. cloud_scroll[0] = -cloud_scroll[0];
  591. vect_c_p_d1 += cloud_scroll;
  592. LLColor4 cloud_color(getCloudColor(), 1.f);
  593. if (gUsePBRShaders)
  594. {
  595. shaderp->uniform3fv(LLShaderMgr::CLOUD_POS_DENSITY1,
  596. LLVector3(vect_c_p_d1).mV);
  597. shaderp->uniform3fv(LLShaderMgr::SUNLIGHT_COLOR,
  598. getSunlightColor().mV);
  599. shaderp->uniform3fv(LLShaderMgr::MOONLIGHT_COLOR,
  600. getMoonlightColor().mV);
  601. shaderp->uniform3fv(LLShaderMgr::CLOUD_COLOR,
  602. LLColor3(cloud_color).mV);
  603. }
  604. else
  605. {
  606. shaderp->uniform4fv(LLShaderMgr::CLOUD_POS_DENSITY1,
  607. vect_c_p_d1.mV);
  608. shaderp->uniform4fv(LLShaderMgr::SUNLIGHT_COLOR,
  609. gPipeline.mSunLightColor.mV);
  610. shaderp->uniform4fv(LLShaderMgr::MOONLIGHT_COLOR,
  611. gPipeline.mMoonLightColor.mV);
  612. shaderp->uniform4fv(LLShaderMgr::CLOUD_COLOR, cloud_color.mV);
  613. }
  614. }
  615. shaderp = &(targetp)[LLGLSLShader::SG_ANY];
  616. if (!shaderp)
  617. {
  618. return;
  619. }
  620. shaderp->uniform1f(LLShaderMgr::SCENE_LIGHT_STRENGTH, mSceneLightStrength);
  621. bool sun_up = getIsSunUp();
  622. shaderp->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up ? 1 : 0);
  623. F32 gamma = getGamma();
  624. if (gUsePBRShaders)
  625. {
  626. static LLCachedControl<F32> sun_scale(gSavedSettings,
  627. "RenderSkySunlightScale");
  628. static LLCachedControl<F32> brightness(gSavedSettings,
  629. "RenderSkySunlightBrightness");
  630. static LLCachedControl<bool> adjust(gSavedSettings,
  631. "RenderSkyAutoAdjustLegacy");
  632. F32 sun_light_scale = sun_scale;
  633. if (sun_light_scale <= 0.f)
  634. {
  635. #if 0 // Moon brightness = Sun brightness, so apply at night too... HB
  636. if (!sun_up)
  637. {
  638. // Leave night-time lighting untouched. HB
  639. sun_light_scale = 1.f;
  640. }
  641. else
  642. #endif
  643. {
  644. // Apply automatic Sun light scaling. HB
  645. F32 desired_brightness = llclamp(F32(brightness), 0.05f, 1.5f);
  646. F32 sun_brightness = getSunlightColor().brightness();
  647. sun_light_scale = desired_brightness / sun_brightness;
  648. }
  649. }
  650. shaderp->uniform1f(LLShaderMgr::SKY_SUNLIGHT_SCALE, sun_light_scale);
  651. static LLCachedControl<F32> sky_amb_scale(gSavedSettings,
  652. "RenderSkyAmbientScale");
  653. shaderp->uniform1f(LLShaderMgr::SKY_AMBIENT_SCALE, sky_amb_scale);
  654. static LLCachedControl<bool> desaturate(gSavedSettings,
  655. "RenderSkyReflectionDesaturate");
  656. static LLCachedControl<F32> desaturation(gSavedSettings,
  657. "RenderSkyReflectionDesaturation");
  658. static LLCachedControl<F32> darkening(gSavedSettings,
  659. "RenderSkyReflectionDarkening");
  660. static LLCachedControl<F32> hdr_adjust(gSavedSettings,
  661. "RenderSkyAutoAdjustHDRScale");
  662. static LLCachedControl<F32> amb_scale(gSavedSettings,
  663. "RenderSkyAutoAdjustAmbientScale");
  664. static LLCachedControl<F32> hor_scale(gSavedSettings,
  665. "RenderSkyAutoAdjustBlueHorizonScale");
  666. static LLCachedControl<F32> den_scale(gSavedSettings,
  667. "RenderSkyAutoAdjustBlueDensityScale");
  668. static LLCachedControl<F32> col_scale(gSavedSettings,
  669. "RenderSkyAutoAdjustSunColorScale");
  670. static LLCachedControl<F32> probe_amb(gSavedSettings,
  671. "RenderSkyAutoAdjustProbeAmbiance");
  672. static LLCachedControl<U32> reflections(gSavedSettings,
  673. "RenderReflectionProbes");
  674. // Sync sAutoAdjustProbeAmbiance with the debug settings now (it will
  675. // be used by getReflectionProbeAmbiance() below). HB
  676. F32 probe_ambiance = reflections ? probe_amb : 1.f;
  677. sAutoAdjustProbeAmbiance = probe_ambiance;
  678. // Note: when RenderReflectionProbes is 0, we must use 1.f for the
  679. // probe ambiance, else the rendering is way too dark. HB
  680. probe_ambiance = reflections ? getReflectionProbeAmbiance() : 1.f;
  681. F32 hdr_scale = 0.f;
  682. LLColor3 ambient;
  683. // During an irradiance map update, disable ambient lighting (direct
  684. // lighting only) and desaturate sky color (avoid tinting the world
  685. // blue).
  686. if (!gCubeSnapshot || gPipeline.mReflectionMapManager.isRadiancePass())
  687. {
  688. if (getReflectionProbeAmbiance() != 0.f)
  689. {
  690. ambient = getTotalAmbient();
  691. // Use a modifier here so 1.0 maps to the "most desirable"
  692. // default and the maximum value does not go off the rails.
  693. hdr_scale = 2.f * sqrtf(gamma);
  694. }
  695. else if (adjust && canAutoAdjust())
  696. {
  697. hdr_scale = hdr_adjust;
  698. // Auto-adjust legacy sky to take advantage of probe ambiance.
  699. ambient = getTotalAmbient() * F32(amb_scale);
  700. LLColor3 sun_diffuse = getSunlightColor() * col_scale;
  701. shaderp->uniform3fv(LLShaderMgr::SUNLIGHT_COLOR,
  702. sun_diffuse.mV);
  703. LLColor3 blue_density = getBlueDensity() * den_scale;
  704. LLColor3 blue_horizon = getBlueHorizon() * hor_scale;
  705. if (gCubeSnapshot && desaturate)
  706. {
  707. // Attenuate the blue hue if this is a reflection probe
  708. // render pass. HB
  709. blue_density.desaturate(desaturation, darkening);
  710. blue_horizon.desaturate(desaturation, darkening);
  711. }
  712. shaderp->uniform3fv(LLShaderMgr::BLUE_DENSITY,
  713. blue_density.mV);
  714. shaderp->uniform3fv(LLShaderMgr::BLUE_HORIZON,
  715. blue_horizon.mV);
  716. }
  717. else
  718. {
  719. hdr_scale = 1.f;
  720. ambient = getTotalAmbient();
  721. }
  722. }
  723. shaderp->uniform3fv(LLShaderMgr::AMBIENT, ambient.mV);
  724. if (hdr_scale)
  725. {
  726. shaderp->uniform1f(LLShaderMgr::SKY_HDR_SCALE, hdr_scale);
  727. }
  728. shaderp->uniform1f(LLShaderMgr::REFLECTION_PROBE_AMBIANCE,
  729. probe_ambiance);
  730. }
  731. else
  732. {
  733. shaderp->uniform4fv(LLShaderMgr::AMBIENT, getTotalAmbient().mV);
  734. shaderp->uniform1f(LLShaderMgr::DISPLAY_GAMMA,
  735. LLPipeline::RenderDeferredDisplayGamma);
  736. }
  737. shaderp->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR,
  738. getSunMoonGlowFactor());
  739. shaderp->uniform1f(LLShaderMgr::DENSITY_MULTIPLIER,
  740. getDensityMultiplier());
  741. shaderp->uniform1f(LLShaderMgr::DISTANCE_MULTIPLIER,
  742. getDistanceMultiplier());
  743. shaderp->uniform1f(LLShaderMgr::GAMMA, gamma);
  744. }
  745. //virtual
  746. const LLSettingsSky::parammapping_t& LLEnvSettingsSky::getParameterMap() const
  747. {
  748. static parammapping_t param_map;
  749. if (param_map.empty())
  750. {
  751. // LEGACY_ATMOSPHERICS
  752. //* TODO: default 'legacy' values duplicate the ones from functions
  753. // like getBlueDensity() find a better home for them. There is
  754. // LLSettingsSky::defaults(), but it does not contain everything since
  755. // it is geared towards creating new settings.
  756. param_map[SETTING_AMBIENT] =
  757. DefaultParam(LLShaderMgr::AMBIENT,
  758. LLColor3(0.25f, 0.25f, 0.25f).getValue());
  759. param_map[SETTING_BLUE_DENSITY] =
  760. DefaultParam(LLShaderMgr::BLUE_DENSITY,
  761. LLColor3(0.2447f, 0.4487f, 0.7599f).getValue());
  762. param_map[SETTING_BLUE_HORIZON] =
  763. DefaultParam(LLShaderMgr::BLUE_HORIZON,
  764. LLColor3(0.4954f, 0.4954f, 0.6399f).getValue());
  765. param_map[SETTING_HAZE_DENSITY] =
  766. DefaultParam(LLShaderMgr::HAZE_DENSITY, LLSD(0.7f));
  767. param_map[SETTING_HAZE_HORIZON] =
  768. DefaultParam(LLShaderMgr::HAZE_HORIZON, LLSD(0.19f));
  769. param_map[SETTING_DENSITY_MULTIPLIER] =
  770. DefaultParam(LLShaderMgr::DENSITY_MULTIPLIER, LLSD(0.0001f));
  771. param_map[SETTING_DISTANCE_MULTIPLIER] =
  772. DefaultParam(LLShaderMgr::DISTANCE_MULTIPLIER, LLSD(0.8f));
  773. // Following values are always present, so we can just zero these ones,
  774. // but used values from defaults()
  775. LLSD sky_defaults = LLSettingsSky::defaults();
  776. param_map[SETTING_CLOUD_POS_DENSITY2] =
  777. DefaultParam(LLShaderMgr::CLOUD_POS_DENSITY2,
  778. sky_defaults[SETTING_CLOUD_POS_DENSITY2]);
  779. param_map[SETTING_CLOUD_SCALE] =
  780. DefaultParam(LLShaderMgr::CLOUD_SCALE,
  781. sky_defaults[SETTING_CLOUD_SCALE]);
  782. param_map[SETTING_CLOUD_SHADOW] =
  783. DefaultParam(LLShaderMgr::CLOUD_SHADOW,
  784. sky_defaults[SETTING_CLOUD_SHADOW]);
  785. param_map[SETTING_GLOW] = DefaultParam(LLShaderMgr::GLOW,
  786. sky_defaults[SETTING_GLOW]);
  787. param_map[SETTING_MAX_Y] = DefaultParam(LLShaderMgr::MAX_Y,
  788. sky_defaults[SETTING_MAX_Y]);
  789. param_map[SETTING_CLOUD_VARIANCE] =
  790. DefaultParam(LLShaderMgr::CLOUD_VARIANCE,
  791. sky_defaults[SETTING_CLOUD_VARIANCE]);
  792. param_map[SETTING_MOON_BRIGHTNESS] =
  793. DefaultParam(LLShaderMgr::MOON_BRIGHTNESS,
  794. sky_defaults[SETTING_MOON_BRIGHTNESS]);
  795. param_map[SETTING_SKY_MOISTURE_LEVEL] =
  796. DefaultParam(LLShaderMgr::MOISTURE_LEVEL,
  797. sky_defaults[SETTING_SKY_MOISTURE_LEVEL]);
  798. param_map[SETTING_SKY_DROPLET_RADIUS] =
  799. DefaultParam(LLShaderMgr::DROPLET_RADIUS,
  800. sky_defaults[SETTING_SKY_DROPLET_RADIUS]);
  801. param_map[SETTING_SKY_ICE_LEVEL] =
  802. DefaultParam(LLShaderMgr::ICE_LEVEL,
  803. sky_defaults[SETTING_SKY_ICE_LEVEL]);
  804. // Legacy Windlight parameters used for conversion from EE to WL
  805. param_map[SETTING_SUNLIGHT_COLOR] =
  806. DefaultParam(LLShaderMgr::SUNLIGHT_COLOR,
  807. sky_defaults[SETTING_SUNLIGHT_COLOR]);
  808. param_map[SETTING_CLOUD_COLOR] =
  809. DefaultParam(LLShaderMgr::CLOUD_COLOR,
  810. sky_defaults[SETTING_CLOUD_COLOR]);
  811. param_map[SETTING_REFLECTION_PROBE_AMBIANCE] =
  812. DefaultParam(LLShaderMgr::REFLECTION_PROBE_AMBIANCE,
  813. sky_defaults[SETTING_REFLECTION_PROBE_AMBIANCE]);
  814. }
  815. return param_map;
  816. }
  817. //static
  818. LLSettingsSky::ptr_t LLEnvSettingsSky::buildSky(LLSD settings)
  819. {
  820. const validation_list_t& validations = validationList();
  821. LLSD results = settingValidation(settings, validations);
  822. if (!results["success"].asBoolean())
  823. {
  824. llwarns << "Sky setting validation failed:\n" << results << llendl;
  825. return ptr_t();
  826. }
  827. return std::make_shared<LLEnvSettingsSky>(settings, true);
  828. }
  829. //static
  830. LLSettingsSky::ptr_t LLEnvSettingsSky::buildDefaultSky()
  831. {
  832. static LLSD default_settings;
  833. if (!default_settings.size())
  834. {
  835. default_settings = LLSettingsSky::defaults();
  836. default_settings[SETTING_NAME] = std::string("_default_");
  837. const validation_list_t& validations = validationList();
  838. LLSD results = settingValidation(default_settings, validations);
  839. if (!results["success"].asBoolean())
  840. {
  841. llwarns << "Sky setting validation failed:\n" << results << llendl;
  842. return ptr_t();
  843. }
  844. }
  845. return std::make_shared<LLEnvSettingsSky>(default_settings);
  846. }
  847. //static
  848. LLSettingsSky::ptr_t LLEnvSettingsSky::buildFromLegacyPreset(const std::string& name,
  849. const LLSD& old_settings,
  850. LLSD& messages)
  851. {
  852. LLSD new_settings = translateLegacySettings(old_settings);
  853. if (new_settings.isUndefined())
  854. {
  855. messages["REASONS"] = LLTrans::getString("SettingTranslateError",
  856. LLSDMap("NAME", name));
  857. llwarns << "Sky setting translation failed:\n" << messages << llendl;
  858. return LLSettingsSky::ptr_t();
  859. }
  860. new_settings[SETTING_NAME] = name;
  861. const validation_list_t& validations = validationList();
  862. LLSD results = settingValidation(new_settings, validations);
  863. if (!results["success"].asBoolean())
  864. {
  865. messages["REASONS"] = LLTrans::getString("SettingValidationError",
  866. LLSDMap("NAME", name));
  867. llwarns << "Sky setting validation failed:\n" << results << llendl;
  868. return ptr_t();
  869. }
  870. return std::make_shared<LLEnvSettingsSky>(new_settings);
  871. }
  872. //static
  873. LLSettingsSky::ptr_t LLEnvSettingsSky::buildFromLegacyPresetFile(const std::string& name,
  874. const std::string& filename,
  875. const std::string& path,
  876. LLSD& messages)
  877. {
  878. LLSD legacy_data = LLEnvSettingsBase::readLegacyPresetData(filename, path,
  879. messages);
  880. if (!legacy_data)
  881. {
  882. // 'messages' is filled in by readLegacyPresetData
  883. llwarns << "Could not load legacy Windlight \"" << name << "\" from "
  884. << path << llendl;
  885. return ptr_t();
  886. }
  887. return buildFromLegacyPreset(LLURI::unescape(name), legacy_data, messages);
  888. }
  889. //static
  890. bool LLEnvSettingsSky::applyPresetByName(std::string name, bool ignore_case)
  891. {
  892. if (ignore_case)
  893. {
  894. // Normally, 'name' should already be passed as a lower-cased setting
  895. // name when 'ignore_case' is true, but let's assume it might not be...
  896. LLStringUtil::toLower(name);
  897. }
  898. // Start with inventory settings, when available...
  899. if (gAgent.hasInventorySettings())
  900. {
  901. const LLUUID& folder_id =
  902. gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS,
  903. false);
  904. if (folder_id.notNull())
  905. {
  906. LLEnvSettingsCollector collector;
  907. LLInventoryModel::cat_array_t cats;
  908. LLInventoryModel::item_array_t items;
  909. gInventory.collectDescendentsIf(folder_id, cats, items, false,
  910. collector);
  911. std::string preset;
  912. for (LLInventoryModel::item_array_t::iterator
  913. iter = items.begin(), end = items.end();
  914. iter != end; ++iter)
  915. {
  916. LLViewerInventoryItem* itemp = *iter;
  917. LLSettingsType::EType type = itemp->getSettingsType();
  918. if (type != LLSettingsType::ST_SKY)
  919. {
  920. continue;
  921. }
  922. preset = itemp->getName();
  923. if (ignore_case)
  924. {
  925. LLStringUtil::toLower(preset);
  926. }
  927. if (preset == name)
  928. {
  929. name = itemp->getName(); // Real name
  930. llinfos << "Using inventory settings: " << name << llendl;
  931. gEnvironment.setEnvironment(LLEnvironment::ENV_LOCAL,
  932. itemp->getAssetUUID());
  933. gEnvironment.setSelectedEnvironment(LLEnvironment::ENV_LOCAL,
  934. LLEnvironment::TRANSITION_INSTANT);
  935. if (gAutomationp)
  936. {
  937. gAutomationp->onWindlightChange(name, "", "");
  938. }
  939. return true;
  940. }
  941. }
  942. }
  943. }
  944. // Inventory settings failed; try Windlight settings... HB
  945. if (ignore_case)
  946. {
  947. // When ignoring the case, we must scan all usable WL settings to find
  948. // one which can match our lower-cased string, and then use that real
  949. // name to convert the corresponding WL settings.
  950. bool found = false;
  951. std::vector<std::string> presets =
  952. LLWLSkyParamMgr::getLoadedPresetsList();
  953. std::string preset;
  954. for (S32 i = 0, count = presets.size(); i < count; ++i)
  955. {
  956. preset = presets[i];
  957. LLStringUtil::toLower(preset);
  958. if (preset == name)
  959. {
  960. // Retain the real, case-sensitive name
  961. name = presets[i];
  962. found = true;
  963. break;
  964. }
  965. }
  966. if (!found)
  967. {
  968. return false;
  969. }
  970. }
  971. std::string filename, path;
  972. if (LLWLDayCycle::findPresetFile(name, "skies", "", filename, path))
  973. {
  974. LLSD msg;
  975. LLSettingsSky::ptr_t skyp = buildFromLegacyPresetFile(name, filename,
  976. path, msg);
  977. if (skyp)
  978. {
  979. llinfos << "Using Windlight settings: " << name << llendl;
  980. gEnvironment.setEnvironment(LLEnvironment::ENV_LOCAL, skyp);
  981. gEnvironment.setSelectedEnvironment(LLEnvironment::ENV_LOCAL,
  982. LLEnvironment::TRANSITION_INSTANT);
  983. if (gAutomationp)
  984. {
  985. gAutomationp->onWindlightChange(name, "", "");
  986. }
  987. return true;
  988. }
  989. }
  990. return false;
  991. }
  992. ///////////////////////////////////////////////////////////////////////////////
  993. // LLEnvSettingsWater class
  994. ///////////////////////////////////////////////////////////////////////////////
  995. LLEnvSettingsWater::LLEnvSettingsWater(const LLSD& data)
  996. : LLSettingsWater(data)
  997. {
  998. }
  999. LLEnvSettingsWater::LLEnvSettingsWater()
  1000. : LLSettingsWater()
  1001. {
  1002. }
  1003. //virtual
  1004. LLSettingsWater::ptr_t LLEnvSettingsWater::buildClone() const
  1005. {
  1006. LLSD settings = cloneSettings();
  1007. const validation_list_t& validations = validationList();
  1008. LLSD results = settingValidation(settings, validations);
  1009. if (!results["success"].asBoolean())
  1010. {
  1011. llwarns << "Water setting validation failed:\n" << results << llendl;
  1012. return ptr_t();
  1013. }
  1014. U32 flags = getFlags();
  1015. ptr_t waterp = std::make_shared<LLEnvSettingsWater>(settings);
  1016. waterp->setFlags(flags);
  1017. return waterp;
  1018. }
  1019. //virtual
  1020. void LLEnvSettingsWater::updateSettings()
  1021. {
  1022. LLSettingsWater::updateSettings();
  1023. LLDrawPoolWater* poolp =
  1024. (LLDrawPoolWater*)gPipeline.getPool(LLDrawPool::POOL_WATER);
  1025. if (!poolp) return;
  1026. poolp->setTransparentTextures(getTransparentTextureID(),
  1027. getNextTransparentTextureID());
  1028. poolp->setNormalMaps(getNormalMapID(), getNextNormalMapID());
  1029. }
  1030. //virtual
  1031. void LLEnvSettingsWater::applySpecial(LLShaderUniforms* targetp)
  1032. {
  1033. if (!targetp || !gAgent.getRegion())
  1034. {
  1035. return;
  1036. }
  1037. S32 group = gUsePBRShaders ? LLGLSLShader::SG_ANY : LLGLSLShader::SG_WATER;
  1038. LLShaderUniforms* shaderp = &(targetp)[group];
  1039. if (!shaderp)
  1040. {
  1041. return;
  1042. }
  1043. F32 water_height = gPipeline.mWaterHeight;
  1044. if (gViewerCamera.cameraUnderWater())
  1045. {
  1046. // When the camera is under water, use the water height at the camera
  1047. // position.
  1048. LLViewerRegion* regionp =
  1049. gWorld.getRegionFromPosAgent(gViewerCamera.getOrigin());
  1050. if (regionp)
  1051. {
  1052. water_height = regionp->getWaterHeight();
  1053. }
  1054. }
  1055. if (!gUsePBRShaders)
  1056. {
  1057. water_height += 0.1f; // Z-fudging for EE/WL rendering
  1058. }
  1059. // Transform water plane to eye space
  1060. LLVector4a norm(0.f, 0.f, 1.f);
  1061. LLVector4a ep(0.f, 0.f, water_height);
  1062. const LLMatrix4a& mat = gGLModelView;
  1063. LLMatrix4a invtrans = mat;
  1064. invtrans.invert();
  1065. invtrans.transpose();
  1066. F32* invtransp = invtrans.getF32ptr();
  1067. invtransp[3] = invtransp[7] = invtransp[11] = 0.f;
  1068. invtrans.perspectiveTransform(norm, norm);
  1069. norm.normalize3fast();
  1070. mat.affineTransform(ep, ep);
  1071. ep.setAllDot3(ep, norm);
  1072. ep.negate();
  1073. norm.copyComponent<3>(ep);
  1074. shaderp->uniform4fv(LLShaderMgr::WATER_WATERPLANE, norm.getF32ptr());
  1075. LLPipeline::sWaterPlane = norm;
  1076. // Mirror
  1077. norm.loadua(gPipeline.mHeroProbeManager.mMirrorNormal.mV);
  1078. ep.loadua(gPipeline.mHeroProbeManager.mMirrorPosition.mV);
  1079. invtrans.perspectiveTransform(norm, norm);
  1080. norm.normalize3fast();
  1081. mat.affineTransform(ep, ep);
  1082. ep.setAllDot3(ep, norm);
  1083. ep.negate();
  1084. norm.copyComponent<3>(ep);
  1085. shaderp->uniform4fv(LLShaderMgr::CLIP_PLANE, norm.getF32ptr());
  1086. if (gPipeline.mHeroProbeManager.isMirrorPass())
  1087. {
  1088. shaderp->uniform1f(LLShaderMgr::MIRROR_FLAG, 1.f);
  1089. }
  1090. else
  1091. {
  1092. shaderp->uniform1f(LLShaderMgr::MIRROR_FLAG, 0.f);
  1093. }
  1094. LLVector4 light_direction = gEnvironment.getClampedLightNorm();
  1095. F32 fog_ks = 1.f / llmax(light_direction.mV[2], WATER_FOG_LIGHT_CLAMP);
  1096. shaderp->uniform1f(LLShaderMgr::WATER_FOGKS, fog_ks);
  1097. bool underwater = gPipeline.mEyeAboveWater < 0.f;
  1098. F32 water_fog_density = getModifiedWaterFogDensity(underwater);
  1099. shaderp->uniform1f(LLShaderMgr::WATER_FOGDENSITY, water_fog_density);
  1100. F32 blend_factor = getBlendFactor();
  1101. shaderp->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
  1102. if (gUsePBRShaders)
  1103. {
  1104. LLColor4 fog_color(getWaterFogColor());
  1105. shaderp->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, fog_color.mV);
  1106. shaderp->uniform3fv(LLShaderMgr::WATER_FOGCOLOR_LINEAR,
  1107. linearColor3(fog_color).mV);
  1108. // Update to normal lightnorm, water shader itself will use rotated
  1109. // lightnorm as necessary
  1110. shaderp->uniform3fv(LLShaderMgr::LIGHTNORM, light_direction.mV);
  1111. }
  1112. else
  1113. {
  1114. LLColor4 fog_color(getWaterFogColor(), 0.f);
  1115. shaderp->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, fog_color.mV);
  1116. // Update to normal lightnorm, water shader itself will use rotated
  1117. // lightnorm as necessary
  1118. shaderp->uniform4fv(LLShaderMgr::LIGHTNORM, light_direction.mV);
  1119. }
  1120. }
  1121. //virtual
  1122. const LLSettingsWater::parammapping_t& LLEnvSettingsWater::getParameterMap() const
  1123. {
  1124. static parammapping_t param_map;
  1125. #if 0 // Disabled also in LL's viewer
  1126. if (param_map.empty())
  1127. {
  1128. LLSD water_defaults = LLSettingsWater::defaults();
  1129. param_map[SETTING_FOG_COLOR] =
  1130. DefaultParam(LLShaderMgr::WATER_FOGCOLOR,
  1131. water_defaults[SETTING_FOG_COLOR]);
  1132. // Let this get set by LLEnvSettingsWater::applySpecial so that it can
  1133. // properly reflect the underwater modifier
  1134. param_map[SETTING_FOG_DENSITY] =
  1135. DefaultParam(LLShaderMgr::WATER_FOGDENSITY,
  1136. water_defaults[SETTING_FOG_DENSITY]);
  1137. }
  1138. #endif
  1139. return param_map;
  1140. }
  1141. //static
  1142. LLSettingsWater::ptr_t LLEnvSettingsWater::buildWater(LLSD settings)
  1143. {
  1144. const validation_list_t& validations = validationList();
  1145. LLSD results = settingValidation(settings, validations);
  1146. if (!results["success"].asBoolean())
  1147. {
  1148. llwarns << "Water setting validation failed:\n" << results << llendl;
  1149. return ptr_t();
  1150. }
  1151. return std::make_shared<LLEnvSettingsWater>(settings);
  1152. }
  1153. //static
  1154. LLSettingsWater::ptr_t LLEnvSettingsWater::buildDefaultWater()
  1155. {
  1156. static LLSD default_settings;
  1157. if (!default_settings.size())
  1158. {
  1159. default_settings = defaults();
  1160. default_settings[SETTING_NAME] = "_default_";
  1161. const validation_list_t& validations = validationList();
  1162. LLSD results = settingValidation(default_settings, validations);
  1163. if (!results["success"].asBoolean())
  1164. {
  1165. llwarns << "Water setting validation failed:\n" << results
  1166. << llendl;
  1167. return ptr_t();
  1168. }
  1169. }
  1170. return std::make_shared<LLEnvSettingsWater>(default_settings);
  1171. }
  1172. //static
  1173. LLSettingsWater::ptr_t LLEnvSettingsWater::buildFromLegacyPreset(const std::string& name,
  1174. const LLSD& old_settings,
  1175. LLSD& messages)
  1176. {
  1177. LLSD new_settings(translateLegacySettings(old_settings));
  1178. if (new_settings.isUndefined())
  1179. {
  1180. messages["REASONS"] = LLTrans::getString("SettingTranslateError",
  1181. LLSDMap("NAME", name));
  1182. llwarns << "Water setting translation failed:\n" << messages << llendl;
  1183. return LLSettingsWater::ptr_t();
  1184. }
  1185. new_settings[SETTING_NAME] = name;
  1186. const validation_list_t& validations = validationList();
  1187. LLSD results = settingValidation(new_settings, validations);
  1188. if (!results["success"].asBoolean())
  1189. {
  1190. messages["REASONS"] = LLTrans::getString("SettingValidationError", name);
  1191. llwarns << "Water setting validation failed:\n" << results << llendl;
  1192. return ptr_t();
  1193. }
  1194. return std::make_shared<LLEnvSettingsWater>(new_settings);
  1195. }
  1196. //static
  1197. LLSettingsWater::ptr_t LLEnvSettingsWater::buildFromLegacyPresetFile(const std::string& name,
  1198. const std::string& filename,
  1199. const std::string& path,
  1200. LLSD& messages)
  1201. {
  1202. LLSD legacy_data = LLEnvSettingsBase::readLegacyPresetData(filename, path,
  1203. messages);
  1204. if (!legacy_data)
  1205. {
  1206. // 'messages' is filled in by readLegacyPresetData
  1207. llwarns << "Could not load legacy Windlight \"" << name << "\" from "
  1208. << path << llendl;
  1209. return ptr_t();
  1210. }
  1211. return buildFromLegacyPreset(LLURI::unescape(name), legacy_data, messages);
  1212. }
  1213. //static
  1214. bool LLEnvSettingsWater::applyPresetByName(std::string name, bool ignore_case)
  1215. {
  1216. if (ignore_case)
  1217. {
  1218. // Normally, 'name' should already be passed as a lower-cased setting
  1219. // name when 'ignore_case' is true, but let's assume it might not be...
  1220. LLStringUtil::toLower(name);
  1221. }
  1222. // Start with inventory settings, when available...
  1223. if (gAgent.hasInventorySettings())
  1224. {
  1225. const LLUUID& folder_id =
  1226. gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS,
  1227. false);
  1228. if (folder_id.notNull())
  1229. {
  1230. LLEnvSettingsCollector collector;
  1231. LLInventoryModel::cat_array_t cats;
  1232. LLInventoryModel::item_array_t items;
  1233. gInventory.collectDescendentsIf(folder_id, cats, items, false,
  1234. collector);
  1235. std::string preset;
  1236. for (LLInventoryModel::item_array_t::iterator
  1237. iter = items.begin(), end = items.end();
  1238. iter != end; ++iter)
  1239. {
  1240. LLViewerInventoryItem* itemp = *iter;
  1241. LLSettingsType::EType type = itemp->getSettingsType();
  1242. if (type != LLSettingsType::ST_WATER)
  1243. {
  1244. continue;
  1245. }
  1246. preset = itemp->getName();
  1247. if (ignore_case)
  1248. {
  1249. LLStringUtil::toLower(preset);
  1250. }
  1251. if (preset == name)
  1252. {
  1253. name = itemp->getName(); // Real name
  1254. llinfos << "Using inventory settings: " << name << llendl;
  1255. gEnvironment.setEnvironment(LLEnvironment::ENV_LOCAL,
  1256. itemp->getAssetUUID());
  1257. gEnvironment.setSelectedEnvironment(LLEnvironment::ENV_LOCAL,
  1258. LLEnvironment::TRANSITION_INSTANT);
  1259. if (gAutomationp)
  1260. {
  1261. gAutomationp->onWindlightChange("", name, "");
  1262. }
  1263. return true;
  1264. }
  1265. }
  1266. }
  1267. }
  1268. // Inventory settings failed; try Windlight settings...
  1269. if (ignore_case)
  1270. {
  1271. // When ignoring the case, we must scan all usable WL settings to find
  1272. // one which can match our lower-cased string, and then use that real
  1273. // name to convert the corresponding WL settings.
  1274. bool found = false;
  1275. std::vector<std::string> presets =
  1276. LLWLWaterParamMgr::getLoadedPresetsList();
  1277. std::string preset;
  1278. for (S32 i = 0, count = presets.size(); i < count; ++i)
  1279. {
  1280. preset = presets[i];
  1281. LLStringUtil::toLower(preset);
  1282. if (preset == name)
  1283. {
  1284. // Retain the real, case-sensitive name
  1285. name = presets[i];
  1286. found = true;
  1287. break;
  1288. }
  1289. }
  1290. if (!found)
  1291. {
  1292. return false;
  1293. }
  1294. }
  1295. std::string filename, path;
  1296. if (LLWLDayCycle::findPresetFile(name, "water", "", filename, path))
  1297. {
  1298. LLSD msg;
  1299. LLSettingsWater::ptr_t waterp = buildFromLegacyPresetFile(name,
  1300. filename,
  1301. path, msg);
  1302. if (waterp)
  1303. {
  1304. llinfos << "Using Windlight settings: " << name << llendl;
  1305. gEnvironment.setEnvironment(LLEnvironment::ENV_LOCAL, waterp);
  1306. gEnvironment.setSelectedEnvironment(LLEnvironment::ENV_LOCAL,
  1307. LLEnvironment::TRANSITION_INSTANT);
  1308. if (gAutomationp)
  1309. {
  1310. gAutomationp->onWindlightChange("", name, "");
  1311. }
  1312. return true;
  1313. }
  1314. }
  1315. return false;
  1316. }
  1317. ///////////////////////////////////////////////////////////////////////////////
  1318. // LLEnvSettingsDay class
  1319. ///////////////////////////////////////////////////////////////////////////////
  1320. LLEnvSettingsDay::LLEnvSettingsDay(const LLSD& data)
  1321. : LLSettingsDay(data)
  1322. {
  1323. }
  1324. LLEnvSettingsDay::LLEnvSettingsDay()
  1325. : LLSettingsDay()
  1326. {
  1327. }
  1328. //virtual
  1329. LLSettingsDay::ptr_t LLEnvSettingsDay::buildClone() const
  1330. {
  1331. LLSD settings = cloneSettings();
  1332. const validation_list_t& validations = validationList();
  1333. LLSD results = settingValidation(settings, validations);
  1334. if (!results["success"].asBoolean())
  1335. {
  1336. llwarns << "Day setting validation failed;\n" << results << llendl;
  1337. return ptr_t();
  1338. }
  1339. ptr_t dayp = std::make_shared<LLEnvSettingsDay>(settings);
  1340. U32 flags = getFlags();
  1341. if (flags)
  1342. {
  1343. dayp->setFlags(flags);
  1344. }
  1345. dayp->initialize();
  1346. return dayp;
  1347. }
  1348. //virtual
  1349. LLSettingsDay::ptr_t LLEnvSettingsDay::buildDeepCloneAndUncompress() const
  1350. {
  1351. U32 flags = getFlags();
  1352. // No need for SETTING_TRACKS or SETTING_FRAMES, so take base LLSD
  1353. LLSD settings = llsd_clone(mSettings);
  1354. ptr_t day_clone = std::make_shared<LLEnvSettingsDay>(settings);
  1355. for (S32 i = 0; i < LLSettingsDay::TRACK_MAX; ++i)
  1356. {
  1357. const cycle_track_t& track = getCycleTrackConst(i);
  1358. cycle_track_t::const_iterator iter = track.begin();
  1359. while (iter != track.end())
  1360. {
  1361. // 'Unpack', usually for editing
  1362. // - frames 'share' settings multiple times
  1363. // - settings can reuse LLSDs they were initialized from
  1364. // We do not want for edited frame to change multiple frames in
  1365. // same track, so do a clone
  1366. day_clone->setSettingsAtKeyframe(iter->second->buildDerivedClone(),
  1367. iter->first, i);
  1368. ++iter;
  1369. }
  1370. }
  1371. day_clone->setFlags(flags);
  1372. return day_clone;
  1373. }
  1374. //virtual
  1375. LLSettingsSky::ptr_t LLEnvSettingsDay::getDefaultSky() const
  1376. {
  1377. return LLEnvSettingsSky::buildDefaultSky();
  1378. }
  1379. //virtual
  1380. LLSettingsWater::ptr_t LLEnvSettingsDay::getDefaultWater() const
  1381. {
  1382. return LLEnvSettingsWater::buildDefaultWater();
  1383. }
  1384. //virtual
  1385. LLSettingsSky::ptr_t LLEnvSettingsDay::buildSky(const LLSD& settings) const
  1386. {
  1387. LLSettingsSky::ptr_t skyp = std::make_shared<LLEnvSettingsSky>(settings);
  1388. return skyp && skyp->validate() ? skyp : LLSettingsSky::ptr_t();
  1389. }
  1390. //virtual
  1391. LLSettingsWater::ptr_t LLEnvSettingsDay::buildWater(const LLSD& settings) const
  1392. {
  1393. LLSettingsWater::ptr_t waterp =
  1394. std::make_shared<LLEnvSettingsWater>(settings);
  1395. return waterp && waterp->validate() ? waterp : LLSettingsWater::ptr_t();
  1396. }
  1397. //static
  1398. LLSettingsDay::ptr_t LLEnvSettingsDay::buildDay(LLSD settings)
  1399. {
  1400. const validation_list_t& validations = validationList();
  1401. LLSD results = settingValidation(settings, validations);
  1402. if (!results["success"].asBoolean())
  1403. {
  1404. llwarns << "Day setting validation failed:\n" << results << llendl;
  1405. LLSettingsDay::ptr_t();
  1406. }
  1407. ptr_t dayp = std::make_shared<LLEnvSettingsDay>(settings);
  1408. if (dayp)
  1409. {
  1410. dayp->initialize();
  1411. }
  1412. return dayp;
  1413. }
  1414. //static
  1415. LLSettingsDay::ptr_t LLEnvSettingsDay::buildDefaultDayCycle()
  1416. {
  1417. static ptr_t default_dayp;
  1418. if (default_dayp)
  1419. {
  1420. return default_dayp->buildClone();
  1421. }
  1422. #if 1 // Default EE day cycle is borked... Use Windlight's "Default" day
  1423. // cycle instead. HB
  1424. // *TODO: fix LLSettingsDay::defaults() so that it would *actually*
  1425. // correspond to the default Windlight day cycle...
  1426. std::string filename, path;
  1427. if (LLWLDayCycle::findPresetFile("Default", "days", "", filename, path))
  1428. {
  1429. LLSD messages;
  1430. default_dayp = buildFromLegacyPresetFile("_default_", filename, path,
  1431. messages);
  1432. if (default_dayp)
  1433. {
  1434. return default_dayp->buildClone();
  1435. }
  1436. }
  1437. else
  1438. {
  1439. llwarns << "Could not find any Default.xml Windlight day cycle file."
  1440. << llendl;
  1441. }
  1442. #endif
  1443. // Fallback path...
  1444. LLSD default_settings = LLSettingsDay::defaults();
  1445. default_settings[SETTING_NAME] = "_default_";
  1446. const LLSettingsDay::validation_list_t& validations =
  1447. LLSettingsDay::validationList();
  1448. LLSD results = LLSettingsDay::settingValidation(default_settings,
  1449. validations);
  1450. if (!results["success"].asBoolean())
  1451. {
  1452. llwarns << "Day setting validation failed:\n" << results << llendl;
  1453. return ptr_t();
  1454. }
  1455. default_dayp = std::make_shared<LLEnvSettingsDay>(default_settings);
  1456. default_dayp->initialize();
  1457. return default_dayp->buildClone();
  1458. }
  1459. //static
  1460. LLSettingsDay::ptr_t LLEnvSettingsDay::buildFromLegacyPreset(const std::string& name,
  1461. const std::string& path,
  1462. const LLSD& old_settings,
  1463. LLSD& messages)
  1464. {
  1465. LL_DEBUGS("EnvSettings") << "Loading '" << name << "' day cycle from: "
  1466. << path << LL_ENDL;
  1467. LLSD skytrack = LLSD::emptyArray();
  1468. std::set<std::string> framenames;
  1469. for (LLSD::array_const_iterator it = old_settings.beginArray(),
  1470. end = old_settings.endArray();
  1471. it != end; ++it)
  1472. {
  1473. std::string framename = (*it)[1].asString();
  1474. LLSD entry = LLSDMap(SETTING_KEYKFRAME, (*it)[0].asReal())
  1475. (SETTING_KEYNAME, "sky:" + framename);
  1476. framenames.emplace(framename);
  1477. skytrack.append(entry);
  1478. LL_DEBUGS("EnvSettings") << "Added sky track: " << framename
  1479. << LL_ENDL;
  1480. }
  1481. LLSD watertrack = llsd::array(LLSDMap(SETTING_KEYKFRAME, LLSD::Real(0.f))
  1482. (SETTING_KEYNAME, "water:Default"));
  1483. LL_DEBUGS("EnvSettings") << "Added water track: Default" << LL_ENDL;
  1484. LLSD new_settings(defaults());
  1485. new_settings[SETTING_TRACKS] = llsd::array(watertrack, skytrack);
  1486. LLSD frames(LLSD::emptyMap());
  1487. std::string filename, actual_path;
  1488. LLWLDayCycle::findPresetFile("Default", "water", path, filename,
  1489. actual_path);
  1490. LLSettingsWater::ptr_t waterp =
  1491. LLEnvSettingsWater::buildFromLegacyPresetFile("Default", filename,
  1492. actual_path, messages);
  1493. if (!waterp)
  1494. {
  1495. llwarns << "Failed to load Default water." << llendl;
  1496. // 'messages' is filled in by buildFromLegacyPresetFile
  1497. return LLSettingsDay::ptr_t();
  1498. }
  1499. LL_DEBUGS("EnvSettings") << "Loaded Default water from: "
  1500. << actual_path << filename << LL_ENDL;
  1501. frames["water:Default"] = waterp->getSettings();
  1502. for (std::set<std::string>::iterator it = framenames.begin(),
  1503. end = framenames.end();
  1504. it != end; ++it)
  1505. {
  1506. LLWLDayCycle::findPresetFile(*it, "skies", path, filename,
  1507. actual_path);
  1508. LLSettingsSky::ptr_t skyp =
  1509. LLEnvSettingsSky::buildFromLegacyPresetFile(*it, filename,
  1510. actual_path, messages);
  1511. if (!skyp)
  1512. {
  1513. llwarns << "Failed to load sky: " << *it << llendl;
  1514. // 'messages' is filled in by buildFromLegacyPresetFile
  1515. return LLSettingsDay::ptr_t();
  1516. }
  1517. LL_DEBUGS("EnvSettings") << "Loaded '" << *it << "' sky from: "
  1518. << actual_path << filename << LL_ENDL;
  1519. frames["sky:" + *it] = skyp->getSettings();
  1520. }
  1521. new_settings[SETTING_FRAMES] = frames;
  1522. const LLSettingsDay::validation_list_t& validations =
  1523. LLSettingsDay::validationList();
  1524. LLSD results = LLSettingsDay::settingValidation(new_settings,
  1525. validations);
  1526. if (!results["success"].asBoolean())
  1527. {
  1528. messages["REASONS"] = LLTrans::getString("SettingValidationError",
  1529. LLSDMap("NAME", name));
  1530. llwarns << "Day setting validation failed:\n" << results << llendl;
  1531. return LLSettingsDay::ptr_t();
  1532. }
  1533. LL_DEBUGS("EnvSettings") << "Creating EE settings from LLSD: "
  1534. << ll_pretty_print_sd(new_settings) << LL_ENDL;
  1535. LLSettingsDay::ptr_t dayp =
  1536. std::make_shared<LLEnvSettingsDay>(new_settings);
  1537. dayp->initialize();
  1538. return dayp;
  1539. }
  1540. //static
  1541. LLSettingsDay::ptr_t LLEnvSettingsDay::buildFromLegacyPresetFile(const std::string& name,
  1542. const std::string& filename,
  1543. const std::string& path,
  1544. LLSD& messages)
  1545. {
  1546. LLSD legacy_data = LLEnvSettingsBase::readLegacyPresetData(filename, path,
  1547. messages);
  1548. if (!legacy_data)
  1549. {
  1550. // 'messages' is filled in by readLegacyPresetData
  1551. llwarns << "Could not load legacy Windlight \"" << name << "\" from "
  1552. << path << llendl;
  1553. return ptr_t();
  1554. }
  1555. // Name for LLSettingsDay only, path to get related files from filesystem
  1556. return buildFromLegacyPreset(LLURI::unescape(name), path, legacy_data,
  1557. messages);
  1558. }
  1559. //static
  1560. LLSettingsDay::ptr_t LLEnvSettingsDay::buildFromLegacyMessage(const LLUUID& region_id,
  1561. LLSD daycycle,
  1562. LLSD skydefs,
  1563. LLSD waterdef)
  1564. {
  1565. LLSD frames(LLSD::emptyMap());
  1566. std::string newname;
  1567. for (LLSD::map_iterator it = skydefs.beginMap(), end = skydefs.endMap();
  1568. it != end; ++it)
  1569. {
  1570. newname = "sky:" + it->first;
  1571. LLSD new_settings = LLSettingsSky::translateLegacySettings(it->second);
  1572. new_settings[SETTING_NAME] = newname;
  1573. frames[newname] = new_settings;
  1574. llwarns << "Created region sky '" << newname << "'" << llendl;
  1575. }
  1576. LLSD watersettings = LLSettingsWater::translateLegacySettings(waterdef);
  1577. std::string watername = "water:"+ watersettings[SETTING_NAME].asString();
  1578. watersettings[SETTING_NAME] = watername;
  1579. frames[watername] = watersettings;
  1580. LLSD watertrack =
  1581. llsd::array(LLSDMap(SETTING_KEYKFRAME, LLSD::Real(0.f))
  1582. (SETTING_KEYNAME, watername));
  1583. LLSD skytrack(LLSD::emptyArray());
  1584. for (LLSD::array_const_iterator it = daycycle.beginArray(),
  1585. end = daycycle.endArray();
  1586. it != end; ++it)
  1587. {
  1588. LLSD entry =
  1589. LLSDMap(SETTING_KEYKFRAME, (*it)[0].asReal())
  1590. (SETTING_KEYNAME, "sky:" + (*it)[1].asString());
  1591. skytrack.append(entry);
  1592. }
  1593. LLSD new_settings =
  1594. LLSDMap(SETTING_NAME, "Region (legacy)")
  1595. (SETTING_TRACKS, llsd::array(watertrack, skytrack))
  1596. (SETTING_FRAMES, frames)
  1597. (SETTING_TYPE, "daycycle");
  1598. const LLSettingsSky::validation_list_t& validations =
  1599. LLSettingsDay::validationList();
  1600. LLSD results = LLSettingsDay::settingValidation(new_settings, validations);
  1601. if (!results["success"].asBoolean())
  1602. {
  1603. llwarns << "Day setting validation failed:\n" << results << llendl;
  1604. return LLSettingsDay::ptr_t();
  1605. }
  1606. LLSettingsDay::ptr_t dayp =
  1607. std::make_shared<LLEnvSettingsDay>(new_settings);
  1608. if (dayp)
  1609. {
  1610. // true for validation; either validate here, or when cloning for
  1611. // floater.
  1612. dayp->initialize(true);
  1613. }
  1614. return dayp;
  1615. }
  1616. //static
  1617. LLSettingsDay::ptr_t LLEnvSettingsDay::buildFromEnvironmentMessage(LLSD settings)
  1618. {
  1619. const LLSettingsDay::validation_list_t& validations =
  1620. LLSettingsDay::validationList();
  1621. LLSD results = LLSettingsDay::settingValidation(settings, validations);
  1622. if (!results["success"].asBoolean())
  1623. {
  1624. llwarns << "Day setting validation failed:\n" << results << llendl;
  1625. return ptr_t();
  1626. }
  1627. ptr_t dayp = std::make_shared<LLEnvSettingsDay>(settings);
  1628. dayp->initialize();
  1629. return dayp;
  1630. }
  1631. //static
  1632. void LLEnvSettingsDay::buildFromOtherSetting(LLSettingsBase::ptr_t settings,
  1633. asset_built_fn cb)
  1634. {
  1635. if (settings->getSettingsType() == "daycycle")
  1636. {
  1637. if (cb)
  1638. {
  1639. cb(std::static_pointer_cast<LLSettingsDay>(settings));
  1640. }
  1641. return;
  1642. }
  1643. LLEnvSettingsBase::getSettingsAsset(getDefaultAssetId(),
  1644. [settings, cb](LLUUID,
  1645. LLSettingsBase::ptr_t dayp,
  1646. S32, LLExtStat)
  1647. {
  1648. combineIntoDayCycle(std::static_pointer_cast<LLSettingsDay>(dayp),
  1649. settings, cb);
  1650. });
  1651. }
  1652. //static
  1653. void LLEnvSettingsDay::combineIntoDayCycle(LLSettingsDay::ptr_t dayp,
  1654. LLSettingsBase::ptr_t settings,
  1655. asset_built_fn cb)
  1656. {
  1657. if (settings->getSettingsType() == "sky")
  1658. {
  1659. dayp->setName("sky: " + settings->getName());
  1660. dayp->clearCycleTrack(1);
  1661. dayp->setSettingsAtKeyframe(settings, 0.0, 1);
  1662. }
  1663. else if (settings->getSettingsType() == "water")
  1664. {
  1665. dayp->setName("water: " + settings->getName());
  1666. dayp->clearCycleTrack(0);
  1667. dayp->setSettingsAtKeyframe(settings, 0.0, 0);
  1668. }
  1669. else
  1670. {
  1671. dayp.reset();
  1672. }
  1673. if (cb)
  1674. {
  1675. cb(dayp);
  1676. }
  1677. }
  1678. //static
  1679. bool LLEnvSettingsDay::applyPresetByName(std::string name, bool ignore_case)
  1680. {
  1681. if (ignore_case)
  1682. {
  1683. // Normally, 'name' should already be passed as a lower-cased setting
  1684. // name when 'ignore_case' is true, but let's assume it might not be...
  1685. LLStringUtil::toLower(name);
  1686. }
  1687. // Start with inventory settings, when available...
  1688. if (gAgent.hasInventorySettings())
  1689. {
  1690. const LLUUID& folder_id =
  1691. gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS,
  1692. false);
  1693. if (folder_id.notNull())
  1694. {
  1695. LLEnvSettingsCollector collector;
  1696. LLInventoryModel::cat_array_t cats;
  1697. LLInventoryModel::item_array_t items;
  1698. gInventory.collectDescendentsIf(folder_id, cats, items, false,
  1699. collector);
  1700. std::string preset;
  1701. for (LLInventoryModel::item_array_t::iterator
  1702. iter = items.begin(), end = items.end();
  1703. iter != end; ++iter)
  1704. {
  1705. LLViewerInventoryItem* itemp = *iter;
  1706. LLSettingsType::EType type = itemp->getSettingsType();
  1707. if (type != LLSettingsType::ST_DAYCYCLE)
  1708. {
  1709. continue;
  1710. }
  1711. preset = itemp->getName();
  1712. if (ignore_case)
  1713. {
  1714. LLStringUtil::toLower(preset);
  1715. }
  1716. if (preset == name)
  1717. {
  1718. name = itemp->getName(); // Real name
  1719. llinfos << "Using inventory settings: " << name << llendl;
  1720. gEnvironment.setEnvironment(LLEnvironment::ENV_LOCAL,
  1721. itemp->getAssetUUID());
  1722. gEnvironment.setSelectedEnvironment(LLEnvironment::ENV_LOCAL,
  1723. LLEnvironment::TRANSITION_INSTANT);
  1724. if (gAutomationp)
  1725. {
  1726. gAutomationp->onWindlightChange("", "", name);
  1727. }
  1728. return true;
  1729. }
  1730. }
  1731. }
  1732. }
  1733. // Inventory settings failed; try Windlight settings...
  1734. if (ignore_case)
  1735. {
  1736. // When ignoring the case, we must scan all usable WL settings to find
  1737. // one which can match our lower-cased string, and then use that real
  1738. // name to convert the corresponding WL settings.
  1739. bool found = false;
  1740. std::vector<std::string> presets =
  1741. LLWLDayCycle::getLoadedPresetsList();
  1742. std::string preset;
  1743. for (S32 i = 0, count = presets.size(); i < count; ++i)
  1744. {
  1745. preset = presets[i];
  1746. LLStringUtil::toLower(preset);
  1747. if (preset == name)
  1748. {
  1749. // Retain the real, case-sensitive name
  1750. name = presets[i];
  1751. found = true;
  1752. break;
  1753. }
  1754. }
  1755. if (!found)
  1756. {
  1757. return false;
  1758. }
  1759. }
  1760. std::string filename, path;
  1761. if (LLWLDayCycle::findPresetFile(name, "days", "", filename, path))
  1762. {
  1763. LLSD msg;
  1764. LLSettingsDay::ptr_t dayp = buildFromLegacyPresetFile(name, filename,
  1765. path, msg);
  1766. if (dayp)
  1767. {
  1768. llinfos << "Using Windlight settings: " << name << llendl;
  1769. gEnvironment.setEnvironment(LLEnvironment::ENV_LOCAL, dayp);
  1770. gEnvironment.setSelectedEnvironment(LLEnvironment::ENV_LOCAL,
  1771. LLEnvironment::TRANSITION_INSTANT);
  1772. if (gAutomationp)
  1773. {
  1774. gAutomationp->onWindlightChange("", "", name);
  1775. }
  1776. return true;
  1777. }
  1778. }
  1779. return false;
  1780. }