1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987 |
- /**
- * @file llenvsettings.cpp
- * @brief Subclasses for viewer specific settings behaviors.
- *
- * $LicenseInfo:firstyear=2018&license=viewergpl$
- *
- * Copyright (c) 2002-2019, Linden Research, Inc.
- * Copyright (c) 2019-2023, Henri Beauchamp.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
- #include "llviewerprecompiledheaders.h"
- #include "llenvsettings.h"
- #include "imageids.h"
- #include "llassetstorage.h"
- #include "lldir.h"
- #include "llfilesystem.h"
- #include "llnotifications.h"
- #include "llpermissions.h"
- #include "llsdutil.h"
- #include "lltrans.h"
- #include "lluri.h"
- #include "llagent.h"
- #include "lldrawpoolwater.h"
- #include "llenvironment.h"
- #include "llfloaterperms.h"
- #include "llinventorymodel.h"
- #include "llpipeline.h"
- #include "llsky.h"
- #include "llviewerassetupload.h"
- #include "hbviewerautomation.h"
- #include "llviewercamera.h"
- #include "llviewercontrol.h"
- #include "llviewerdisplay.h" // For gCubeSnapshot
- #include "llviewerinventory.h"
- #include "llviewerregion.h"
- #include "llviewershadermgr.h"
- #include "llwlskyparammgr.h"
- #include "llwlwaterparammgr.h"
- #include "llworld.h"
- constexpr F32 WATER_FOG_LIGHT_CLAMP = 0.3f;
- // Helper class
- class LLSettingsInventoryCB final : public LLInventoryCallback
- {
- public:
- LLSettingsInventoryCB(LLSettingsBase::ptr_t settings,
- LLEnvSettingsBase::inv_result_fn cb)
- : mSettings(settings),
- mCallback(cb)
- {
- }
- void fire(const LLUUID& inv_item_id) override
- {
- LLEnvSettingsBase::onInventoryItemCreated(inv_item_id, mSettings,
- mCallback);
- }
- private:
- LLSettingsBase::ptr_t mSettings;
- LLEnvSettingsBase::inv_result_fn mCallback;
- };
- ///////////////////////////////////////////////////////////////////////////////
- // LLEnvSettingsBase class
- ///////////////////////////////////////////////////////////////////////////////
- //static
- void LLEnvSettingsBase::createNewInventoryItem(LLSettingsType::EType stype,
- const LLUUID& parent_id,
- inv_result_fn callback)
- {
- // *TODO: implement Settings default permissions ?
- U32 next_owner_perm = LLFloaterPerms::getNextOwnerPerms();
- next_owner_perm |= PERM_COPY;
- if (!gAgent.hasInventorySettings())
- {
- gNotifications.add("NoEnvironmentSettings");
- return;
- }
- LLPointer<LLInventoryCallback> cb =
- new LLSettingsInventoryCB(LLSettingsBase::ptr_t(), callback);
- create_inventory_item(parent_id, LLTransactionID::tnull,
- LLSettingsType::getDefaultName(stype), "",
- LLAssetType::AT_SETTINGS,
- LLInventoryType::IT_SETTINGS, (U8)stype,
- next_owner_perm, cb);
- }
- //static
- void LLEnvSettingsBase::createInventoryItem(const LLSettingsBase::ptr_t& settings,
- const LLUUID& parent_id,
- const std::string& settings_name,
- inv_result_fn callback)
- {
- U32 next_owner_perm = LLPermissions::DEFAULT.getMaskNextOwner();
- createInventoryItem(settings, next_owner_perm, parent_id, settings_name,
- callback);
- }
- //static
- void LLEnvSettingsBase::createInventoryItem(const LLSettingsBase::ptr_t& settings,
- U32 next_owner_perm,
- const LLUUID& parent_id,
- std::string settings_name,
- inv_result_fn callback)
- {
- if (!gAgent.hasInventorySettings())
- {
- gNotifications.add("NoEnvironmentSettings");
- return;
- }
- LLTransactionID tid;
- tid.generate();
- if (settings_name.empty())
- {
- settings_name = settings->getName();
- }
- LLPointer<LLInventoryCallback> cb = new LLSettingsInventoryCB(settings,
- callback);
- create_inventory_item(parent_id, tid, settings_name, "",
- LLAssetType::AT_SETTINGS,
- LLInventoryType::IT_SETTINGS,
- (U8)settings->getSettingsTypeValue(),
- next_owner_perm, cb);
- }
- //static
- void LLEnvSettingsBase::onInventoryItemCreated(const LLUUID& inv_id,
- LLSettingsBase::ptr_t settings,
- inv_result_fn callback)
- {
- LLViewerInventoryItem* itemp = gInventory.getItem(inv_id);
- if (itemp)
- {
- LLPermissions perm = itemp->getPermissions();
- if (perm.getMaskEveryone() != PERM_COPY)
- {
- perm.setMaskEveryone(PERM_COPY);
- itemp->setPermissions(perm);
- itemp->updateServer(false);
- }
- }
- if (!settings)
- {
- // The item was created as new with no settings passed in. The
- // simulator should have given it the default for the type...
- // Check Id; no need to upload asset.
- LLUUID asset_id;
- if (itemp)
- {
- asset_id = itemp->getAssetUUID();
- }
- if (callback)
- {
- callback(asset_id, inv_id, LLUUID::null, LLSD());
- }
- return;
- }
- // We may need to update some inventory stuff here...
- updateInventoryItem(settings, inv_id, callback, false);
- }
- //static
- void LLEnvSettingsBase::updateInventoryItem(const LLSettingsBase::ptr_t& settings,
- const LLUUID& inv_item_id,
- inv_result_fn callback,
- bool update_name)
- {
- std::string cap_url =
- gAgent.getRegionCapability("UpdateSettingsAgentInventory");
- if (cap_url.empty())
- {
- llwarns << "No UpdateSettingsAgentInventory capability available. Cannot save setting."
- << llendl;
- return;
- }
- if (!gAgent.hasInventorySettings())
- {
- gNotifications.add("NoEnvironmentSettings");
- return;
- }
- LLViewerInventoryItem* itemp = gInventory.getItem(inv_item_id);
- if (itemp)
- {
- bool need_update = false;
- LLPointer<LLViewerInventoryItem> new_itemp =
- new LLViewerInventoryItem(itemp);
- if (settings->getFlag(LLSettingsBase::FLAG_NOTRANS) &&
- new_itemp->getPermissions().allowTransferBy(gAgentID))
- {
- LLPermissions perm(itemp->getPermissions());
- perm.setBaseBits(LLUUID::null, false, PERM_TRANSFER);
- perm.setOwnerBits(LLUUID::null, false, PERM_TRANSFER);
- new_itemp->setPermissions(perm);
- need_update = true;
- }
- if (update_name && settings->getName() != new_itemp->getName())
- {
- new_itemp->rename(settings->getName());
- settings->setName(new_itemp->getName()); // Account for corrections
- need_update = true;
- }
- if (need_update)
- {
- new_itemp->updateServer(false);
- gInventory.updateItem(new_itemp);
- gInventory.notifyObservers();
- }
- }
- std::stringstream buffer;
- LLSD settingdata(settings->getSettings());
- LLSDSerialize::serialize(settingdata, buffer,
- LLSDSerialize::LLSD_NOTATION);
- LLResourceUploadInfo::ptr_t info =
- std::make_shared<LLBufferedAssetUploadInfo>(inv_item_id,
- LLAssetType::AT_SETTINGS,
- buffer.str(),
- boost::bind(&LLEnvSettingsBase::onAgentAssetUploadComplete,
- _1, _2, _3, _4,
- settings,
- callback));
- LLViewerAssetUpload::enqueueInventoryUpload(cap_url, info);
- }
- //static
- void LLEnvSettingsBase::updateInventoryItem(const LLSettingsBase::ptr_t& settings,
- const LLUUID& object_id,
- const LLUUID& inv_item_id,
- inv_result_fn callback)
- {
- std::string cap_url =
- gAgent.getRegionCapability("UpdateSettingsAgentInventory");
- if (cap_url.empty())
- {
- llwarns << "No UpdateSettingsAgentInventory capability available. Cannot save setting."
- << llendl;
- return;
- }
- if (!gAgent.hasInventorySettings())
- {
- gNotifications.add("NoEnvironmentSettings");
- return;
- }
- std::stringstream buffer;
- LLSD settingdata(settings->getSettings());
- LLSDSerialize::serialize(settingdata, buffer,
- LLSDSerialize::LLSD_NOTATION);
- LLResourceUploadInfo::ptr_t info =
- std::make_shared<LLBufferedAssetUploadInfo>(object_id, inv_item_id,
- LLAssetType::AT_SETTINGS,
- buffer.str(),
- boost::bind(&LLEnvSettingsBase::onTaskAssetUploadComplete,
- _1, _2, _3, _4,
- settings,
- callback));
- LLViewerAssetUpload::enqueueInventoryUpload(cap_url, info);
- }
- //static
- void LLEnvSettingsBase::onAgentAssetUploadComplete(LLUUID item_id,
- LLUUID new_asset_id,
- LLUUID new_item_id,
- LLSD response,
- LLSettingsBase::ptr_t psettings,
- inv_result_fn callback)
- {
- llinfos << "Item Id: " << item_id << " - New asset Id: " << new_asset_id
- << " - New item Id: " << new_item_id << " - Response: " << response
- << llendl;
- psettings->setAssetId(new_asset_id);
- if (callback)
- {
- callback(new_asset_id, item_id, LLUUID::null, response);
- }
- }
- //static
- void LLEnvSettingsBase::onTaskAssetUploadComplete(LLUUID item_id,
- LLUUID task_id,
- LLUUID new_asset_id,
- LLSD response,
- LLSettingsBase::ptr_t settings,
- inv_result_fn callback)
- {
- llinfos << "Item Id: " << item_id << " - Task Id: " << task_id
- << " - New asset Id: " << new_asset_id << " - Response: "
- << response << " - Upload to task complete." << llendl;
- settings->setAssetId(new_asset_id);
- if (callback)
- {
- callback(new_asset_id, item_id, task_id, response);
- }
- }
- struct CallbackPtrStorage
- {
- LLEnvSettingsBase::asset_download_fn callback;
- };
- //static
- void LLEnvSettingsBase::getSettingsAsset(const LLUUID& asset_id,
- asset_download_fn callback)
- {
- CallbackPtrStorage* storage = new CallbackPtrStorage;
- storage->callback = callback;
- gAssetStoragep->getAssetData(asset_id, LLAssetType::AT_SETTINGS,
- onAssetDownloadComplete, (void*)storage,
- true);
- }
- //static
- void LLEnvSettingsBase::onAssetDownloadComplete(const LLUUID& asset_id,
- LLAssetType::EType,
- void* user_data, S32 status,
- LLExtStat ext_status)
- {
- if (!user_data) return; // Paranoia
- CallbackPtrStorage* storage = (CallbackPtrStorage*)user_data;
- asset_download_fn callback = storage->callback;
- delete storage;
- LLSettingsBase::ptr_t settings;
- if (!status)
- {
- LLFileSystem file(asset_id);
- S32 size = file.getSize();
- std::string buffer(size + 1, '\0');
- file.read((U8*)buffer.data(), size);
- std::stringstream llsdstream(buffer);
- LLSD llsdsettings;
- if (LLSDSerialize::deserialize(llsdsettings, llsdstream,
- LLSDSerialize::SIZE_UNLIMITED))
- {
- settings = createFromLLSD(llsdsettings);
- }
- if (!settings)
- {
- status = 1;
- llwarns << "Unable to create settings object for asset: "
- << asset_id << llendl;
- }
- else
- {
- settings->setAssetId(asset_id);
- }
- }
- else
- {
- llwarns << "Error retrieving asset: " << asset_id << ". Status code="
- << status << " (" << LLAssetStorage::getErrorString(status)
- << ") ext_status=" << (U32)ext_status << llendl;
- }
- if (callback)
- {
- callback(asset_id, settings, status, ext_status);
- }
- }
- //static
- bool LLEnvSettingsBase::exportFile(const LLSettingsBase::ptr_t& settings,
- const std::string& filename,
- LLSDSerialize::ELLSD_Serialize format)
- {
- try
- {
- std::ofstream file(filename, std::ios::out | std::ios::trunc);
- file.exceptions(std::ios_base::failbit | std::ios_base::badbit);
- if (!file)
- {
- llwarns << "Unable to open '" << filename << "' for writing."
- << llendl;
- return false;
- }
- LLSDSerialize::serialize(settings->getSettings(), file, format);
- }
- catch (const std::ios_base::failure& e)
- {
- llwarns << "Unable to save settings to file '" << filename
- << "': " << e.what() << llendl;
- return false;
- }
- return true;
- }
- //static
- LLSettingsBase::ptr_t LLEnvSettingsBase::importFile(const std::string& filename)
- {
- LLSD settings;
- try
- {
- std::ifstream file(filename, std::ios::in);
- file.exceptions(std::ios_base::failbit | std::ios_base::badbit);
- if (!file)
- {
- llwarns << "Unable to open '" << filename << "' for reading."
- << llendl;
- return LLSettingsBase::ptr_t();
- }
- if (!LLSDSerialize::deserialize(settings, file,
- LLSDSerialize::SIZE_UNLIMITED))
- {
- llwarns << "Unable to deserialize settings from '" << filename
- << "'" << llendl;
- return LLSettingsBase::ptr_t();
- }
- }
- catch (const std::ios_base::failure& e)
- {
- llwarns << "Unable to save settings to file '" << filename << "': "
- << e.what() << llendl;
- return LLSettingsBase::ptr_t();
- }
- return createFromLLSD(settings);
- }
- //static
- LLSettingsBase::ptr_t LLEnvSettingsBase::createFromLLSD(const LLSD& settings)
- {
- if (!settings.has(SETTING_TYPE))
- {
- llwarns << "No settings type in LLSD" << llendl;
- return LLSettingsBase::ptr_t();
- }
- std::string settingtype = settings[SETTING_TYPE].asString();
- if (settingtype == "daycycle")
- {
- return LLEnvSettingsDay::buildDay(settings);
- }
- if (settingtype == "sky")
- {
- return LLEnvSettingsSky::buildSky(settings);
- }
- if (settingtype == "water")
- {
- return LLEnvSettingsWater::buildWater(settings);
- }
- llwarns << "Unable to determine settings type for '" << settingtype
- << "'." << llendl;
- return LLSettingsBase::ptr_t();
- }
- //static
- LLSD LLEnvSettingsBase::readLegacyPresetData(std::string filename,
- std::string path,
- LLSD& messages)
- {
- // Ensure path got a dir delimiter appended
- if (!path.empty() && path.back() != LL_DIR_DELIM_CHR)
- {
- path += LL_DIR_DELIM_STR;
- }
- // Ensure name does not have dir delimiter prepended
- if (!filename.empty() && filename[0] == LL_DIR_DELIM_CHR)
- {
- filename = filename.substr(1);
- }
- std::string full_path = path + filename;
- llifstream xml_file;
- xml_file.open(full_path.c_str());
- if (!xml_file)
- {
- messages["REASONS"] = LLTrans::getString("SettingImportFileError",
- LLSDMap("FILE", full_path));
- llwarns << "Unable to open Windlight file: " << full_path << llendl;
- return LLSD();
- }
- LLSD params_data;
- LLPointer<LLSDParser> parser = new LLSDXMLParser();
- if (parser->parse(xml_file, params_data,
- LLSDSerialize::SIZE_UNLIMITED) == LLSDParser::PARSE_FAILURE)
- {
- xml_file.close();
- messages["REASONS"] = LLTrans::getString("SettingParseFileError",
- LLSDMap("FILE", full_path));
- return LLSD();
- }
- xml_file.close();
- LL_DEBUGS("EnvSettings") << "Loaded: " << full_path << LL_ENDL;
- return params_data;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // LLEnvSettingsSky class
- ///////////////////////////////////////////////////////////////////////////////
- LLEnvSettingsSky::LLEnvSettingsSky(const LLSD& data, bool is_advanced)
- : LLSettingsSky(data),
- mIsAdvanced(is_advanced),
- mSceneLightStrength(3.f)
- {
- }
- LLEnvSettingsSky::LLEnvSettingsSky()
- : LLSettingsSky(),
- mIsAdvanced(false),
- mSceneLightStrength(3.f)
- {
- }
- //virtual
- LLSettingsSky::ptr_t LLEnvSettingsSky::buildClone() const
- {
- LLSD settings = cloneSettings();
- const validation_list_t& validations = validationList();
- LLSD results = settingValidation(settings, validations);
- if (!results["success"].asBoolean())
- {
- llwarns << "Sky setting validation failed:\n" << results << llendl;
- return ptr_t();
- }
- U32 flags = getFlags();
- ptr_t skyp = std::make_shared<LLEnvSettingsSky>(settings);
- skyp->setFlags(flags);
- return skyp;
- }
- //virtual
- void LLEnvSettingsSky::updateSettings()
- {
- LLSettingsSky::updateSettings();
- // Note: calling these also causes an update of the positions in the sky
- // settings. It is therefore essential to call them here.
- LLVector3 sun_direction = getSunDirection();
- LLVector3 moon_direction = getMoonDirection();
- LL_DEBUGS("EnvSettings") << "Sun direction: " << sun_direction
- << " - Moon direction: " << moon_direction
- << LL_ENDL;
- #if 1 // Is this still needed at all ?
- // Set the extended environment textures
- gSky.setSunTextures(getSunTextureId(), getNextSunTextureId());
- gSky.setMoonTextures(getMoonTextureId(), getNextMoonTextureId());
- gSky.setCloudNoiseTextures(getCloudNoiseTextureId(),
- getNextCloudNoiseTextureId());
- gSky.setBloomTextures(getBloomTextureId(), getNextBloomTextureId());
- #endif
- // We want the dot prod of Sun with high noon vector (0,0,1), which is just
- // the z component
- F32 dp = llmax(sun_direction[2], 0.f); // Clamped to 0 when sun is down
- // Since WL scales everything by 2, there should always be at least a 2:1
- // brightness ratio between sunlight and point lights in windlight to
- // normalize point lights.
- static LLCachedControl<F32> dyn_rng(gSavedSettings,
- "RenderSunDynamicRange");
- F32 sun_dynamic_range = llmax((F32)dyn_rng, 0.0001f);
- mSceneLightStrength = 1.5f + 2.f * sun_dynamic_range * dp;
- gSky.setSunAndMoonDirectionsCFR(sun_direction, moon_direction);
- gSky.setSunScale(getSunScale());
- gSky.setMoonScale(getMoonScale());
- }
- //virtual
- void LLEnvSettingsSky::applySpecial(LLShaderUniforms* targetp)
- {
- LLShaderUniforms* shaderp = &(targetp)[LLGLSLShader::SG_DEFAULT];
- if (shaderp)
- {
- if (gUsePBRShaders)
- {
- shaderp->uniform3fv(LLShaderMgr::LIGHTNORM,
- gEnvironment.getClampedLightNorm().mV);
- }
- else
- {
- shaderp->uniform4fv(LLShaderMgr::LIGHTNORM,
- gEnvironment.getClampedLightNorm().mV);
- }
- shaderp->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL,
- gViewerCamera.getOrigin());
- }
- shaderp = &(targetp)[LLGLSLShader::SG_SKY];
- if (shaderp)
- {
- if (gUsePBRShaders)
- {
- shaderp->uniform3fv(LLShaderMgr::LIGHTNORM,
- gEnvironment.getClampedLightNorm().mV);
- }
- else
- {
- shaderp->uniform4fv(LLShaderMgr::LIGHTNORM,
- gEnvironment.getClampedLightNorm().mV);
- }
- // Legacy SETTING_CLOUD_SCROLL_RATE("cloud_scroll_rate") ?
- const LLColor3& col_c_p_d1 = getCloudPosDensity1();
- LLVector4 vect_c_p_d1(col_c_p_d1.mV[0], col_c_p_d1.mV[1],
- col_c_p_d1.mV[2], 1.f);
- LLVector4 cloud_scroll(gEnvironment.getCloudScrollDelta());
- // SL-13084 EEP added support for custom cloud textures: flip them
- // horizontally to match the preview of Clouds > Cloud Scroll.
- // Keep these shaders in sync:
- // - ee/class2/windlight/cloudsV.glsl
- // - ee/class1/deferred/cloudsV.glsl
- cloud_scroll[0] = -cloud_scroll[0];
- vect_c_p_d1 += cloud_scroll;
- LLColor4 cloud_color(getCloudColor(), 1.f);
- if (gUsePBRShaders)
- {
- shaderp->uniform3fv(LLShaderMgr::CLOUD_POS_DENSITY1,
- LLVector3(vect_c_p_d1).mV);
- shaderp->uniform3fv(LLShaderMgr::SUNLIGHT_COLOR,
- getSunlightColor().mV);
- shaderp->uniform3fv(LLShaderMgr::MOONLIGHT_COLOR,
- getMoonlightColor().mV);
- shaderp->uniform3fv(LLShaderMgr::CLOUD_COLOR,
- LLColor3(cloud_color).mV);
- }
- else
- {
- shaderp->uniform4fv(LLShaderMgr::CLOUD_POS_DENSITY1,
- vect_c_p_d1.mV);
- shaderp->uniform4fv(LLShaderMgr::SUNLIGHT_COLOR,
- gPipeline.mSunLightColor.mV);
- shaderp->uniform4fv(LLShaderMgr::MOONLIGHT_COLOR,
- gPipeline.mMoonLightColor.mV);
- shaderp->uniform4fv(LLShaderMgr::CLOUD_COLOR, cloud_color.mV);
- }
- }
- shaderp = &(targetp)[LLGLSLShader::SG_ANY];
- if (!shaderp)
- {
- return;
- }
- shaderp->uniform1f(LLShaderMgr::SCENE_LIGHT_STRENGTH, mSceneLightStrength);
- bool sun_up = getIsSunUp();
- shaderp->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up ? 1 : 0);
- F32 gamma = getGamma();
- if (gUsePBRShaders)
- {
- static LLCachedControl<F32> sun_scale(gSavedSettings,
- "RenderSkySunlightScale");
- static LLCachedControl<F32> brightness(gSavedSettings,
- "RenderSkySunlightBrightness");
- static LLCachedControl<bool> adjust(gSavedSettings,
- "RenderSkyAutoAdjustLegacy");
- F32 sun_light_scale = sun_scale;
- if (sun_light_scale <= 0.f)
- {
- #if 0 // Moon brightness = Sun brightness, so apply at night too... HB
- if (!sun_up)
- {
- // Leave night-time lighting untouched. HB
- sun_light_scale = 1.f;
- }
- else
- #endif
- {
- // Apply automatic Sun light scaling. HB
- F32 desired_brightness = llclamp(F32(brightness), 0.05f, 1.5f);
- F32 sun_brightness = getSunlightColor().brightness();
- sun_light_scale = desired_brightness / sun_brightness;
- }
- }
- shaderp->uniform1f(LLShaderMgr::SKY_SUNLIGHT_SCALE, sun_light_scale);
- static LLCachedControl<F32> sky_amb_scale(gSavedSettings,
- "RenderSkyAmbientScale");
- shaderp->uniform1f(LLShaderMgr::SKY_AMBIENT_SCALE, sky_amb_scale);
- static LLCachedControl<bool> desaturate(gSavedSettings,
- "RenderSkyReflectionDesaturate");
- static LLCachedControl<F32> desaturation(gSavedSettings,
- "RenderSkyReflectionDesaturation");
- static LLCachedControl<F32> darkening(gSavedSettings,
- "RenderSkyReflectionDarkening");
- static LLCachedControl<F32> hdr_adjust(gSavedSettings,
- "RenderSkyAutoAdjustHDRScale");
- static LLCachedControl<F32> amb_scale(gSavedSettings,
- "RenderSkyAutoAdjustAmbientScale");
- static LLCachedControl<F32> hor_scale(gSavedSettings,
- "RenderSkyAutoAdjustBlueHorizonScale");
- static LLCachedControl<F32> den_scale(gSavedSettings,
- "RenderSkyAutoAdjustBlueDensityScale");
- static LLCachedControl<F32> col_scale(gSavedSettings,
- "RenderSkyAutoAdjustSunColorScale");
- static LLCachedControl<F32> probe_amb(gSavedSettings,
- "RenderSkyAutoAdjustProbeAmbiance");
- static LLCachedControl<U32> reflections(gSavedSettings,
- "RenderReflectionProbes");
- // Sync sAutoAdjustProbeAmbiance with the debug settings now (it will
- // be used by getReflectionProbeAmbiance() below). HB
- F32 probe_ambiance = reflections ? probe_amb : 1.f;
- sAutoAdjustProbeAmbiance = probe_ambiance;
- // Note: when RenderReflectionProbes is 0, we must use 1.f for the
- // probe ambiance, else the rendering is way too dark. HB
- probe_ambiance = reflections ? getReflectionProbeAmbiance() : 1.f;
- F32 hdr_scale = 0.f;
- LLColor3 ambient;
- // During an irradiance map update, disable ambient lighting (direct
- // lighting only) and desaturate sky color (avoid tinting the world
- // blue).
- if (!gCubeSnapshot || gPipeline.mReflectionMapManager.isRadiancePass())
- {
- if (getReflectionProbeAmbiance() != 0.f)
- {
- ambient = getTotalAmbient();
- // Use a modifier here so 1.0 maps to the "most desirable"
- // default and the maximum value does not go off the rails.
- hdr_scale = 2.f * sqrtf(gamma);
- }
- else if (adjust && canAutoAdjust())
- {
- hdr_scale = hdr_adjust;
- // Auto-adjust legacy sky to take advantage of probe ambiance.
- ambient = getTotalAmbient() * F32(amb_scale);
- LLColor3 sun_diffuse = getSunlightColor() * col_scale;
- shaderp->uniform3fv(LLShaderMgr::SUNLIGHT_COLOR,
- sun_diffuse.mV);
- LLColor3 blue_density = getBlueDensity() * den_scale;
- LLColor3 blue_horizon = getBlueHorizon() * hor_scale;
- if (gCubeSnapshot && desaturate)
- {
- // Attenuate the blue hue if this is a reflection probe
- // render pass. HB
- blue_density.desaturate(desaturation, darkening);
- blue_horizon.desaturate(desaturation, darkening);
- }
- shaderp->uniform3fv(LLShaderMgr::BLUE_DENSITY,
- blue_density.mV);
- shaderp->uniform3fv(LLShaderMgr::BLUE_HORIZON,
- blue_horizon.mV);
- }
- else
- {
- hdr_scale = 1.f;
- ambient = getTotalAmbient();
- }
- }
- shaderp->uniform3fv(LLShaderMgr::AMBIENT, ambient.mV);
- if (hdr_scale)
- {
- shaderp->uniform1f(LLShaderMgr::SKY_HDR_SCALE, hdr_scale);
- }
- shaderp->uniform1f(LLShaderMgr::REFLECTION_PROBE_AMBIANCE,
- probe_ambiance);
- }
- else
- {
- shaderp->uniform4fv(LLShaderMgr::AMBIENT, getTotalAmbient().mV);
- shaderp->uniform1f(LLShaderMgr::DISPLAY_GAMMA,
- LLPipeline::RenderDeferredDisplayGamma);
- }
- shaderp->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR,
- getSunMoonGlowFactor());
- shaderp->uniform1f(LLShaderMgr::DENSITY_MULTIPLIER,
- getDensityMultiplier());
- shaderp->uniform1f(LLShaderMgr::DISTANCE_MULTIPLIER,
- getDistanceMultiplier());
- shaderp->uniform1f(LLShaderMgr::GAMMA, gamma);
- }
- //virtual
- const LLSettingsSky::parammapping_t& LLEnvSettingsSky::getParameterMap() const
- {
- static parammapping_t param_map;
- if (param_map.empty())
- {
- // LEGACY_ATMOSPHERICS
- //* TODO: default 'legacy' values duplicate the ones from functions
- // like getBlueDensity() find a better home for them. There is
- // LLSettingsSky::defaults(), but it does not contain everything since
- // it is geared towards creating new settings.
- param_map[SETTING_AMBIENT] =
- DefaultParam(LLShaderMgr::AMBIENT,
- LLColor3(0.25f, 0.25f, 0.25f).getValue());
- param_map[SETTING_BLUE_DENSITY] =
- DefaultParam(LLShaderMgr::BLUE_DENSITY,
- LLColor3(0.2447f, 0.4487f, 0.7599f).getValue());
- param_map[SETTING_BLUE_HORIZON] =
- DefaultParam(LLShaderMgr::BLUE_HORIZON,
- LLColor3(0.4954f, 0.4954f, 0.6399f).getValue());
- param_map[SETTING_HAZE_DENSITY] =
- DefaultParam(LLShaderMgr::HAZE_DENSITY, LLSD(0.7f));
- param_map[SETTING_HAZE_HORIZON] =
- DefaultParam(LLShaderMgr::HAZE_HORIZON, LLSD(0.19f));
- param_map[SETTING_DENSITY_MULTIPLIER] =
- DefaultParam(LLShaderMgr::DENSITY_MULTIPLIER, LLSD(0.0001f));
- param_map[SETTING_DISTANCE_MULTIPLIER] =
- DefaultParam(LLShaderMgr::DISTANCE_MULTIPLIER, LLSD(0.8f));
- // Following values are always present, so we can just zero these ones,
- // but used values from defaults()
- LLSD sky_defaults = LLSettingsSky::defaults();
- param_map[SETTING_CLOUD_POS_DENSITY2] =
- DefaultParam(LLShaderMgr::CLOUD_POS_DENSITY2,
- sky_defaults[SETTING_CLOUD_POS_DENSITY2]);
- param_map[SETTING_CLOUD_SCALE] =
- DefaultParam(LLShaderMgr::CLOUD_SCALE,
- sky_defaults[SETTING_CLOUD_SCALE]);
- param_map[SETTING_CLOUD_SHADOW] =
- DefaultParam(LLShaderMgr::CLOUD_SHADOW,
- sky_defaults[SETTING_CLOUD_SHADOW]);
- param_map[SETTING_GLOW] = DefaultParam(LLShaderMgr::GLOW,
- sky_defaults[SETTING_GLOW]);
- param_map[SETTING_MAX_Y] = DefaultParam(LLShaderMgr::MAX_Y,
- sky_defaults[SETTING_MAX_Y]);
- param_map[SETTING_CLOUD_VARIANCE] =
- DefaultParam(LLShaderMgr::CLOUD_VARIANCE,
- sky_defaults[SETTING_CLOUD_VARIANCE]);
- param_map[SETTING_MOON_BRIGHTNESS] =
- DefaultParam(LLShaderMgr::MOON_BRIGHTNESS,
- sky_defaults[SETTING_MOON_BRIGHTNESS]);
- param_map[SETTING_SKY_MOISTURE_LEVEL] =
- DefaultParam(LLShaderMgr::MOISTURE_LEVEL,
- sky_defaults[SETTING_SKY_MOISTURE_LEVEL]);
- param_map[SETTING_SKY_DROPLET_RADIUS] =
- DefaultParam(LLShaderMgr::DROPLET_RADIUS,
- sky_defaults[SETTING_SKY_DROPLET_RADIUS]);
- param_map[SETTING_SKY_ICE_LEVEL] =
- DefaultParam(LLShaderMgr::ICE_LEVEL,
- sky_defaults[SETTING_SKY_ICE_LEVEL]);
- // Legacy Windlight parameters used for conversion from EE to WL
- param_map[SETTING_SUNLIGHT_COLOR] =
- DefaultParam(LLShaderMgr::SUNLIGHT_COLOR,
- sky_defaults[SETTING_SUNLIGHT_COLOR]);
- param_map[SETTING_CLOUD_COLOR] =
- DefaultParam(LLShaderMgr::CLOUD_COLOR,
- sky_defaults[SETTING_CLOUD_COLOR]);
- param_map[SETTING_REFLECTION_PROBE_AMBIANCE] =
- DefaultParam(LLShaderMgr::REFLECTION_PROBE_AMBIANCE,
- sky_defaults[SETTING_REFLECTION_PROBE_AMBIANCE]);
- }
- return param_map;
- }
- //static
- LLSettingsSky::ptr_t LLEnvSettingsSky::buildSky(LLSD settings)
- {
- const validation_list_t& validations = validationList();
- LLSD results = settingValidation(settings, validations);
- if (!results["success"].asBoolean())
- {
- llwarns << "Sky setting validation failed:\n" << results << llendl;
- return ptr_t();
- }
- return std::make_shared<LLEnvSettingsSky>(settings, true);
- }
- //static
- LLSettingsSky::ptr_t LLEnvSettingsSky::buildDefaultSky()
- {
- static LLSD default_settings;
- if (!default_settings.size())
- {
- default_settings = LLSettingsSky::defaults();
- default_settings[SETTING_NAME] = std::string("_default_");
- const validation_list_t& validations = validationList();
- LLSD results = settingValidation(default_settings, validations);
- if (!results["success"].asBoolean())
- {
- llwarns << "Sky setting validation failed:\n" << results << llendl;
- return ptr_t();
- }
- }
- return std::make_shared<LLEnvSettingsSky>(default_settings);
- }
- //static
- LLSettingsSky::ptr_t LLEnvSettingsSky::buildFromLegacyPreset(const std::string& name,
- const LLSD& old_settings,
- LLSD& messages)
- {
- LLSD new_settings = translateLegacySettings(old_settings);
- if (new_settings.isUndefined())
- {
- messages["REASONS"] = LLTrans::getString("SettingTranslateError",
- LLSDMap("NAME", name));
- llwarns << "Sky setting translation failed:\n" << messages << llendl;
- return LLSettingsSky::ptr_t();
- }
- new_settings[SETTING_NAME] = name;
- const validation_list_t& validations = validationList();
- LLSD results = settingValidation(new_settings, validations);
- if (!results["success"].asBoolean())
- {
- messages["REASONS"] = LLTrans::getString("SettingValidationError",
- LLSDMap("NAME", name));
- llwarns << "Sky setting validation failed:\n" << results << llendl;
- return ptr_t();
- }
- return std::make_shared<LLEnvSettingsSky>(new_settings);
- }
- //static
- LLSettingsSky::ptr_t LLEnvSettingsSky::buildFromLegacyPresetFile(const std::string& name,
- const std::string& filename,
- const std::string& path,
- LLSD& messages)
- {
- LLSD legacy_data = LLEnvSettingsBase::readLegacyPresetData(filename, path,
- messages);
- if (!legacy_data)
- {
- // 'messages' is filled in by readLegacyPresetData
- llwarns << "Could not load legacy Windlight \"" << name << "\" from "
- << path << llendl;
- return ptr_t();
- }
- return buildFromLegacyPreset(LLURI::unescape(name), legacy_data, messages);
- }
- //static
- bool LLEnvSettingsSky::applyPresetByName(std::string name, bool ignore_case)
- {
- if (ignore_case)
- {
- // Normally, 'name' should already be passed as a lower-cased setting
- // name when 'ignore_case' is true, but let's assume it might not be...
- LLStringUtil::toLower(name);
- }
- // Start with inventory settings, when available...
- if (gAgent.hasInventorySettings())
- {
- const LLUUID& folder_id =
- gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS,
- false);
- if (folder_id.notNull())
- {
- LLEnvSettingsCollector collector;
- LLInventoryModel::cat_array_t cats;
- LLInventoryModel::item_array_t items;
- gInventory.collectDescendentsIf(folder_id, cats, items, false,
- collector);
- std::string preset;
- for (LLInventoryModel::item_array_t::iterator
- iter = items.begin(), end = items.end();
- iter != end; ++iter)
- {
- LLViewerInventoryItem* itemp = *iter;
- LLSettingsType::EType type = itemp->getSettingsType();
- if (type != LLSettingsType::ST_SKY)
- {
- continue;
- }
- preset = itemp->getName();
- if (ignore_case)
- {
- LLStringUtil::toLower(preset);
- }
- if (preset == name)
- {
- name = itemp->getName(); // Real name
- llinfos << "Using inventory settings: " << name << llendl;
- gEnvironment.setEnvironment(LLEnvironment::ENV_LOCAL,
- itemp->getAssetUUID());
- gEnvironment.setSelectedEnvironment(LLEnvironment::ENV_LOCAL,
- LLEnvironment::TRANSITION_INSTANT);
- if (gAutomationp)
- {
- gAutomationp->onWindlightChange(name, "", "");
- }
- return true;
- }
- }
- }
- }
- // Inventory settings failed; try Windlight settings... HB
- if (ignore_case)
- {
- // When ignoring the case, we must scan all usable WL settings to find
- // one which can match our lower-cased string, and then use that real
- // name to convert the corresponding WL settings.
- bool found = false;
- std::vector<std::string> presets =
- LLWLSkyParamMgr::getLoadedPresetsList();
- std::string preset;
- for (S32 i = 0, count = presets.size(); i < count; ++i)
- {
- preset = presets[i];
- LLStringUtil::toLower(preset);
- if (preset == name)
- {
- // Retain the real, case-sensitive name
- name = presets[i];
- found = true;
- break;
- }
- }
- if (!found)
- {
- return false;
- }
- }
- std::string filename, path;
- if (LLWLDayCycle::findPresetFile(name, "skies", "", filename, path))
- {
- LLSD msg;
- LLSettingsSky::ptr_t skyp = buildFromLegacyPresetFile(name, filename,
- path, msg);
- if (skyp)
- {
- llinfos << "Using Windlight settings: " << name << llendl;
- gEnvironment.setEnvironment(LLEnvironment::ENV_LOCAL, skyp);
- gEnvironment.setSelectedEnvironment(LLEnvironment::ENV_LOCAL,
- LLEnvironment::TRANSITION_INSTANT);
- if (gAutomationp)
- {
- gAutomationp->onWindlightChange(name, "", "");
- }
- return true;
- }
- }
- return false;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // LLEnvSettingsWater class
- ///////////////////////////////////////////////////////////////////////////////
- LLEnvSettingsWater::LLEnvSettingsWater(const LLSD& data)
- : LLSettingsWater(data)
- {
- }
- LLEnvSettingsWater::LLEnvSettingsWater()
- : LLSettingsWater()
- {
- }
- //virtual
- LLSettingsWater::ptr_t LLEnvSettingsWater::buildClone() const
- {
- LLSD settings = cloneSettings();
- const validation_list_t& validations = validationList();
- LLSD results = settingValidation(settings, validations);
- if (!results["success"].asBoolean())
- {
- llwarns << "Water setting validation failed:\n" << results << llendl;
- return ptr_t();
- }
- U32 flags = getFlags();
- ptr_t waterp = std::make_shared<LLEnvSettingsWater>(settings);
- waterp->setFlags(flags);
- return waterp;
- }
- //virtual
- void LLEnvSettingsWater::updateSettings()
- {
- LLSettingsWater::updateSettings();
- LLDrawPoolWater* poolp =
- (LLDrawPoolWater*)gPipeline.getPool(LLDrawPool::POOL_WATER);
- if (!poolp) return;
- poolp->setTransparentTextures(getTransparentTextureID(),
- getNextTransparentTextureID());
- poolp->setNormalMaps(getNormalMapID(), getNextNormalMapID());
- }
- //virtual
- void LLEnvSettingsWater::applySpecial(LLShaderUniforms* targetp)
- {
- if (!targetp || !gAgent.getRegion())
- {
- return;
- }
- S32 group = gUsePBRShaders ? LLGLSLShader::SG_ANY : LLGLSLShader::SG_WATER;
- LLShaderUniforms* shaderp = &(targetp)[group];
- if (!shaderp)
- {
- return;
- }
- F32 water_height = gPipeline.mWaterHeight;
- if (gViewerCamera.cameraUnderWater())
- {
- // When the camera is under water, use the water height at the camera
- // position.
- LLViewerRegion* regionp =
- gWorld.getRegionFromPosAgent(gViewerCamera.getOrigin());
- if (regionp)
- {
- water_height = regionp->getWaterHeight();
- }
- }
- if (!gUsePBRShaders)
- {
- water_height += 0.1f; // Z-fudging for EE/WL rendering
- }
- // Transform water plane to eye space
- LLVector4a norm(0.f, 0.f, 1.f);
- LLVector4a ep(0.f, 0.f, water_height);
- const LLMatrix4a& mat = gGLModelView;
- LLMatrix4a invtrans = mat;
- invtrans.invert();
- invtrans.transpose();
- F32* invtransp = invtrans.getF32ptr();
- invtransp[3] = invtransp[7] = invtransp[11] = 0.f;
- invtrans.perspectiveTransform(norm, norm);
- norm.normalize3fast();
- mat.affineTransform(ep, ep);
- ep.setAllDot3(ep, norm);
- ep.negate();
- norm.copyComponent<3>(ep);
- shaderp->uniform4fv(LLShaderMgr::WATER_WATERPLANE, norm.getF32ptr());
- LLPipeline::sWaterPlane = norm;
- // Mirror
- norm.loadua(gPipeline.mHeroProbeManager.mMirrorNormal.mV);
- ep.loadua(gPipeline.mHeroProbeManager.mMirrorPosition.mV);
- invtrans.perspectiveTransform(norm, norm);
- norm.normalize3fast();
- mat.affineTransform(ep, ep);
- ep.setAllDot3(ep, norm);
- ep.negate();
- norm.copyComponent<3>(ep);
- shaderp->uniform4fv(LLShaderMgr::CLIP_PLANE, norm.getF32ptr());
- if (gPipeline.mHeroProbeManager.isMirrorPass())
- {
- shaderp->uniform1f(LLShaderMgr::MIRROR_FLAG, 1.f);
- }
- else
- {
- shaderp->uniform1f(LLShaderMgr::MIRROR_FLAG, 0.f);
- }
- LLVector4 light_direction = gEnvironment.getClampedLightNorm();
- F32 fog_ks = 1.f / llmax(light_direction.mV[2], WATER_FOG_LIGHT_CLAMP);
- shaderp->uniform1f(LLShaderMgr::WATER_FOGKS, fog_ks);
- bool underwater = gPipeline.mEyeAboveWater < 0.f;
- F32 water_fog_density = getModifiedWaterFogDensity(underwater);
- shaderp->uniform1f(LLShaderMgr::WATER_FOGDENSITY, water_fog_density);
- F32 blend_factor = getBlendFactor();
- shaderp->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
- if (gUsePBRShaders)
- {
- LLColor4 fog_color(getWaterFogColor());
- shaderp->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, fog_color.mV);
- shaderp->uniform3fv(LLShaderMgr::WATER_FOGCOLOR_LINEAR,
- linearColor3(fog_color).mV);
- // Update to normal lightnorm, water shader itself will use rotated
- // lightnorm as necessary
- shaderp->uniform3fv(LLShaderMgr::LIGHTNORM, light_direction.mV);
- }
- else
- {
- LLColor4 fog_color(getWaterFogColor(), 0.f);
- shaderp->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, fog_color.mV);
- // Update to normal lightnorm, water shader itself will use rotated
- // lightnorm as necessary
- shaderp->uniform4fv(LLShaderMgr::LIGHTNORM, light_direction.mV);
- }
- }
- //virtual
- const LLSettingsWater::parammapping_t& LLEnvSettingsWater::getParameterMap() const
- {
- static parammapping_t param_map;
- #if 0 // Disabled also in LL's viewer
- if (param_map.empty())
- {
- LLSD water_defaults = LLSettingsWater::defaults();
- param_map[SETTING_FOG_COLOR] =
- DefaultParam(LLShaderMgr::WATER_FOGCOLOR,
- water_defaults[SETTING_FOG_COLOR]);
- // Let this get set by LLEnvSettingsWater::applySpecial so that it can
- // properly reflect the underwater modifier
- param_map[SETTING_FOG_DENSITY] =
- DefaultParam(LLShaderMgr::WATER_FOGDENSITY,
- water_defaults[SETTING_FOG_DENSITY]);
- }
- #endif
- return param_map;
- }
- //static
- LLSettingsWater::ptr_t LLEnvSettingsWater::buildWater(LLSD settings)
- {
- const validation_list_t& validations = validationList();
- LLSD results = settingValidation(settings, validations);
- if (!results["success"].asBoolean())
- {
- llwarns << "Water setting validation failed:\n" << results << llendl;
- return ptr_t();
- }
- return std::make_shared<LLEnvSettingsWater>(settings);
- }
- //static
- LLSettingsWater::ptr_t LLEnvSettingsWater::buildDefaultWater()
- {
- static LLSD default_settings;
- if (!default_settings.size())
- {
- default_settings = defaults();
- default_settings[SETTING_NAME] = "_default_";
- const validation_list_t& validations = validationList();
- LLSD results = settingValidation(default_settings, validations);
- if (!results["success"].asBoolean())
- {
- llwarns << "Water setting validation failed:\n" << results
- << llendl;
- return ptr_t();
- }
- }
- return std::make_shared<LLEnvSettingsWater>(default_settings);
- }
- //static
- LLSettingsWater::ptr_t LLEnvSettingsWater::buildFromLegacyPreset(const std::string& name,
- const LLSD& old_settings,
- LLSD& messages)
- {
- LLSD new_settings(translateLegacySettings(old_settings));
- if (new_settings.isUndefined())
- {
- messages["REASONS"] = LLTrans::getString("SettingTranslateError",
- LLSDMap("NAME", name));
- llwarns << "Water setting translation failed:\n" << messages << llendl;
- return LLSettingsWater::ptr_t();
- }
- new_settings[SETTING_NAME] = name;
- const validation_list_t& validations = validationList();
- LLSD results = settingValidation(new_settings, validations);
- if (!results["success"].asBoolean())
- {
- messages["REASONS"] = LLTrans::getString("SettingValidationError", name);
- llwarns << "Water setting validation failed:\n" << results << llendl;
- return ptr_t();
- }
- return std::make_shared<LLEnvSettingsWater>(new_settings);
- }
- //static
- LLSettingsWater::ptr_t LLEnvSettingsWater::buildFromLegacyPresetFile(const std::string& name,
- const std::string& filename,
- const std::string& path,
- LLSD& messages)
- {
- LLSD legacy_data = LLEnvSettingsBase::readLegacyPresetData(filename, path,
- messages);
- if (!legacy_data)
- {
- // 'messages' is filled in by readLegacyPresetData
- llwarns << "Could not load legacy Windlight \"" << name << "\" from "
- << path << llendl;
- return ptr_t();
- }
- return buildFromLegacyPreset(LLURI::unescape(name), legacy_data, messages);
- }
- //static
- bool LLEnvSettingsWater::applyPresetByName(std::string name, bool ignore_case)
- {
- if (ignore_case)
- {
- // Normally, 'name' should already be passed as a lower-cased setting
- // name when 'ignore_case' is true, but let's assume it might not be...
- LLStringUtil::toLower(name);
- }
- // Start with inventory settings, when available...
- if (gAgent.hasInventorySettings())
- {
- const LLUUID& folder_id =
- gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS,
- false);
- if (folder_id.notNull())
- {
- LLEnvSettingsCollector collector;
- LLInventoryModel::cat_array_t cats;
- LLInventoryModel::item_array_t items;
- gInventory.collectDescendentsIf(folder_id, cats, items, false,
- collector);
- std::string preset;
- for (LLInventoryModel::item_array_t::iterator
- iter = items.begin(), end = items.end();
- iter != end; ++iter)
- {
- LLViewerInventoryItem* itemp = *iter;
- LLSettingsType::EType type = itemp->getSettingsType();
- if (type != LLSettingsType::ST_WATER)
- {
- continue;
- }
- preset = itemp->getName();
- if (ignore_case)
- {
- LLStringUtil::toLower(preset);
- }
- if (preset == name)
- {
- name = itemp->getName(); // Real name
- llinfos << "Using inventory settings: " << name << llendl;
- gEnvironment.setEnvironment(LLEnvironment::ENV_LOCAL,
- itemp->getAssetUUID());
- gEnvironment.setSelectedEnvironment(LLEnvironment::ENV_LOCAL,
- LLEnvironment::TRANSITION_INSTANT);
- if (gAutomationp)
- {
- gAutomationp->onWindlightChange("", name, "");
- }
- return true;
- }
- }
- }
- }
- // Inventory settings failed; try Windlight settings...
- if (ignore_case)
- {
- // When ignoring the case, we must scan all usable WL settings to find
- // one which can match our lower-cased string, and then use that real
- // name to convert the corresponding WL settings.
- bool found = false;
- std::vector<std::string> presets =
- LLWLWaterParamMgr::getLoadedPresetsList();
- std::string preset;
- for (S32 i = 0, count = presets.size(); i < count; ++i)
- {
- preset = presets[i];
- LLStringUtil::toLower(preset);
- if (preset == name)
- {
- // Retain the real, case-sensitive name
- name = presets[i];
- found = true;
- break;
- }
- }
- if (!found)
- {
- return false;
- }
- }
- std::string filename, path;
- if (LLWLDayCycle::findPresetFile(name, "water", "", filename, path))
- {
- LLSD msg;
- LLSettingsWater::ptr_t waterp = buildFromLegacyPresetFile(name,
- filename,
- path, msg);
- if (waterp)
- {
- llinfos << "Using Windlight settings: " << name << llendl;
- gEnvironment.setEnvironment(LLEnvironment::ENV_LOCAL, waterp);
- gEnvironment.setSelectedEnvironment(LLEnvironment::ENV_LOCAL,
- LLEnvironment::TRANSITION_INSTANT);
- if (gAutomationp)
- {
- gAutomationp->onWindlightChange("", name, "");
- }
- return true;
- }
- }
- return false;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // LLEnvSettingsDay class
- ///////////////////////////////////////////////////////////////////////////////
- LLEnvSettingsDay::LLEnvSettingsDay(const LLSD& data)
- : LLSettingsDay(data)
- {
- }
- LLEnvSettingsDay::LLEnvSettingsDay()
- : LLSettingsDay()
- {
- }
- //virtual
- LLSettingsDay::ptr_t LLEnvSettingsDay::buildClone() const
- {
- LLSD settings = cloneSettings();
- const validation_list_t& validations = validationList();
- LLSD results = settingValidation(settings, validations);
- if (!results["success"].asBoolean())
- {
- llwarns << "Day setting validation failed;\n" << results << llendl;
- return ptr_t();
- }
- ptr_t dayp = std::make_shared<LLEnvSettingsDay>(settings);
- U32 flags = getFlags();
- if (flags)
- {
- dayp->setFlags(flags);
- }
- dayp->initialize();
- return dayp;
- }
- //virtual
- LLSettingsDay::ptr_t LLEnvSettingsDay::buildDeepCloneAndUncompress() const
- {
- U32 flags = getFlags();
- // No need for SETTING_TRACKS or SETTING_FRAMES, so take base LLSD
- LLSD settings = llsd_clone(mSettings);
- ptr_t day_clone = std::make_shared<LLEnvSettingsDay>(settings);
- for (S32 i = 0; i < LLSettingsDay::TRACK_MAX; ++i)
- {
- const cycle_track_t& track = getCycleTrackConst(i);
- cycle_track_t::const_iterator iter = track.begin();
- while (iter != track.end())
- {
- // 'Unpack', usually for editing
- // - frames 'share' settings multiple times
- // - settings can reuse LLSDs they were initialized from
- // We do not want for edited frame to change multiple frames in
- // same track, so do a clone
- day_clone->setSettingsAtKeyframe(iter->second->buildDerivedClone(),
- iter->first, i);
- ++iter;
- }
- }
- day_clone->setFlags(flags);
- return day_clone;
- }
- //virtual
- LLSettingsSky::ptr_t LLEnvSettingsDay::getDefaultSky() const
- {
- return LLEnvSettingsSky::buildDefaultSky();
- }
- //virtual
- LLSettingsWater::ptr_t LLEnvSettingsDay::getDefaultWater() const
- {
- return LLEnvSettingsWater::buildDefaultWater();
- }
- //virtual
- LLSettingsSky::ptr_t LLEnvSettingsDay::buildSky(const LLSD& settings) const
- {
- LLSettingsSky::ptr_t skyp = std::make_shared<LLEnvSettingsSky>(settings);
- return skyp && skyp->validate() ? skyp : LLSettingsSky::ptr_t();
- }
- //virtual
- LLSettingsWater::ptr_t LLEnvSettingsDay::buildWater(const LLSD& settings) const
- {
- LLSettingsWater::ptr_t waterp =
- std::make_shared<LLEnvSettingsWater>(settings);
- return waterp && waterp->validate() ? waterp : LLSettingsWater::ptr_t();
- }
- //static
- LLSettingsDay::ptr_t LLEnvSettingsDay::buildDay(LLSD settings)
- {
- const validation_list_t& validations = validationList();
- LLSD results = settingValidation(settings, validations);
- if (!results["success"].asBoolean())
- {
- llwarns << "Day setting validation failed:\n" << results << llendl;
- LLSettingsDay::ptr_t();
- }
- ptr_t dayp = std::make_shared<LLEnvSettingsDay>(settings);
- if (dayp)
- {
- dayp->initialize();
- }
- return dayp;
- }
- //static
- LLSettingsDay::ptr_t LLEnvSettingsDay::buildDefaultDayCycle()
- {
- static ptr_t default_dayp;
- if (default_dayp)
- {
- return default_dayp->buildClone();
- }
- #if 1 // Default EE day cycle is borked... Use Windlight's "Default" day
- // cycle instead. HB
- // *TODO: fix LLSettingsDay::defaults() so that it would *actually*
- // correspond to the default Windlight day cycle...
- std::string filename, path;
- if (LLWLDayCycle::findPresetFile("Default", "days", "", filename, path))
- {
- LLSD messages;
- default_dayp = buildFromLegacyPresetFile("_default_", filename, path,
- messages);
- if (default_dayp)
- {
- return default_dayp->buildClone();
- }
- }
- else
- {
- llwarns << "Could not find any Default.xml Windlight day cycle file."
- << llendl;
- }
- #endif
- // Fallback path...
- LLSD default_settings = LLSettingsDay::defaults();
- default_settings[SETTING_NAME] = "_default_";
- const LLSettingsDay::validation_list_t& validations =
- LLSettingsDay::validationList();
- LLSD results = LLSettingsDay::settingValidation(default_settings,
- validations);
- if (!results["success"].asBoolean())
- {
- llwarns << "Day setting validation failed:\n" << results << llendl;
- return ptr_t();
- }
- default_dayp = std::make_shared<LLEnvSettingsDay>(default_settings);
- default_dayp->initialize();
- return default_dayp->buildClone();
- }
- //static
- LLSettingsDay::ptr_t LLEnvSettingsDay::buildFromLegacyPreset(const std::string& name,
- const std::string& path,
- const LLSD& old_settings,
- LLSD& messages)
- {
- LL_DEBUGS("EnvSettings") << "Loading '" << name << "' day cycle from: "
- << path << LL_ENDL;
- LLSD skytrack = LLSD::emptyArray();
- std::set<std::string> framenames;
- for (LLSD::array_const_iterator it = old_settings.beginArray(),
- end = old_settings.endArray();
- it != end; ++it)
- {
- std::string framename = (*it)[1].asString();
- LLSD entry = LLSDMap(SETTING_KEYKFRAME, (*it)[0].asReal())
- (SETTING_KEYNAME, "sky:" + framename);
- framenames.emplace(framename);
- skytrack.append(entry);
- LL_DEBUGS("EnvSettings") << "Added sky track: " << framename
- << LL_ENDL;
- }
- LLSD watertrack = llsd::array(LLSDMap(SETTING_KEYKFRAME, LLSD::Real(0.f))
- (SETTING_KEYNAME, "water:Default"));
- LL_DEBUGS("EnvSettings") << "Added water track: Default" << LL_ENDL;
- LLSD new_settings(defaults());
- new_settings[SETTING_TRACKS] = llsd::array(watertrack, skytrack);
- LLSD frames(LLSD::emptyMap());
- std::string filename, actual_path;
- LLWLDayCycle::findPresetFile("Default", "water", path, filename,
- actual_path);
- LLSettingsWater::ptr_t waterp =
- LLEnvSettingsWater::buildFromLegacyPresetFile("Default", filename,
- actual_path, messages);
- if (!waterp)
- {
- llwarns << "Failed to load Default water." << llendl;
- // 'messages' is filled in by buildFromLegacyPresetFile
- return LLSettingsDay::ptr_t();
- }
- LL_DEBUGS("EnvSettings") << "Loaded Default water from: "
- << actual_path << filename << LL_ENDL;
- frames["water:Default"] = waterp->getSettings();
- for (std::set<std::string>::iterator it = framenames.begin(),
- end = framenames.end();
- it != end; ++it)
- {
- LLWLDayCycle::findPresetFile(*it, "skies", path, filename,
- actual_path);
- LLSettingsSky::ptr_t skyp =
- LLEnvSettingsSky::buildFromLegacyPresetFile(*it, filename,
- actual_path, messages);
- if (!skyp)
- {
- llwarns << "Failed to load sky: " << *it << llendl;
- // 'messages' is filled in by buildFromLegacyPresetFile
- return LLSettingsDay::ptr_t();
- }
- LL_DEBUGS("EnvSettings") << "Loaded '" << *it << "' sky from: "
- << actual_path << filename << LL_ENDL;
- frames["sky:" + *it] = skyp->getSettings();
- }
- new_settings[SETTING_FRAMES] = frames;
- const LLSettingsDay::validation_list_t& validations =
- LLSettingsDay::validationList();
- LLSD results = LLSettingsDay::settingValidation(new_settings,
- validations);
- if (!results["success"].asBoolean())
- {
- messages["REASONS"] = LLTrans::getString("SettingValidationError",
- LLSDMap("NAME", name));
- llwarns << "Day setting validation failed:\n" << results << llendl;
- return LLSettingsDay::ptr_t();
- }
- LL_DEBUGS("EnvSettings") << "Creating EE settings from LLSD: "
- << ll_pretty_print_sd(new_settings) << LL_ENDL;
- LLSettingsDay::ptr_t dayp =
- std::make_shared<LLEnvSettingsDay>(new_settings);
- dayp->initialize();
- return dayp;
- }
- //static
- LLSettingsDay::ptr_t LLEnvSettingsDay::buildFromLegacyPresetFile(const std::string& name,
- const std::string& filename,
- const std::string& path,
- LLSD& messages)
- {
- LLSD legacy_data = LLEnvSettingsBase::readLegacyPresetData(filename, path,
- messages);
- if (!legacy_data)
- {
- // 'messages' is filled in by readLegacyPresetData
- llwarns << "Could not load legacy Windlight \"" << name << "\" from "
- << path << llendl;
- return ptr_t();
- }
- // Name for LLSettingsDay only, path to get related files from filesystem
- return buildFromLegacyPreset(LLURI::unescape(name), path, legacy_data,
- messages);
- }
- //static
- LLSettingsDay::ptr_t LLEnvSettingsDay::buildFromLegacyMessage(const LLUUID& region_id,
- LLSD daycycle,
- LLSD skydefs,
- LLSD waterdef)
- {
- LLSD frames(LLSD::emptyMap());
- std::string newname;
- for (LLSD::map_iterator it = skydefs.beginMap(), end = skydefs.endMap();
- it != end; ++it)
- {
- newname = "sky:" + it->first;
- LLSD new_settings = LLSettingsSky::translateLegacySettings(it->second);
- new_settings[SETTING_NAME] = newname;
- frames[newname] = new_settings;
- llwarns << "Created region sky '" << newname << "'" << llendl;
- }
- LLSD watersettings = LLSettingsWater::translateLegacySettings(waterdef);
- std::string watername = "water:"+ watersettings[SETTING_NAME].asString();
- watersettings[SETTING_NAME] = watername;
- frames[watername] = watersettings;
- LLSD watertrack =
- llsd::array(LLSDMap(SETTING_KEYKFRAME, LLSD::Real(0.f))
- (SETTING_KEYNAME, watername));
- LLSD skytrack(LLSD::emptyArray());
- for (LLSD::array_const_iterator it = daycycle.beginArray(),
- end = daycycle.endArray();
- it != end; ++it)
- {
- LLSD entry =
- LLSDMap(SETTING_KEYKFRAME, (*it)[0].asReal())
- (SETTING_KEYNAME, "sky:" + (*it)[1].asString());
- skytrack.append(entry);
- }
- LLSD new_settings =
- LLSDMap(SETTING_NAME, "Region (legacy)")
- (SETTING_TRACKS, llsd::array(watertrack, skytrack))
- (SETTING_FRAMES, frames)
- (SETTING_TYPE, "daycycle");
- const LLSettingsSky::validation_list_t& validations =
- LLSettingsDay::validationList();
- LLSD results = LLSettingsDay::settingValidation(new_settings, validations);
- if (!results["success"].asBoolean())
- {
- llwarns << "Day setting validation failed:\n" << results << llendl;
- return LLSettingsDay::ptr_t();
- }
- LLSettingsDay::ptr_t dayp =
- std::make_shared<LLEnvSettingsDay>(new_settings);
- if (dayp)
- {
- // true for validation; either validate here, or when cloning for
- // floater.
- dayp->initialize(true);
- }
- return dayp;
- }
- //static
- LLSettingsDay::ptr_t LLEnvSettingsDay::buildFromEnvironmentMessage(LLSD settings)
- {
- const LLSettingsDay::validation_list_t& validations =
- LLSettingsDay::validationList();
- LLSD results = LLSettingsDay::settingValidation(settings, validations);
- if (!results["success"].asBoolean())
- {
- llwarns << "Day setting validation failed:\n" << results << llendl;
- return ptr_t();
- }
- ptr_t dayp = std::make_shared<LLEnvSettingsDay>(settings);
- dayp->initialize();
- return dayp;
- }
- //static
- void LLEnvSettingsDay::buildFromOtherSetting(LLSettingsBase::ptr_t settings,
- asset_built_fn cb)
- {
- if (settings->getSettingsType() == "daycycle")
- {
- if (cb)
- {
- cb(std::static_pointer_cast<LLSettingsDay>(settings));
- }
- return;
- }
- LLEnvSettingsBase::getSettingsAsset(getDefaultAssetId(),
- [settings, cb](LLUUID,
- LLSettingsBase::ptr_t dayp,
- S32, LLExtStat)
- {
- combineIntoDayCycle(std::static_pointer_cast<LLSettingsDay>(dayp),
- settings, cb);
- });
- }
- //static
- void LLEnvSettingsDay::combineIntoDayCycle(LLSettingsDay::ptr_t dayp,
- LLSettingsBase::ptr_t settings,
- asset_built_fn cb)
- {
- if (settings->getSettingsType() == "sky")
- {
- dayp->setName("sky: " + settings->getName());
- dayp->clearCycleTrack(1);
- dayp->setSettingsAtKeyframe(settings, 0.0, 1);
- }
- else if (settings->getSettingsType() == "water")
- {
- dayp->setName("water: " + settings->getName());
- dayp->clearCycleTrack(0);
- dayp->setSettingsAtKeyframe(settings, 0.0, 0);
- }
- else
- {
- dayp.reset();
- }
- if (cb)
- {
- cb(dayp);
- }
- }
- //static
- bool LLEnvSettingsDay::applyPresetByName(std::string name, bool ignore_case)
- {
- if (ignore_case)
- {
- // Normally, 'name' should already be passed as a lower-cased setting
- // name when 'ignore_case' is true, but let's assume it might not be...
- LLStringUtil::toLower(name);
- }
- // Start with inventory settings, when available...
- if (gAgent.hasInventorySettings())
- {
- const LLUUID& folder_id =
- gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS,
- false);
- if (folder_id.notNull())
- {
- LLEnvSettingsCollector collector;
- LLInventoryModel::cat_array_t cats;
- LLInventoryModel::item_array_t items;
- gInventory.collectDescendentsIf(folder_id, cats, items, false,
- collector);
- std::string preset;
- for (LLInventoryModel::item_array_t::iterator
- iter = items.begin(), end = items.end();
- iter != end; ++iter)
- {
- LLViewerInventoryItem* itemp = *iter;
- LLSettingsType::EType type = itemp->getSettingsType();
- if (type != LLSettingsType::ST_DAYCYCLE)
- {
- continue;
- }
- preset = itemp->getName();
- if (ignore_case)
- {
- LLStringUtil::toLower(preset);
- }
- if (preset == name)
- {
- name = itemp->getName(); // Real name
- llinfos << "Using inventory settings: " << name << llendl;
- gEnvironment.setEnvironment(LLEnvironment::ENV_LOCAL,
- itemp->getAssetUUID());
- gEnvironment.setSelectedEnvironment(LLEnvironment::ENV_LOCAL,
- LLEnvironment::TRANSITION_INSTANT);
- if (gAutomationp)
- {
- gAutomationp->onWindlightChange("", "", name);
- }
- return true;
- }
- }
- }
- }
- // Inventory settings failed; try Windlight settings...
- if (ignore_case)
- {
- // When ignoring the case, we must scan all usable WL settings to find
- // one which can match our lower-cased string, and then use that real
- // name to convert the corresponding WL settings.
- bool found = false;
- std::vector<std::string> presets =
- LLWLDayCycle::getLoadedPresetsList();
- std::string preset;
- for (S32 i = 0, count = presets.size(); i < count; ++i)
- {
- preset = presets[i];
- LLStringUtil::toLower(preset);
- if (preset == name)
- {
- // Retain the real, case-sensitive name
- name = presets[i];
- found = true;
- break;
- }
- }
- if (!found)
- {
- return false;
- }
- }
- std::string filename, path;
- if (LLWLDayCycle::findPresetFile(name, "days", "", filename, path))
- {
- LLSD msg;
- LLSettingsDay::ptr_t dayp = buildFromLegacyPresetFile(name, filename,
- path, msg);
- if (dayp)
- {
- llinfos << "Using Windlight settings: " << name << llendl;
- gEnvironment.setEnvironment(LLEnvironment::ENV_LOCAL, dayp);
- gEnvironment.setSelectedEnvironment(LLEnvironment::ENV_LOCAL,
- LLEnvironment::TRANSITION_INSTANT);
- if (gAutomationp)
- {
- gAutomationp->onWindlightChange("", "", name);
- }
- return true;
- }
- }
- return false;
- }
|