diff options
| author | Graham Linden <graham@lindenlab.com> | 2018-10-18 21:18:40 +0100 | 
|---|---|---|
| committer | Graham Linden <graham@lindenlab.com> | 2018-10-18 21:18:40 +0100 | 
| commit | 3447621a15c14a6a23a9827cfbb2e244ce91e8c0 (patch) | |
| tree | 06d3c71c052c1776b0e6c103d919c835266f67d4 | |
| parent | d8ed800991feaa3264f36f8e62f054bf0fe4d448 (diff) | |
Port sim-side changes to back-conversion of new settings to legacy.
Fix validating of density multiplier to clamp >= 0.0001f.
Port fix to setter for ambient color in sky settings.
| -rw-r--r-- | indra/llinventory/llsettingssky.cpp | 41 | ||||
| -rw-r--r-- | indra/newview/llsettingsvo.cpp | 2724 | 
2 files changed, 1406 insertions, 1359 deletions
| diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp index 61e31df663..0093d84cef 100644 --- a/indra/llinventory/llsettingssky.cpp +++ b/indra/llinventory/llsettingssky.cpp @@ -510,9 +510,9 @@ LLSettingsSky::validation_list_t LLSettingsSky::validationList()                  LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),                  LLSD(LLSDArray(3.0f)(3.0f)(3.0f)("*")))));          validation.push_back(Validator(SETTING_DENSITY_MULTIPLIER,  false,  LLSD::TypeReal,   -            boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(2.0f))))); +            boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0001f)(2.0f)))));          validation.push_back(Validator(SETTING_DISTANCE_MULTIPLIER, false,  LLSD::TypeReal,   -            boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1000.0f))))); +            boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0001f)(1000.0f)))));          validation.push_back(Validator(SETTING_BLOOM_TEXTUREID,     true,  LLSD::TypeUUID)); @@ -870,7 +870,7 @@ LLSD LLSettingsSky::translateLegacySettings(const LLSD& legacy)          // original WL moon dir was diametrically opposed to the sun dir          LLQuaternion moonquat = convert_azimuth_and_altitude_to_quat(azimuth + F_PI, -altitude); -        newsettings[SETTING_SUN_ROTATION] = sunquat.getValue(); +        newsettings[SETTING_SUN_ROTATION]  = sunquat.getValue();          newsettings[SETTING_MOON_ROTATION] = moonquat.getValue();      } @@ -943,6 +943,19 @@ LLVector3 LLSettingsSky::getLightDirection() const      return LLVector3::z_axis;  } +LLColor3 LLSettingsSky::getAmbientColor() const +{ +    if (mSettings.has(SETTING_LEGACY_HAZE) && mSettings[SETTING_LEGACY_HAZE].has(SETTING_AMBIENT)) +    { +        return LLColor3(mSettings[SETTING_LEGACY_HAZE][SETTING_AMBIENT]); +    } +    if (mSettings.has(SETTING_AMBIENT)) +    { +        return LLColor3(mSettings[SETTING_AMBIENT]); +    } +    return LLColor3(0.25f, 0.25f, 0.25f); +} +  LLColor3 LLSettingsSky::getBlueDensity() const  {      if (mSettings.has(SETTING_LEGACY_HAZE) && mSettings[SETTING_LEGACY_HAZE].has(SETTING_BLUE_DENSITY)) @@ -1025,17 +1038,23 @@ void LLSettingsSky::setMieAnisotropy(F32 aniso_factor)  void LLSettingsSky::setSkyMoistureLevel(F32 moisture_level)  { -    mSettings[SETTING_SKY_MOISTURE_LEVEL] = moisture_level; +    setValue(SETTING_SKY_MOISTURE_LEVEL, moisture_level);  }  void LLSettingsSky::setSkyDropletRadius(F32 radius)  { -    mSettings[SETTING_SKY_DROPLET_RADIUS] = radius; +    setValue(SETTING_SKY_DROPLET_RADIUS,radius);  }  void LLSettingsSky::setSkyIceLevel(F32 ice_level)  { -    mSettings[SETTING_SKY_ICE_LEVEL] = ice_level; +    setValue(SETTING_SKY_ICE_LEVEL, ice_level); +} + +void LLSettingsSky::setAmbientColor(const LLColor3 &val) +{ +    mSettings[SETTING_LEGACY_HAZE][SETTING_AMBIENT] = val.getValue(); +    setDirtyFlag(true);  }  void LLSettingsSky::setBlueDensity(const LLColor3 &val) @@ -1342,16 +1361,6 @@ LLUUID LLSettingsSky::getHaloTextureId() const  }  //--------------------------------------------------------------------- -LLColor3 LLSettingsSky::getAmbientColor() const -{ -    return LLColor3(mSettings[SETTING_AMBIENT]); -} - -void LLSettingsSky::setAmbientColor(const LLColor3 &val) -{ -    setValue(SETTING_AMBIENT, val); -} -  LLColor3 LLSettingsSky::getCloudColor() const  {      return LLColor3(mSettings[SETTING_CLOUD_COLOR]); diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp index 8e55ae395a..f13265ae84 100644 --- a/indra/newview/llsettingsvo.cpp +++ b/indra/newview/llsettingsvo.cpp @@ -1,1343 +1,1381 @@ -/** -* @file llsettingsvo.cpp -* @author Rider Linden -* @brief Subclasses for viewer specific settings behaviors. -* -* $LicenseInfo:2011&license=viewerlgpl$ -* Second Life Viewer Source Code -* Copyright (C) 2017, Linden Research, Inc. -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation; -* version 2.1 of the License only. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU -* Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA -* -* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA -* $/LicenseInfo$ -*/ - -#include "llviewerprecompiledheaders.h" -#include "llviewercontrol.h" -#include "llsettingsvo.h" - -#include "pipeline.h" - -#include <algorithm> -#include <cstdio> -#include <boost/make_shared.hpp> -#include "lltrace.h" -#include "llfasttimer.h" -#include "v3colorutil.h" - -#include "llglslshader.h" -#include "llviewershadermgr.h" - -#include "llagent.h" -#include "llassettype.h" -#include "llfloaterperms.h" -#include "llnotificationsutil.h" - -#include "llviewerregion.h" -#include "llviewerassetupload.h" -#include "llviewerinventory.h" - -#include "llenvironment.h" -#include "llsky.h" - -#include "llpermissions.h" - -#include "llinventorymodel.h" -#include "llassetstorage.h" -#include "llvfile.h" -#include "lldrawpoolwater.h" - -#include <boost/algorithm/string/replace.hpp> -#include "llinventoryobserver.h" -#include "llinventorydefines.h" - -#undef  VERIFY_LEGACY_CONVERSION - -//========================================================================= -namespace  -{ -    LLSD ensure_array_4(LLSD in, F32 fill); -    LLSD read_legacy_preset_data(const std::string &name, const std::string& path); - -    //------------------------------------------------------------------------- -    class LLSettingsInventoryCB : public LLInventoryCallback -    { -    public: -        typedef std::function<void(const LLUUID &)> callback_t; - -        LLSettingsInventoryCB(callback_t cbfn) : -            mCbfn(cbfn) -        { } - -        void fire(const LLUUID& inv_item) override  { if (mCbfn) mCbfn(inv_item); } - -    private: -        callback_t  mCbfn; -    }; - -    //------------------------------------------------------------------------- -} - - -//========================================================================= -void LLSettingsVOBase::createNewInventoryItem(LLSettingsType::type_e stype, const LLUUID &parent_id, inventory_result_fn callback) -{ -    LLTransactionID tid; -    U32 nextOwnerPerm = LLFloaterPerms::getNextOwnerPerms("Settings"); -    nextOwnerPerm |= PERM_COPY; - -    if (!LLEnvironment::instance().isInventoryEnabled()) -    { -        LL_WARNS("SETTINGS") << "Region does not support settings inventory objects." << LL_ENDL; -        LLNotificationsUtil::add("SettingsUnsuported"); -        return; -    } - -    tid.generate(); - -    LLPointer<LLInventoryCallback> cb = new LLSettingsInventoryCB([callback](const LLUUID &inventoryId) { -        LLSettingsVOBase::onInventoryItemCreated(inventoryId, LLSettingsBase::ptr_t(), callback); -    }); - -    create_inventory_settings(gAgent.getID(), gAgent.getSessionID(), -        parent_id, LLTransactionID::tnull, -        LLSettingsType::getDefaultName(stype), "", -        stype, nextOwnerPerm, cb); -} - - -void LLSettingsVOBase::createInventoryItem(const LLSettingsBase::ptr_t &settings, const LLUUID &parent_id, std::string settings_name, inventory_result_fn callback) -{ -    LLTransactionID tid; -    U32             nextOwnerPerm = LLPermissions::DEFAULT.getMaskNextOwner(); - -    if (!LLEnvironment::instance().isInventoryEnabled()) -    { -        LL_WARNS("SETTINGS") << "Region does not support settings inventory objects." << LL_ENDL; -        LLNotificationsUtil::add("SettingsUnsuported"); -        return; -    } - -    tid.generate(); - -    LLPointer<LLInventoryCallback> cb = new LLSettingsInventoryCB([settings, callback](const LLUUID &inventoryId) { -            LLSettingsVOBase::onInventoryItemCreated(inventoryId, settings, callback); -        }); - -    if (settings_name.empty()) -    { -        settings_name = settings->getName(); -    } -    create_inventory_settings(gAgent.getID(), gAgent.getSessionID(), -        parent_id, tid, -        settings_name, "", -        settings->getSettingsTypeValue(), nextOwnerPerm, cb); -} - -void LLSettingsVOBase::onInventoryItemCreated(const LLUUID &inventoryId, LLSettingsBase::ptr_t settings, inventory_result_fn callback) -{ -    if (!settings) -    {   // The item was created as new with no settings passed in.  Simulator should have given it the default for the type... check ID,  -        // no need to upload asset. -        LLUUID asset_id; -        LLViewerInventoryItem *pitem = gInventory.getItem(inventoryId); - -        if (pitem) -        { -            asset_id = pitem->getAssetUUID(); -        } -        if (callback) -            callback(asset_id, inventoryId, LLUUID::null, LLSD()); -        return; -    } -    // We need to update some inventory stuff here.... maybe. -    updateInventoryItem(settings, inventoryId, callback, false); -} - -void LLSettingsVOBase::updateInventoryItem(const LLSettingsBase::ptr_t &settings, LLUUID inv_item_id, inventory_result_fn callback, bool update_name) -{ -    const LLViewerRegion* region = gAgent.getRegion(); -    if (!region) -    { -        LL_WARNS("SETTINGS") << "Not connected to a region, cannot save setting." << LL_ENDL; -        return; -    } - -    std::string agent_url(region->getCapability("UpdateSettingsAgentInventory")); - -    if (!LLEnvironment::instance().isInventoryEnabled()) -    { -        LL_WARNS("SETTINGS") << "Region does not support settings inventory objects." << LL_ENDL; -        LLNotificationsUtil::add("SettingsUnsuported"); -        return; -    } - -    LLViewerInventoryItem *inv_item = gInventory.getItem(inv_item_id); -    if (inv_item) -    { -        bool need_update(false); -        LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(inv_item); - -        if (settings->getFlag(LLSettingsBase::FLAG_NOTRANS) && new_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID())) -        { -            LLPermissions perm(inv_item->getPermissions()); -            perm.setBaseBits(LLUUID::null, FALSE, PERM_TRANSFER); -            perm.setOwnerBits(LLUUID::null, FALSE, PERM_TRANSFER); -            new_item->setPermissions(perm); -            need_update |= true; -        } -        if (update_name && (settings->getName() != new_item->getName())) -        { -            new_item->rename(settings->getName()); -            settings->setName(new_item->getName()); // account for corrections -            need_update |= true; -        } -        if (need_update) -        { -            new_item->updateServer(FALSE); -            gInventory.updateItem(new_item); -            gInventory.notifyObservers(); -        } -    } - -    std::stringstream buffer;  -    LLSD settingdata(settings->getSettings()); -    LLSDSerialize::serialize(settingdata, buffer, LLSDSerialize::LLSD_NOTATION); - -    LLResourceUploadInfo::ptr_t uploadInfo = std::make_shared<LLBufferedAssetUploadInfo>(inv_item_id, LLAssetType::AT_SETTINGS, buffer.str(),  -        [settings, callback](LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD response) { -            LLSettingsVOBase::onAgentAssetUploadComplete(itemId, newAssetId, newItemId, response, settings, callback); -        }); - -    LLViewerAssetUpload::EnqueueInventoryUpload(agent_url, uploadInfo); -} - -void LLSettingsVOBase::updateInventoryItem(const LLSettingsBase::ptr_t &settings, LLUUID object_id, LLUUID inv_item_id, inventory_result_fn callback) -{ -    const LLViewerRegion* region = gAgent.getRegion(); -    if (!region) -    { -        LL_WARNS("SETTINGS") << "Not connected to a region, cannot save setting." << LL_ENDL; -        return; -    } - -    std::string agent_url(region->getCapability("UpdateSettingsAgentInventory")); - -    if (!LLEnvironment::instance().isInventoryEnabled()) -    { -        LL_WARNS("SETTINGS") << "Region does not support settings inventory objects." << LL_ENDL; -        LLNotificationsUtil::add("SettingsUnsuported"); -        return; -    } - -    std::stringstream buffer; -    LLSD settingdata(settings->getSettings()); - -    LLSDSerialize::serialize(settingdata, buffer, LLSDSerialize::LLSD_NOTATION); - -    LLResourceUploadInfo::ptr_t uploadInfo = std::make_shared<LLBufferedAssetUploadInfo>(object_id, inv_item_id, LLAssetType::AT_SETTINGS, buffer.str(), -        [settings, callback](LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response) { -        LLSettingsVOBase::onTaskAssetUploadComplete(itemId, taskId, newAssetId, response, settings, callback); -    }); - -    LLViewerAssetUpload::EnqueueInventoryUpload(agent_url, uploadInfo); -} - -void LLSettingsVOBase::onAgentAssetUploadComplete(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD response, LLSettingsBase::ptr_t psettings, inventory_result_fn callback) -{ -    LL_INFOS("SETTINGS") << "itemId:" << itemId << " newAssetId:" << newAssetId << " newItemId:" << newItemId << " response:" << response << LL_ENDL; -    psettings->setAssetId(newAssetId); -    if (callback) -        callback( newAssetId, itemId, LLUUID::null, response ); - -#if 0 -    std::string exprtFile = gDirUtilp->getTempDir() + gDirUtilp->getDirDelimiter() + newAssetId.asString() + ".llsd"; - -    LLSettingsVOBase::exportFile(psettings, exprtFile, LLSDSerialize::LLSD_NOTATION); - -    LL_WARNS("LAPRAS") << "SETTINGS File written as: '" << exprtFile << "'" << LL_ENDL; -#endif -} - -void LLSettingsVOBase::onTaskAssetUploadComplete(LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response, LLSettingsBase::ptr_t psettings, inventory_result_fn callback) -{ -    LL_INFOS("SETTINGS") << "Upload to task complete!" << LL_ENDL; -    psettings->setAssetId(newAssetId); -    if (callback) -        callback(newAssetId, itemId, taskId, response); -} - - -void LLSettingsVOBase::getSettingsAsset(const LLUUID &assetId, LLSettingsVOBase::asset_download_fn callback) -{ -    gAssetStorage->getAssetData(assetId, LLAssetType::AT_SETTINGS, -        [callback](LLVFS *vfs, const LLUUID &asset_id, LLAssetType::EType, void *, S32 status, LLExtStat ext_status)  -            { onAssetDownloadComplete(vfs, asset_id, status, ext_status, callback); }, -        nullptr, true); - -} - -void LLSettingsVOBase::onAssetDownloadComplete(LLVFS *vfs, const LLUUID &asset_id, S32 status, LLExtStat ext_status, LLSettingsVOBase::asset_download_fn callback) -{ -    LLSettingsBase::ptr_t settings; -    if (!status) -    { -        LLVFile file(vfs, asset_id, LLAssetType::AT_SETTINGS, LLVFile::READ); -        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, -1)) -        { -            settings = createFromLLSD(llsdsettings); -        } - -        if (!settings) -        { -            status = 1; -            LL_WARNS("SETTINGS") << "Unable to create settings object." << LL_ENDL; -        } -        else -        { -            LL_WARNS("LAPRAS") << "Setting asset ID to " << asset_id << LL_ENDL; -            settings->setAssetId(asset_id); -        } -    } -    else -    { -        LL_WARNS("SETTINGS") << "Error retrieving asset " << asset_id << ". Status code=" << status << "(" << LLAssetStorage::getErrorString(status) << ") ext_status=" << ext_status << LL_ENDL; -    } -    if (callback) -        callback(asset_id, settings, status, ext_status); -} - -void LLSettingsVOBase::getSettingsInventory(const LLUUID &inventoryId, inventory_download_fn callback) -{ - -} - -bool LLSettingsVOBase::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) -        { -            LL_WARNS("SETTINGS") << "Unable to open '" << filename << "' for writing." << LL_ENDL; -            return false; -        } - -        LLSDSerialize::serialize(settings->getSettings(), file, format); -    } -    catch (const std::ios_base::failure &e) -    { -        LL_WARNS("SETTINGS") << "Unable to save settings to file '" << filename << "': " << e.what() << LL_ENDL; -        return false; -    } - -    return true; -} - -LLSettingsBase::ptr_t LLSettingsVOBase::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) -        { -            LL_WARNS("SETTINGS") << "Unable to open '" << filename << "' for reading." << LL_ENDL; -            return LLSettingsBase::ptr_t(); -        } - -        if (!LLSDSerialize::deserialize(settings, file, -1)) -        { -            LL_WARNS("SETTINGS") << "Unable to deserialize settings from '" << filename << "'" << LL_ENDL; -            return LLSettingsBase::ptr_t(); -        } -    } -    catch (const std::ios_base::failure &e) -    { -        LL_WARNS("SETTINGS") << "Unable to save settings to file '" << filename << "': " << e.what() << LL_ENDL; -        return LLSettingsBase::ptr_t(); -    } - -    return createFromLLSD(settings); -} - -LLSettingsBase::ptr_t LLSettingsVOBase::createFromLLSD(const LLSD &settings) -{ -    if (!settings.has(SETTING_TYPE)) -    { -        LL_WARNS("SETTINGS") << "No settings type in LLSD" << LL_ENDL; -        return LLSettingsBase::ptr_t(); -    } - -    std::string settingtype = settings[SETTING_TYPE].asString(); - -    LLSettingsBase::ptr_t psetting; - -    if (settingtype == "water") -    { -        return LLSettingsVOWater::buildWater(settings); -    } -    else if (settingtype == "sky") -    { -        return LLSettingsVOSky::buildSky(settings); -    } -    else if (settingtype == "daycycle") -    { -        return LLSettingsVODay::buildDay(settings); -    } - -    LL_WARNS("SETTINGS") << "Unable to determine settings type for '" << settingtype << "'." << LL_ENDL; -    return LLSettingsBase::ptr_t(); - -} - -//========================================================================= -LLSettingsVOSky::LLSettingsVOSky(const LLSD &data, bool isAdvanced) -: LLSettingsSky(data) -, m_isAdvanced(isAdvanced) -{ -} - -LLSettingsVOSky::LLSettingsVOSky() -: LLSettingsSky() -, m_isAdvanced(false) -{ -} - -//------------------------------------------------------------------------- -LLSettingsSky::ptr_t LLSettingsVOSky::buildSky(LLSD settings) -{ -    LLSettingsSky::validation_list_t validations = LLSettingsSky::validationList(); - -    LLSD results = LLSettingsBase::settingValidation(settings, validations); - -    if (!results["success"].asBoolean()) -    { -        LL_WARNS("SETTINGS") << "Sky setting validation failed!\n" << results << LL_ENDL; -        LLSettingsSky::ptr_t(); -    } - -    return std::make_shared<LLSettingsVOSky>(settings, true); -} - - -LLSettingsSky::ptr_t LLSettingsVOSky::buildFromLegacyPreset(const std::string &name, const LLSD &legacy) -{ - -    LLSD newsettings = LLSettingsSky::translateLegacySettings(legacy); - -    newsettings[SETTING_NAME] = name; - -    LLSettingsSky::validation_list_t validations = LLSettingsSky::validationList(); -    LLSD results = LLSettingsBase::settingValidation(newsettings, validations); -    if (!results["success"].asBoolean()) -    { -        LL_WARNS("SETTINGS") << "Sky setting validation failed!\n" << results << LL_ENDL; -        LLSettingsSky::ptr_t(); -    } - -    LLSettingsSky::ptr_t skyp = std::make_shared<LLSettingsVOSky>(newsettings); - -#ifdef VERIFY_LEGACY_CONVERSION -    LLSD oldsettings = LLSettingsVOSky::convertToLegacy(skyp, isAdvanced()); - -    if (!llsd_equals(legacy, oldsettings)) -    { -        LL_WARNS("SKY") << "Conversion to/from legacy does not match!\n"  -            << "Old: " << legacy -            << "new: " << oldsettings << LL_ENDL; -    } - -#endif - -    return skyp; -} - -LLSettingsSky::ptr_t LLSettingsVOSky::buildFromLegacyPresetFile(const std::string &name, const std::string &path) -{ -    LLSD legacy_data = read_legacy_preset_data(name, path); - -    if (!legacy_data) -    { -        LL_WARNS("SETTINGS") << "Could not load legacy Windlight \"" << name << "\" from " << path << LL_ENDL; -        return ptr_t(); -    } - -    return buildFromLegacyPreset(name, legacy_data); -} - - -LLSettingsSky::ptr_t LLSettingsVOSky::buildDefaultSky() -{ -    static LLSD default_settings; - -    if (!default_settings.size()) -    { -        default_settings = LLSettingsSky::defaults(); - -        default_settings[SETTING_NAME] = std::string("_default_"); - -        LLSettingsSky::validation_list_t validations = LLSettingsSky::validationList(); -        LLSD results = LLSettingsBase::settingValidation(default_settings, validations); -        if (!results["success"].asBoolean()) -        { -            LL_WARNS("SETTINGS") << "Sky setting validation failed!\n" << results << LL_ENDL; -            LLSettingsSky::ptr_t(); -        } -    } - -    LLSettingsSky::ptr_t skyp = std::make_shared<LLSettingsVOSky>(default_settings); -    return skyp; -} - -LLSettingsSky::ptr_t LLSettingsVOSky::buildClone() const -{ -    LLSD settings = cloneSettings(); - -    LLSettingsSky::validation_list_t validations = LLSettingsSky::validationList(); -    LLSD results = LLSettingsBase::settingValidation(settings, validations); -    if (!results["success"].asBoolean()) -    { -        LL_WARNS("SETTINGS") << "Sky setting validation failed!\n" << results << LL_ENDL; -        LLSettingsSky::ptr_t(); -    } - -    LLSettingsSky::ptr_t skyp = std::make_shared<LLSettingsVOSky>(settings); -    return skyp; -} - -void LLSettingsVOSky::convertAtmosphericsToLegacy(LLSD& legacy, LLSD& settings) -{ -    // These will need to be inferred from new settings' density profiles -    if (settings.has(SETTING_LEGACY_HAZE)) -    { -        LLSD legacyhaze = settings[SETTING_LEGACY_HAZE]; -        legacy[SETTING_AMBIENT]             = ensure_array_4(legacyhaze[SETTING_AMBIENT], 1.0f); -        legacy[SETTING_BLUE_DENSITY]        = ensure_array_4(legacyhaze[SETTING_BLUE_DENSITY], 1.0); -        legacy[SETTING_BLUE_HORIZON]        = ensure_array_4(legacyhaze[SETTING_BLUE_HORIZON], 1.0); -        legacy[SETTING_DENSITY_MULTIPLIER]  = LLSDArray(legacyhaze[SETTING_DENSITY_MULTIPLIER].asReal())(0.0f)(0.0f)(1.0f); -        legacy[SETTING_DISTANCE_MULTIPLIER] = LLSDArray(legacyhaze[SETTING_DISTANCE_MULTIPLIER].asReal())(0.0f)(0.0f)(1.0f); -        legacy[SETTING_HAZE_DENSITY]        = LLSDArray(legacyhaze[SETTING_HAZE_DENSITY])(0.0f)(0.0f)(1.0f); -        legacy[SETTING_HAZE_HORIZON]        = LLSDArray(legacyhaze[SETTING_HAZE_HORIZON])(0.0f)(0.0f)(1.0f); -    } -} - -LLSD LLSettingsVOSky::convertToLegacy(const LLSettingsSky::ptr_t &psky, bool isAdvanced) -{ -    LLSD legacy(LLSD::emptyMap()); -    LLSD settings = psky->getSettings(); -     -    convertAtmosphericsToLegacy(legacy, settings); - -    legacy[SETTING_CLOUD_COLOR] = ensure_array_4(settings[SETTING_CLOUD_COLOR], 1.0); -    legacy[SETTING_CLOUD_POS_DENSITY1] = ensure_array_4(settings[SETTING_CLOUD_POS_DENSITY1], 1.0); -    legacy[SETTING_CLOUD_POS_DENSITY2] = ensure_array_4(settings[SETTING_CLOUD_POS_DENSITY2], 1.0); -    legacy[SETTING_CLOUD_SCALE] = LLSDArray(settings[SETTING_CLOUD_SCALE])(LLSD::Real(0.0))(LLSD::Real(0.0))(LLSD::Real(1.0));        -    legacy[SETTING_CLOUD_SCROLL_RATE] = settings[SETTING_CLOUD_SCROLL_RATE]; -    legacy[SETTING_LEGACY_ENABLE_CLOUD_SCROLL] = LLSDArray(LLSD::Boolean(!is_approx_zero(settings[SETTING_CLOUD_SCROLL_RATE][0].asReal()))) -        (LLSD::Boolean(!is_approx_zero(settings[SETTING_CLOUD_SCROLL_RATE][1].asReal())));      -    legacy[SETTING_CLOUD_SHADOW] = LLSDArray(settings[SETTING_CLOUD_SHADOW].asReal())(0.0f)(0.0f)(1.0f);     -    legacy[SETTING_GAMMA] = LLSDArray(settings[SETTING_GAMMA])(0.0f)(0.0f)(1.0f); -    legacy[SETTING_GLOW] = ensure_array_4(settings[SETTING_GLOW], 1.0); -    legacy[SETTING_LIGHT_NORMAL] = ensure_array_4(psky->getLightDirection().getValue(), 0.0f); -    legacy[SETTING_MAX_Y] = LLSDArray(settings[SETTING_MAX_Y])(0.0f)(0.0f)(1.0f); -    legacy[SETTING_STAR_BRIGHTNESS] = settings[SETTING_STAR_BRIGHTNESS]; -    legacy[SETTING_SUNLIGHT_COLOR] = ensure_array_4(settings[SETTING_SUNLIGHT_COLOR], 1.0f); -     -    LLQuaternion sunquat = psky->getSunRotation(); - -    F32 roll; -    F32 pitch; -    F32 yaw; - -    // get euler angles in right-handed X right, Y up, Z at -    sunquat.getEulerAngles(&roll, &pitch, &yaw); -     -    legacy[SETTING_LEGACY_EAST_ANGLE] = yaw; -    legacy[SETTING_LEGACY_SUN_ANGLE]  = -pitch; - -    return legacy;     -} - -//------------------------------------------------------------------------- -void LLSettingsVOSky::updateSettings() -{ -    LLSettingsSky::updateSettings(); -    LLVector3 sun_direction  = getSunDirection(); -    LLVector3 moon_direction = getMoonDirection(); - -    F32 dp = getLightDirection() * LLVector3(0.0f, 0.0f, 1.0f); -	if (dp < 0) -	{ -		dp = 0; -	} -    dp = llmax(dp, 0.1f); - -	// 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. -	F32 sun_dynamic_range = llmax(gSavedSettings.getF32("RenderSunDynamicRange"), 0.0001f); -    mSceneLightStrength = 2.0f * (1.0f + sun_dynamic_range * dp); - -    gSky.setSunAndMoonDirectionsCFR(sun_direction, moon_direction); -    gSky.setSunTextures(getSunTextureId(), getNextSunTextureId()); -    gSky.setMoonTextures(getMoonTextureId(), getNextMoonTextureId()); -    gSky.setCloudNoiseTextures(getCloudNoiseTextureId(), getNextCloudNoiseTextureId()); -    gSky.setBloomTextures(getBloomTextureId(), getNextBloomTextureId()); - -    gSky.setSunScale(getSunScale()); -    gSky.setMoonScale(getMoonScale()); -} - -void LLSettingsVOSky::applySpecial(void *ptarget) -{ -    LLGLSLShader *shader = (LLGLSLShader *)ptarget; - -    LLVector4 light_direction = LLEnvironment::instance().getClampedSunNorm(); - -    if (shader->mShaderGroup == LLGLSLShader::SG_DEFAULT) -	{         -        shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, light_direction.mV); -		shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV); -	}  -	else if (shader->mShaderGroup == LLGLSLShader::SG_SKY) -	{ -        shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, light_direction.mV);         - -        LLVector4 vect_c_p_d1(mSettings[SETTING_CLOUD_POS_DENSITY1]); -        vect_c_p_d1 += LLVector4(LLEnvironment::instance().getCloudScrollDelta()); -        shader->uniform4fv(LLShaderMgr::CLOUD_POS_DENSITY1, 1, vect_c_p_d1.mV); -	} - -    shader->uniform1f(LLShaderMgr::SCENE_LIGHT_STRENGTH, mSceneLightStrength); -    shader->uniform4f(LLShaderMgr::GAMMA, getGamma(), 0.0, 0.0, 1.0); -} - -LLSettingsSky::parammapping_t LLSettingsVOSky::getParameterMap() const -{ -    static parammapping_t param_map; - -    if (param_map.empty()) -    { -// LEGACY_ATMOSPHERICS -        param_map[SETTING_AMBIENT] = LLShaderMgr::AMBIENT; -        param_map[SETTING_BLUE_DENSITY] = LLShaderMgr::BLUE_DENSITY; -        param_map[SETTING_BLUE_HORIZON] = LLShaderMgr::BLUE_HORIZON; -        param_map[SETTING_HAZE_DENSITY] = LLShaderMgr::HAZE_DENSITY; -        param_map[SETTING_HAZE_HORIZON] = LLShaderMgr::HAZE_HORIZON; -        param_map[SETTING_DENSITY_MULTIPLIER] = LLShaderMgr::DENSITY_MULTIPLIER; -        param_map[SETTING_DISTANCE_MULTIPLIER] = LLShaderMgr::DISTANCE_MULTIPLIER; - -        param_map[SETTING_CLOUD_COLOR] = LLShaderMgr::CLOUD_COLOR; -        param_map[SETTING_CLOUD_POS_DENSITY2] = LLShaderMgr::CLOUD_POS_DENSITY2; -        param_map[SETTING_CLOUD_SCALE] = LLShaderMgr::CLOUD_SCALE; -        param_map[SETTING_CLOUD_SHADOW] = LLShaderMgr::CLOUD_SHADOW;        -        param_map[SETTING_CLOUD_VARIANCE] = LLShaderMgr::CLOUD_VARIANCE; -        param_map[SETTING_GLOW] = LLShaderMgr::GLOW;         -        param_map[SETTING_MAX_Y] = LLShaderMgr::MAX_Y; -        param_map[SETTING_SUNLIGHT_COLOR] = LLShaderMgr::SUNLIGHT_COLOR; -        param_map[SETTING_MOON_BRIGHTNESS] = LLShaderMgr::MOON_BRIGHTNESS; -        param_map[SETTING_SKY_MOISTURE_LEVEL] = LLShaderMgr::MOISTURE_LEVEL; -        param_map[SETTING_SKY_DROPLET_RADIUS] = LLShaderMgr::DROPLET_RADIUS; -        param_map[SETTING_SKY_ICE_LEVEL] = LLShaderMgr::ICE_LEVEL; - -// AdvancedAtmospherics TODO -// Provide mappings for new shader params here -    } - -    return param_map; -} - -//========================================================================= -const F32 LLSettingsVOWater::WATER_FOG_LIGHT_CLAMP(0.3f); - -//------------------------------------------------------------------------- -LLSettingsVOWater::LLSettingsVOWater(const LLSD &data) : -    LLSettingsWater(data) -{ - -} - -LLSettingsVOWater::LLSettingsVOWater() : -    LLSettingsWater() -{ - -} - -LLSettingsWater::ptr_t LLSettingsVOWater::buildWater(LLSD settings) -{ -    LLSettingsWater::validation_list_t validations = LLSettingsWater::validationList(); -    LLSD results = LLSettingsWater::settingValidation(settings, validations); -    if (!results["success"].asBoolean()) -    { -        LL_WARNS("SETTINGS") << "Water setting validation failed!\n" << results << LL_ENDL; -        LLSettingsWater::ptr_t(); -    } - -    return std::make_shared<LLSettingsVOWater>(settings); -} - -//------------------------------------------------------------------------- -LLSettingsWater::ptr_t LLSettingsVOWater::buildFromLegacyPreset(const std::string &name, const LLSD &legacy) -{ -    LLSD newsettings(LLSettingsWater::translateLegacySettings(legacy)); - -    newsettings[SETTING_NAME] = name;  -    LLSettingsWater::validation_list_t validations = LLSettingsWater::validationList(); -    LLSD results = LLSettingsWater::settingValidation(newsettings, validations); -    if (!results["success"].asBoolean()) -    { -        LL_WARNS("SETTINGS") << "Water setting validation failed!: " << results << LL_ENDL; -        return LLSettingsWater::ptr_t(); -    } - -    LLSettingsWater::ptr_t waterp = std::make_shared<LLSettingsVOWater>(newsettings); - -#ifdef VERIFY_LEGACY_CONVERSION -    LLSD oldsettings = LLSettingsVOWater::convertToLegacy(waterp); - -    if (!llsd_equals(legacy, oldsettings)) -    { -        LL_WARNS("WATER") << "Conversion to/from legacy does not match!\n" -            << "Old: " << legacy -            << "new: " << oldsettings << LL_ENDL; -    } - -#endif -    return waterp; -} - -LLSettingsWater::ptr_t LLSettingsVOWater::buildFromLegacyPresetFile(const std::string &name, const std::string &path) -{ -    LLSD legacy_data = read_legacy_preset_data(name, path); - -    if (!legacy_data) -    { -        LL_WARNS("SETTINGS") << "Could not load legacy Windlight \"" << name << "\" from " << path << LL_ENDL; -        return ptr_t(); -    } - -    return buildFromLegacyPreset(name, legacy_data); -} - - -LLSettingsWater::ptr_t LLSettingsVOWater::buildDefaultWater() -{ -    static LLSD default_settings; - -    if (!default_settings.size()) -    { -        default_settings = LLSettingsWater::defaults(); - -        default_settings[SETTING_NAME] = std::string("_default_"); - -        LLSettingsWater::validation_list_t validations = LLSettingsWater::validationList(); -        LLSD results = LLSettingsWater::settingValidation(default_settings, validations); -        if (!results["success"].asBoolean()) -        { -            LL_WARNS("SETTINGS") << "Water setting validation failed!: " << results << LL_ENDL; -            return LLSettingsWater::ptr_t(); -        } -    } - -    LLSettingsWater::ptr_t waterp = std::make_shared<LLSettingsVOWater>(default_settings); - -    return waterp; -} - -LLSettingsWater::ptr_t LLSettingsVOWater::buildClone() const -{ -    LLSD settings = cloneSettings(); -    LLSettingsWater::validation_list_t validations = LLSettingsWater::validationList(); -    LLSD results = LLSettingsWater::settingValidation(settings, validations); -    if (!results["success"].asBoolean()) -    { -        LL_WARNS("SETTINGS") << "Water setting validation failed!: " << results << LL_ENDL; -        return LLSettingsWater::ptr_t(); -    } - -    LLSettingsWater::ptr_t waterp = std::make_shared<LLSettingsVOWater>(settings); - -    return waterp; -} - -LLSD LLSettingsVOWater::convertToLegacy(const LLSettingsWater::ptr_t &pwater) -{ -    LLSD legacy(LLSD::emptyMap()); -    LLSD settings = pwater->getSettings(); - -    legacy[SETTING_LEGACY_BLUR_MULTIPLIER] = settings[SETTING_BLUR_MULTIPLIER]; -    legacy[SETTING_LEGACY_FOG_COLOR] = ensure_array_4(settings[SETTING_FOG_COLOR], 1.0f); -    legacy[SETTING_LEGACY_FOG_DENSITY] = settings[SETTING_FOG_DENSITY]; -    legacy[SETTING_LEGACY_FOG_MOD] = settings[SETTING_FOG_MOD]; -    legacy[SETTING_LEGACY_FRESNEL_OFFSET] = settings[SETTING_FRESNEL_OFFSET]; -    legacy[SETTING_LEGACY_FRESNEL_SCALE] = settings[SETTING_FRESNEL_SCALE]; -    legacy[SETTING_LEGACY_NORMAL_MAP] = settings[SETTING_NORMAL_MAP]; -    legacy[SETTING_LEGACY_NORMAL_SCALE] = settings[SETTING_NORMAL_SCALE]; -    legacy[SETTING_LEGACY_SCALE_ABOVE] = settings[SETTING_SCALE_ABOVE]; -    legacy[SETTING_LEGACY_SCALE_BELOW] = settings[SETTING_SCALE_BELOW]; -    legacy[SETTING_LEGACY_WAVE1_DIR] = settings[SETTING_WAVE1_DIR]; -    legacy[SETTING_LEGACY_WAVE2_DIR] = settings[SETTING_WAVE2_DIR]; -     -    //_WARNS("LAPRAS") << "Legacy water: " << legacy << LL_ENDL; -    return legacy; -} -//------------------------------------------------------------------------- -//------------------------------------------------------------------------- -void LLSettingsVOWater::applySpecial(void *ptarget) -{ -    LLGLSLShader *shader = (LLGLSLShader *)ptarget; - -    if (shader->mShaderGroup == LLGLSLShader::SG_WATER) -	{ -        //transform water plane to eye space -        glh::vec3f norm(0.f, 0.f, 1.f); -        glh::vec3f p(0.f, 0.f, LLEnvironment::instance().getWaterHeight() + 0.1f); - -        F32 modelView[16]; -        for (U32 i = 0; i < 16; i++) -        { -            modelView[i] = (F32)gGLModelView[i]; -        } - -        glh::matrix4f mat(modelView); -        glh::matrix4f invtrans = mat.inverse().transpose(); -        glh::vec3f enorm; -        glh::vec3f ep; -        invtrans.mult_matrix_vec(norm, enorm); -        enorm.normalize(); -        mat.mult_matrix_vec(p, ep); - -        LLVector4 waterPlane(enorm.v[0], enorm.v[1], enorm.v[2], -ep.dot(enorm)); - -        shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, waterPlane.mV); - -        LLVector4 light_direction = LLEnvironment::instance().getClampedLightNorm(); - -        F32 waterFogKS = 1.f / llmax(light_direction.mV[2], WATER_FOG_LIGHT_CLAMP); - -        shader->uniform1f(LLShaderMgr::WATER_FOGKS, waterFogKS); - -        F32 blend_factor = LLEnvironment::instance().getCurrentWater()->getBlendFactor(); -        shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor); - -        LLVector4 rotated_light_direction = LLEnvironment::instance().getRotatedLightNorm(); -        shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, rotated_light_direction.mV); -        shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV); -        shader->uniform1f(LLViewerShaderMgr::DISTANCE_MULTIPLIER, 0); -    } -} - -void LLSettingsVOWater::updateSettings() -{ -    // base class clears dirty flag so as to not trigger recursive update -    LLSettingsBase::updateSettings(); - -    LLDrawPoolWater* pwaterpool = (LLDrawPoolWater*)gPipeline.getPool(LLDrawPool::POOL_WATER); -    if (pwaterpool) -    { -        pwaterpool->setTransparentTextures(getTransparentTextureID(), getNextTransparentTextureID()); -        pwaterpool->setOpaqueTexture(GetDefaultOpaqueTextureAssetId()); -        pwaterpool->setNormalMaps(getNormalMapID(), getNextNormalMapID()); -    } -} - -LLSettingsWater::parammapping_t LLSettingsVOWater::getParameterMap() const -{ -    static parammapping_t param_map; - -    if (param_map.empty()) -    { -        param_map[SETTING_FOG_COLOR] = LLShaderMgr::WATER_FOGCOLOR; -        param_map[SETTING_FOG_DENSITY] = LLShaderMgr::WATER_FOGDENSITY; -    } -    return param_map; -} - -//========================================================================= -LLSettingsVODay::LLSettingsVODay(const LLSD &data): -    LLSettingsDay(data) -{} - -LLSettingsVODay::LLSettingsVODay(): -    LLSettingsDay() -{} - -LLSettingsDay::ptr_t LLSettingsVODay::buildDay(LLSD settings) -{ -    LLSettingsDay::validation_list_t validations = LLSettingsDay::validationList(); -    LLSD results = LLSettingsDay::settingValidation(settings, validations); -    if (!results["success"].asBoolean()) -    { -        LL_WARNS("SETTINGS") << "Day setting validation failed!\n" << results << LL_ENDL; -        LLSettingsDay::ptr_t(); -    } - -    LLSettingsDay::ptr_t pday = std::make_shared<LLSettingsVODay>(settings); -    if (pday) -        pday->initialize(); - -    return pday; -} - -//------------------------------------------------------------------------- -LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyPreset(const std::string &name, const std::string &path, const LLSD &oldsettings) -{ -    LLSD newsettings(defaults()); -    std::set<std::string> framenames; -    std::set<std::string> notfound; - -    std::string base_path(gDirUtilp->getDirName(path)); -    std::string water_path(base_path); -    std::string sky_path(base_path); - -    gDirUtilp->append(water_path, "water"); -    gDirUtilp->append(sky_path, "skies"); - -    newsettings[SETTING_NAME] = name; - -    LLSD watertrack = LLSDArray( -        LLSDMap(SETTING_KEYKFRAME, LLSD::Real(0.0f)) -        (SETTING_KEYNAME, "water:Default")); - -    LLSD skytrack = LLSD::emptyArray(); - -    for (LLSD::array_const_iterator it = oldsettings.beginArray(); it != oldsettings.endArray(); ++it) -    { -        std::string framename = (*it)[1].asString(); -        LLSD entry = LLSDMap(SETTING_KEYKFRAME, (*it)[0].asReal()) -            (SETTING_KEYNAME, "sky:" + framename); -        framenames.insert(framename); -        skytrack.append(entry); -    } - -    newsettings[SETTING_TRACKS] = LLSDArray(watertrack)(skytrack); - -    LLSD frames(LLSD::emptyMap()); - -    { -        LLSettingsWater::ptr_t pwater = LLSettingsVOWater::buildFromLegacyPresetFile("Default", water_path); -        if (pwater) -            frames["water:Default"] = pwater->getSettings(); -    } - -    for (std::set<std::string>::iterator itn = framenames.begin(); itn != framenames.end(); ++itn) -    { -        LLSettingsSky::ptr_t psky = LLSettingsVOSky::buildFromLegacyPresetFile((*itn), sky_path); -        if (psky) -            frames["sky:" + (*itn)] = psky->getSettings(); -    } - -    newsettings[SETTING_FRAMES] = frames; - -    LLSettingsDay::validation_list_t validations = LLSettingsDay::validationList(); -    LLSD results = LLSettingsDay::settingValidation(newsettings, validations); -    if (!results["success"].asBoolean()) -    { -        LL_WARNS("SETTINGS") << "Day setting validation failed!: " << results << LL_ENDL; -        return LLSettingsDay::ptr_t(); -    } - -    LLSettingsDay::ptr_t dayp = std::make_shared<LLSettingsVODay>(newsettings); - -#ifdef VERIFY_LEGACY_CONVERSION -    LLSD testsettings = LLSettingsVODay::convertToLegacy(dayp); - -    if (!llsd_equals(oldsettings, testsettings)) -    { -        LL_WARNS("DAYCYCLE") << "Conversion to/from legacy does not match!\n"  -            << "Old: " << oldsettings -            << "new: " << testsettings << LL_ENDL; -    } - -#endif - -    dayp->initialize(); - -    return dayp; -} - -LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyPresetFile(const std::string &name, const std::string &path) -{ -    LLSD legacy_data = read_legacy_preset_data(name, path); - -    if (!legacy_data) -    { -        LL_WARNS("SETTINGS") << "Could not load legacy Windlight \"" << name << "\" from " << path << LL_ENDL; -        return ptr_t(); -    } - -    return buildFromLegacyPreset(name, path, legacy_data); -} - - - -LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyMessage(const LLUUID ®ionId, LLSD daycycle, LLSD skydefs, LLSD waterdef) -{ -    LLSD frames(LLSD::emptyMap()); - -    for (LLSD::map_iterator itm = skydefs.beginMap(); itm != skydefs.endMap(); ++itm) -    { -        std::string newname = "sky:" + (*itm).first; -        LLSD newsettings = LLSettingsSky::translateLegacySettings((*itm).second); -         -        newsettings[SETTING_NAME] = newname; -        frames[newname] = newsettings; - -        LL_WARNS("SETTINGS") << "created region sky '" << newname << "'" << LL_ENDL; -    } - -    LLSD watersettings = LLSettingsWater::translateLegacySettings(waterdef); -    std::string watername = "water:"+ watersettings[SETTING_NAME].asString(); -    watersettings[SETTING_NAME] = watername; -    frames[watername] = watersettings; - -    LLSD watertrack = LLSDArray( -            LLSDMap(SETTING_KEYKFRAME, LLSD::Real(0.0f)) -            (SETTING_KEYNAME, watername)); - -    LLSD skytrack(LLSD::emptyArray()); -    for (LLSD::array_const_iterator it = daycycle.beginArray(); it != daycycle.endArray(); ++it) -    { -        LLSD entry = LLSDMap(SETTING_KEYKFRAME, (*it)[0].asReal()) -            (SETTING_KEYNAME, "sky:" + (*it)[1].asString()); -        skytrack.append(entry); -    } - -    LLSD newsettings = LLSDMap -        ( SETTING_NAME, "Region (legacy)" ) -        ( SETTING_TRACKS, LLSDArray(watertrack)(skytrack)) -        ( SETTING_FRAMES, frames ) -        ( SETTING_TYPE, "daycycle" ); - -    LL_WARNS("LAPRAS") << "newsettings=" << newsettings << LL_ENDL; - -    LLSettingsSky::validation_list_t validations = LLSettingsDay::validationList(); -    LLSD results = LLSettingsDay::settingValidation(newsettings, validations); -    if (!results["success"].asBoolean()) -    { -        LL_WARNS("SETTINGS") << "Day setting validation failed!:" << results << LL_ENDL; -        return LLSettingsDay::ptr_t(); -    } - -    LLSettingsDay::ptr_t dayp = std::make_shared<LLSettingsVODay>(newsettings); -     -    if (dayp) -    { -        // true for validation - either validate here, or when cloning for floater. -        dayp->initialize(true); -    } -    return dayp; -} - - - -LLSettingsDay::ptr_t LLSettingsVODay::buildDefaultDayCycle() -{ -    static LLSD default_settings; - -    if (!default_settings.size()) -    { -        default_settings = LLSettingsDay::defaults(); -        default_settings[SETTING_NAME] = std::string("_default_"); - -        LLSettingsDay::validation_list_t validations = LLSettingsDay::validationList(); -        LLSD results = LLSettingsDay::settingValidation(default_settings, validations); -        if (!results["success"].asBoolean()) -        { -            LL_WARNS("SETTINGS") << "Day setting validation failed!\n" << results << LL_ENDL; -            LLSettingsDay::ptr_t(); -        } -    } - -    LLSettingsDay::ptr_t dayp = std::make_shared<LLSettingsVODay>(default_settings); - -    dayp->initialize(); -    return dayp; -} - -LLSettingsDay::ptr_t LLSettingsVODay::buildFromEnvironmentMessage(LLSD settings) -{ -    LLSettingsDay::validation_list_t validations = LLSettingsDay::validationList(); -    LLSD results = LLSettingsDay::settingValidation(settings, validations); -    if (!results["success"].asBoolean()) -    { -        LL_WARNS("SETTINGS") << "Day setting validation failed!\n" << results << LL_ENDL; -        LLSettingsDay::ptr_t(); -    } - -    LLSettingsDay::ptr_t dayp = std::make_shared<LLSettingsVODay>(settings); - -    dayp->initialize(); -    return dayp; -} - - -void LLSettingsVODay::buildFromOtherSetting(LLSettingsBase::ptr_t settings, LLSettingsVODay::asset_built_fn cb) -{ -    if (settings->getSettingsType() == "daycycle") -    { -        if (cb) -            cb(std::static_pointer_cast<LLSettingsDay>(settings)); -    } -    else -    { -        LLSettingsVOBase::getSettingsAsset(LLSettingsDay::GetDefaultAssetId(), -            [settings, cb](LLUUID, LLSettingsBase::ptr_t pday, S32, LLExtStat){ combineIntoDayCycle(std::static_pointer_cast<LLSettingsDay>(pday), settings, cb); }); -    } -} - -void LLSettingsVODay::combineIntoDayCycle(LLSettingsDay::ptr_t pday, LLSettingsBase::ptr_t settings, asset_built_fn cb) -{ -    if (settings->getSettingsType() == "sky") -    { -        pday->setName("sky: " + settings->getName()); -        pday->clearCycleTrack(1); -        pday->setSettingsAtKeyframe(settings, 0.0, 1); -    } -    else if (settings->getSettingsType() == "water") -    { -        pday->setName("water: " + settings->getName()); -        pday->clearCycleTrack(0); -        pday->setSettingsAtKeyframe(settings, 0.0, 0); -    } -    else -    { -        pday.reset(); -    } - -    if (cb) -        cb(pday); -} - - -LLSettingsDay::ptr_t LLSettingsVODay::buildClone() const -{ -    LLSD settings = cloneSettings(); - -    LLSettingsDay::validation_list_t validations = LLSettingsDay::validationList(); -    LLSD results = LLSettingsDay::settingValidation(settings, validations); -    if (!results["success"].asBoolean()) -    { -        LL_WARNS("SETTINGS") << "Day setting validation failed!\n" << results << LL_ENDL; -        LLSettingsDay::ptr_t(); -    } - -    LLSettingsDay::ptr_t dayp = std::make_shared<LLSettingsVODay>(settings); - -    U32 flags = getFlags(); -    if (flags) -        dayp->setFlags(flags); - -    dayp->initialize(); -    return dayp; -} - -LLSettingsDay::ptr_t LLSettingsVODay::buildDeepCloneAndUncompress() const -{ -    // no need for SETTING_TRACKS or SETTING_FRAMES, so take base LLSD -    LLSD settings = llsd_clone(mSettings); - -    LLSettingsDay::ptr_t day_clone = std::make_shared<LLSettingsVODay>(settings); - -    for (S32 i = 0; i < LLSettingsDay::TRACK_MAX; ++i) -    { -        const LLSettingsDay::CycleTrack_t& track = getCycleTrackConst(i); -        LLSettingsDay::CycleTrack_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++; -        } -    } -    return day_clone; -} - -LLSD LLSettingsVODay::convertToLegacy(const LLSettingsVODay::ptr_t &pday) -{ -    CycleTrack_t &trackwater = pday->getCycleTrack(TRACK_WATER); - -    LLSettingsWater::ptr_t pwater; -    if (!trackwater.empty()) -    { -        pwater = std::static_pointer_cast<LLSettingsWater>((*trackwater.begin()).second); -    } - -    if (!pwater) -        pwater = LLSettingsVOWater::buildDefaultWater(); -     -    LLSD llsdwater = LLSettingsVOWater::convertToLegacy(pwater); -     -    CycleTrack_t &tracksky = pday->getCycleTrack(1);   // first sky track -    std::map<std::string, LLSettingsSky::ptr_t> skys; -     -    LLSD llsdcycle(LLSD::emptyArray()); -     -    for(CycleTrack_t::iterator it = tracksky.begin(); it != tracksky.end(); ++it) -    { -        size_t hash = (*it).second->getHash(); -        std::stringstream name; -         -        name << hash; -         -        skys[name.str()] = std::static_pointer_cast<LLSettingsSky>((*it).second); -         -        F32 frame = ((tracksky.size() == 1) && (it == tracksky.begin())) ? -1.0f : (*it).first; -        llsdcycle.append( LLSDArray(LLSD::Real(frame))(name.str()) ); -    } -    //_WARNS("LAPRAS") << "Cycle created with " << llsdcycle.size() << "entries: " << llsdcycle << LL_ENDL; - -    LLSD llsdskylist(LLSD::emptyMap()); -     -    for (std::map<std::string, LLSettingsSky::ptr_t>::iterator its = skys.begin(); its != skys.end(); ++its) -    { -        LLSD llsdsky = LLSettingsVOSky::convertToLegacy((*its).second, false); -        llsdsky[SETTING_NAME] = (*its).first; -         -        llsdskylist[(*its).first] = llsdsky; -    } - -    //_WARNS("LAPRAS") << "Sky map with " << llsdskylist.size() << " entries created: " << llsdskylist << LL_ENDL; -     -    return LLSDArray(LLSD::emptyMap())(llsdcycle)(llsdskylist)(llsdwater); -} - -LLSettingsSkyPtr_t  LLSettingsVODay::getDefaultSky() const -{ -    return LLSettingsVOSky::buildDefaultSky(); -} - -LLSettingsWaterPtr_t LLSettingsVODay::getDefaultWater() const -{ -    return LLSettingsVOWater::buildDefaultWater(); -} - -LLSettingsSkyPtr_t LLSettingsVODay::buildSky(LLSD settings) const -{ -    LLSettingsSky::ptr_t skyp = std::make_shared<LLSettingsVOSky>(settings); - -    if (skyp->validate()) -        return skyp; - -    return LLSettingsSky::ptr_t(); -} - -LLSettingsWaterPtr_t LLSettingsVODay::buildWater(LLSD settings) const -{ -    LLSettingsWater::ptr_t waterp = std::make_shared<LLSettingsVOWater>(settings); - -    if (waterp->validate()) -        return waterp; - -    return LLSettingsWater::ptr_t(); -} - -//========================================================================= -namespace -{ -    LLSD ensure_array_4(LLSD in, F32 fill) -    { -        if (in.size() >= 4) -            return in; - -        LLSD out(LLSD::emptyArray()); - -        for (S32 idx = 0; idx < in.size(); ++idx) -        { -            out.append(in[idx]); -        } - -        while (out.size() < 4) -        { -            out.append(LLSD::Real(fill)); -        } -        return out; -    } - -    // This is a disturbing hack -    std::string legacy_name_to_filename(const std::string &name, bool convertdash = false) -    { -        std::string fixedname(LLURI::escape(name)); - -        if (convertdash) -            boost::algorithm::replace_all(fixedname, "-", "%2D"); - -        return fixedname; -    } - -    //--------------------------------------------------------------------- -    LLSD read_legacy_preset_data(const std::string &name, const std::string& path) -    { -        llifstream xml_file; - -        std::string full_path(path); -        std::string full_name(name); -        full_name += ".xml"; -        gDirUtilp->append(full_path, full_name); - -        xml_file.open(full_path.c_str()); -        if (!xml_file) -        { -            std::string bad_path(full_path); -            full_path = path; -            full_name = legacy_name_to_filename(name); -            full_name += ".xml"; -            gDirUtilp->append(full_path, full_name); - -            LL_INFOS("LEGACYSETTING") << "Could not open \"" << bad_path << "\" trying escaped \"" << full_path << "\"" << LL_ENDL; - -            xml_file.open(full_path.c_str()); -            if (!xml_file) -            { -                LL_WARNS("LEGACYSETTING") << "Unable to open legacy windlight \"" << name << "\" from " << path << LL_ENDL; - -                full_path = path; -                full_name = legacy_name_to_filename(name, true); -                full_name += ".xml"; -                gDirUtilp->append(full_path, full_name); -                xml_file.open(full_path.c_str()); -                if (!xml_file) -                { -                    LL_WARNS("LEGACYSETTING") << "Unable to open legacy windlight \"" << name << "\" from " << path << LL_ENDL; -                    return LLSD(); -                } -            } -        } - -        LLSD params_data; -        LLPointer<LLSDParser> parser = new LLSDXMLParser(); -        parser->parse(xml_file, params_data, LLSDSerialize::SIZE_UNLIMITED); -        xml_file.close(); - -        return params_data; -    } -} +/**
 +* @file llsettingsvo.cpp
 +* @author Rider Linden
 +* @brief Subclasses for viewer specific settings behaviors.
 +*
 +* $LicenseInfo:2011&license=viewerlgpl$
 +* Second Life Viewer Source Code
 +* Copyright (C) 2017, Linden Research, Inc.
 +*
 +* This library is free software; you can redistribute it and/or
 +* modify it under the terms of the GNU Lesser General Public
 +* License as published by the Free Software Foundation;
 +* version 2.1 of the License only.
 +*
 +* This library is distributed in the hope that it will be useful,
 +* but WITHOUT ANY WARRANTY; without even the implied warranty of
 +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +* Lesser General Public License for more details.
 +*
 +* You should have received a copy of the GNU Lesser General Public
 +* License along with this library; if not, write to the Free Software
 +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 +*
 +* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 +* $/LicenseInfo$
 +*/
 +
 +#include "llviewerprecompiledheaders.h"
 +#include "llviewercontrol.h"
 +#include "llsettingsvo.h"
 +
 +#include "pipeline.h"
 +
 +#include <algorithm>
 +#include <cstdio>
 +#include <boost/make_shared.hpp>
 +#include "lltrace.h"
 +#include "llfasttimer.h"
 +#include "v3colorutil.h"
 +
 +#include "llglslshader.h"
 +#include "llviewershadermgr.h"
 +
 +#include "llagent.h"
 +#include "llassettype.h"
 +#include "llfloaterperms.h"
 +#include "llnotificationsutil.h"
 +
 +#include "llviewerregion.h"
 +#include "llviewerassetupload.h"
 +#include "llviewerinventory.h"
 +
 +#include "llenvironment.h"
 +#include "llsky.h"
 +
 +#include "llpermissions.h"
 +
 +#include "llinventorymodel.h"
 +#include "llassetstorage.h"
 +#include "llvfile.h"
 +#include "lldrawpoolwater.h"
 +
 +#include <boost/algorithm/string/replace.hpp>
 +#include "llinventoryobserver.h"
 +#include "llinventorydefines.h"
 +
 +#undef  VERIFY_LEGACY_CONVERSION
 +
 +//=========================================================================
 +namespace 
 +{
 +    LLSD ensure_array_4(LLSD in, F32 fill);
 +    LLSD read_legacy_preset_data(const std::string &name, const std::string& path);
 +
 +    //-------------------------------------------------------------------------
 +    class LLSettingsInventoryCB : public LLInventoryCallback
 +    {
 +    public:
 +        typedef std::function<void(const LLUUID &)> callback_t;
 +
 +        LLSettingsInventoryCB(callback_t cbfn) :
 +            mCbfn(cbfn)
 +        { }
 +
 +        void fire(const LLUUID& inv_item) override  { if (mCbfn) mCbfn(inv_item); }
 +
 +    private:
 +        callback_t  mCbfn;
 +    };
 +
 +    //-------------------------------------------------------------------------
 +}
 +
 +
 +//=========================================================================
 +void LLSettingsVOBase::createNewInventoryItem(LLSettingsType::type_e stype, const LLUUID &parent_id, inventory_result_fn callback)
 +{
 +    LLTransactionID tid;
 +    U32 nextOwnerPerm = LLFloaterPerms::getNextOwnerPerms("Settings");
 +    nextOwnerPerm |= PERM_COPY;
 +
 +    if (!LLEnvironment::instance().isInventoryEnabled())
 +    {
 +        LL_WARNS("SETTINGS") << "Region does not support settings inventory objects." << LL_ENDL;
 +        LLNotificationsUtil::add("SettingsUnsuported");
 +        return;
 +    }
 +
 +    tid.generate();
 +
 +    LLPointer<LLInventoryCallback> cb = new LLSettingsInventoryCB([callback](const LLUUID &inventoryId) {
 +        LLSettingsVOBase::onInventoryItemCreated(inventoryId, LLSettingsBase::ptr_t(), callback);
 +    });
 +
 +    create_inventory_settings(gAgent.getID(), gAgent.getSessionID(),
 +        parent_id, LLTransactionID::tnull,
 +        LLSettingsType::getDefaultName(stype), "",
 +        stype, nextOwnerPerm, cb);
 +}
 +
 +
 +void LLSettingsVOBase::createInventoryItem(const LLSettingsBase::ptr_t &settings, const LLUUID &parent_id, std::string settings_name, inventory_result_fn callback)
 +{
 +    LLTransactionID tid;
 +    U32             nextOwnerPerm = LLPermissions::DEFAULT.getMaskNextOwner();
 +
 +    if (!LLEnvironment::instance().isInventoryEnabled())
 +    {
 +        LL_WARNS("SETTINGS") << "Region does not support settings inventory objects." << LL_ENDL;
 +        LLNotificationsUtil::add("SettingsUnsuported");
 +        return;
 +    }
 +
 +    tid.generate();
 +
 +    LLPointer<LLInventoryCallback> cb = new LLSettingsInventoryCB([settings, callback](const LLUUID &inventoryId) {
 +            LLSettingsVOBase::onInventoryItemCreated(inventoryId, settings, callback);
 +        });
 +
 +    if (settings_name.empty())
 +    {
 +        settings_name = settings->getName();
 +    }
 +    create_inventory_settings(gAgent.getID(), gAgent.getSessionID(),
 +        parent_id, tid,
 +        settings_name, "",
 +        settings->getSettingsTypeValue(), nextOwnerPerm, cb);
 +}
 +
 +void LLSettingsVOBase::onInventoryItemCreated(const LLUUID &inventoryId, LLSettingsBase::ptr_t settings, inventory_result_fn callback)
 +{
 +    if (!settings)
 +    {   // The item was created as new with no settings passed in.  Simulator should have given it the default for the type... check ID, 
 +        // no need to upload asset.
 +        LLUUID asset_id;
 +        LLViewerInventoryItem *pitem = gInventory.getItem(inventoryId);
 +
 +        if (pitem)
 +        {
 +            asset_id = pitem->getAssetUUID();
 +        }
 +        if (callback)
 +            callback(asset_id, inventoryId, LLUUID::null, LLSD());
 +        return;
 +    }
 +    // We need to update some inventory stuff here.... maybe.
 +    updateInventoryItem(settings, inventoryId, callback, false);
 +}
 +
 +void LLSettingsVOBase::updateInventoryItem(const LLSettingsBase::ptr_t &settings, LLUUID inv_item_id, inventory_result_fn callback, bool update_name)
 +{
 +    const LLViewerRegion* region = gAgent.getRegion();
 +    if (!region)
 +    {
 +        LL_WARNS("SETTINGS") << "Not connected to a region, cannot save setting." << LL_ENDL;
 +        return;
 +    }
 +
 +    std::string agent_url(region->getCapability("UpdateSettingsAgentInventory"));
 +
 +    if (!LLEnvironment::instance().isInventoryEnabled())
 +    {
 +        LL_WARNS("SETTINGS") << "Region does not support settings inventory objects." << LL_ENDL;
 +        LLNotificationsUtil::add("SettingsUnsuported");
 +        return;
 +    }
 +
 +    LLViewerInventoryItem *inv_item = gInventory.getItem(inv_item_id);
 +    if (inv_item)
 +    {
 +        bool need_update(false);
 +        LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(inv_item);
 +
 +        if (settings->getFlag(LLSettingsBase::FLAG_NOTRANS) && new_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()))
 +        {
 +            LLPermissions perm(inv_item->getPermissions());
 +            perm.setBaseBits(LLUUID::null, FALSE, PERM_TRANSFER);
 +            perm.setOwnerBits(LLUUID::null, FALSE, PERM_TRANSFER);
 +            new_item->setPermissions(perm);
 +            need_update |= true;
 +        }
 +        if (update_name && (settings->getName() != new_item->getName()))
 +        {
 +            new_item->rename(settings->getName());
 +            settings->setName(new_item->getName()); // account for corrections
 +            need_update |= true;
 +        }
 +        if (need_update)
 +        {
 +            new_item->updateServer(FALSE);
 +            gInventory.updateItem(new_item);
 +            gInventory.notifyObservers();
 +        }
 +    }
 +
 +    std::stringstream buffer; 
 +    LLSD settingdata(settings->getSettings());
 +    LLSDSerialize::serialize(settingdata, buffer, LLSDSerialize::LLSD_NOTATION);
 +
 +    LLResourceUploadInfo::ptr_t uploadInfo = std::make_shared<LLBufferedAssetUploadInfo>(inv_item_id, LLAssetType::AT_SETTINGS, buffer.str(), 
 +        [settings, callback](LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD response) {
 +            LLSettingsVOBase::onAgentAssetUploadComplete(itemId, newAssetId, newItemId, response, settings, callback);
 +        });
 +
 +    LLViewerAssetUpload::EnqueueInventoryUpload(agent_url, uploadInfo);
 +}
 +
 +void LLSettingsVOBase::updateInventoryItem(const LLSettingsBase::ptr_t &settings, LLUUID object_id, LLUUID inv_item_id, inventory_result_fn callback)
 +{
 +    const LLViewerRegion* region = gAgent.getRegion();
 +    if (!region)
 +    {
 +        LL_WARNS("SETTINGS") << "Not connected to a region, cannot save setting." << LL_ENDL;
 +        return;
 +    }
 +
 +    std::string agent_url(region->getCapability("UpdateSettingsAgentInventory"));
 +
 +    if (!LLEnvironment::instance().isInventoryEnabled())
 +    {
 +        LL_WARNS("SETTINGS") << "Region does not support settings inventory objects." << LL_ENDL;
 +        LLNotificationsUtil::add("SettingsUnsuported");
 +        return;
 +    }
 +
 +    std::stringstream buffer;
 +    LLSD settingdata(settings->getSettings());
 +
 +    LLSDSerialize::serialize(settingdata, buffer, LLSDSerialize::LLSD_NOTATION);
 +
 +    LLResourceUploadInfo::ptr_t uploadInfo = std::make_shared<LLBufferedAssetUploadInfo>(object_id, inv_item_id, LLAssetType::AT_SETTINGS, buffer.str(),
 +        [settings, callback](LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response) {
 +        LLSettingsVOBase::onTaskAssetUploadComplete(itemId, taskId, newAssetId, response, settings, callback);
 +    });
 +
 +    LLViewerAssetUpload::EnqueueInventoryUpload(agent_url, uploadInfo);
 +}
 +
 +void LLSettingsVOBase::onAgentAssetUploadComplete(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD response, LLSettingsBase::ptr_t psettings, inventory_result_fn callback)
 +{
 +    LL_INFOS("SETTINGS") << "itemId:" << itemId << " newAssetId:" << newAssetId << " newItemId:" << newItemId << " response:" << response << LL_ENDL;
 +    psettings->setAssetId(newAssetId);
 +    if (callback)
 +        callback( newAssetId, itemId, LLUUID::null, response );
 +
 +#if 0
 +    std::string exprtFile = gDirUtilp->getTempDir() + gDirUtilp->getDirDelimiter() + newAssetId.asString() + ".llsd";
 +
 +    LLSettingsVOBase::exportFile(psettings, exprtFile, LLSDSerialize::LLSD_NOTATION);
 +
 +    LL_WARNS("LAPRAS") << "SETTINGS File written as: '" << exprtFile << "'" << LL_ENDL;
 +#endif
 +}
 +
 +void LLSettingsVOBase::onTaskAssetUploadComplete(LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response, LLSettingsBase::ptr_t psettings, inventory_result_fn callback)
 +{
 +    LL_INFOS("SETTINGS") << "Upload to task complete!" << LL_ENDL;
 +    psettings->setAssetId(newAssetId);
 +    if (callback)
 +        callback(newAssetId, itemId, taskId, response);
 +}
 +
 +
 +void LLSettingsVOBase::getSettingsAsset(const LLUUID &assetId, LLSettingsVOBase::asset_download_fn callback)
 +{
 +    gAssetStorage->getAssetData(assetId, LLAssetType::AT_SETTINGS,
 +        [callback](LLVFS *vfs, const LLUUID &asset_id, LLAssetType::EType, void *, S32 status, LLExtStat ext_status) 
 +            { onAssetDownloadComplete(vfs, asset_id, status, ext_status, callback); },
 +        nullptr, true);
 +
 +}
 +
 +void LLSettingsVOBase::onAssetDownloadComplete(LLVFS *vfs, const LLUUID &asset_id, S32 status, LLExtStat ext_status, LLSettingsVOBase::asset_download_fn callback)
 +{
 +    LLSettingsBase::ptr_t settings;
 +    if (!status)
 +    {
 +        LLVFile file(vfs, asset_id, LLAssetType::AT_SETTINGS, LLVFile::READ);
 +        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, -1))
 +        {
 +            settings = createFromLLSD(llsdsettings);
 +        }
 +
 +        if (!settings)
 +        {
 +            status = 1;
 +            LL_WARNS("SETTINGS") << "Unable to create settings object." << LL_ENDL;
 +        }
 +        else
 +        {
 +            LL_WARNS("LAPRAS") << "Setting asset ID to " << asset_id << LL_ENDL;
 +            settings->setAssetId(asset_id);
 +        }
 +    }
 +    else
 +    {
 +        LL_WARNS("SETTINGS") << "Error retrieving asset " << asset_id << ". Status code=" << status << "(" << LLAssetStorage::getErrorString(status) << ") ext_status=" << ext_status << LL_ENDL;
 +    }
 +    if (callback)
 +        callback(asset_id, settings, status, ext_status);
 +}
 +
 +void LLSettingsVOBase::getSettingsInventory(const LLUUID &inventoryId, inventory_download_fn callback)
 +{
 +
 +}
 +
 +bool LLSettingsVOBase::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)
 +        {
 +            LL_WARNS("SETTINGS") << "Unable to open '" << filename << "' for writing." << LL_ENDL;
 +            return false;
 +        }
 +
 +        LLSDSerialize::serialize(settings->getSettings(), file, format);
 +    }
 +    catch (const std::ios_base::failure &e)
 +    {
 +        LL_WARNS("SETTINGS") << "Unable to save settings to file '" << filename << "': " << e.what() << LL_ENDL;
 +        return false;
 +    }
 +
 +    return true;
 +}
 +
 +LLSettingsBase::ptr_t LLSettingsVOBase::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)
 +        {
 +            LL_WARNS("SETTINGS") << "Unable to open '" << filename << "' for reading." << LL_ENDL;
 +            return LLSettingsBase::ptr_t();
 +        }
 +
 +        if (!LLSDSerialize::deserialize(settings, file, -1))
 +        {
 +            LL_WARNS("SETTINGS") << "Unable to deserialize settings from '" << filename << "'" << LL_ENDL;
 +            return LLSettingsBase::ptr_t();
 +        }
 +    }
 +    catch (const std::ios_base::failure &e)
 +    {
 +        LL_WARNS("SETTINGS") << "Unable to save settings to file '" << filename << "': " << e.what() << LL_ENDL;
 +        return LLSettingsBase::ptr_t();
 +    }
 +
 +    return createFromLLSD(settings);
 +}
 +
 +LLSettingsBase::ptr_t LLSettingsVOBase::createFromLLSD(const LLSD &settings)
 +{
 +    if (!settings.has(SETTING_TYPE))
 +    {
 +        LL_WARNS("SETTINGS") << "No settings type in LLSD" << LL_ENDL;
 +        return LLSettingsBase::ptr_t();
 +    }
 +
 +    std::string settingtype = settings[SETTING_TYPE].asString();
 +
 +    LLSettingsBase::ptr_t psetting;
 +
 +    if (settingtype == "water")
 +    {
 +        return LLSettingsVOWater::buildWater(settings);
 +    }
 +    else if (settingtype == "sky")
 +    {
 +        return LLSettingsVOSky::buildSky(settings);
 +    }
 +    else if (settingtype == "daycycle")
 +    {
 +        return LLSettingsVODay::buildDay(settings);
 +    }
 +
 +    LL_WARNS("SETTINGS") << "Unable to determine settings type for '" << settingtype << "'." << LL_ENDL;
 +    return LLSettingsBase::ptr_t();
 +
 +}
 +
 +//=========================================================================
 +LLSettingsVOSky::LLSettingsVOSky(const LLSD &data, bool isAdvanced)
 +: LLSettingsSky(data)
 +, m_isAdvanced(isAdvanced)
 +{
 +}
 +
 +LLSettingsVOSky::LLSettingsVOSky()
 +: LLSettingsSky()
 +, m_isAdvanced(false)
 +{
 +}
 +
 +//-------------------------------------------------------------------------
 +LLSettingsSky::ptr_t LLSettingsVOSky::buildSky(LLSD settings)
 +{
 +    LLSettingsSky::validation_list_t validations = LLSettingsSky::validationList();
 +
 +    LLSD results = LLSettingsBase::settingValidation(settings, validations);
 +
 +    if (!results["success"].asBoolean())
 +    {
 +        LL_WARNS("SETTINGS") << "Sky setting validation failed!\n" << results << LL_ENDL;
 +        LLSettingsSky::ptr_t();
 +    }
 +
 +    return std::make_shared<LLSettingsVOSky>(settings, true);
 +}
 +
 +
 +LLSettingsSky::ptr_t LLSettingsVOSky::buildFromLegacyPreset(const std::string &name, const LLSD &legacy)
 +{
 +
 +    LLSD newsettings = LLSettingsSky::translateLegacySettings(legacy);
 +
 +    newsettings[SETTING_NAME] = name;
 +
 +    LLSettingsSky::validation_list_t validations = LLSettingsSky::validationList();
 +    LLSD results = LLSettingsBase::settingValidation(newsettings, validations);
 +    if (!results["success"].asBoolean())
 +    {
 +        LL_WARNS("SETTINGS") << "Sky setting validation failed!\n" << results << LL_ENDL;
 +        LLSettingsSky::ptr_t();
 +    }
 +
 +    LLSettingsSky::ptr_t skyp = std::make_shared<LLSettingsVOSky>(newsettings);
 +
 +#ifdef VERIFY_LEGACY_CONVERSION
 +    LLSD oldsettings = LLSettingsVOSky::convertToLegacy(skyp, isAdvanced());
 +
 +    if (!llsd_equals(legacy, oldsettings))
 +    {
 +        LL_WARNS("SKY") << "Conversion to/from legacy does not match!\n" 
 +            << "Old: " << legacy
 +            << "new: " << oldsettings << LL_ENDL;
 +    }
 +
 +#endif
 +
 +    return skyp;
 +}
 +
 +LLSettingsSky::ptr_t LLSettingsVOSky::buildFromLegacyPresetFile(const std::string &name, const std::string &path)
 +{
 +    LLSD legacy_data = read_legacy_preset_data(name, path);
 +
 +    if (!legacy_data)
 +    {
 +        LL_WARNS("SETTINGS") << "Could not load legacy Windlight \"" << name << "\" from " << path << LL_ENDL;
 +        return ptr_t();
 +    }
 +
 +    return buildFromLegacyPreset(name, legacy_data);
 +}
 +
 +
 +LLSettingsSky::ptr_t LLSettingsVOSky::buildDefaultSky()
 +{
 +    static LLSD default_settings;
 +
 +    if (!default_settings.size())
 +    {
 +        default_settings = LLSettingsSky::defaults();
 +
 +        default_settings[SETTING_NAME] = std::string("_default_");
 +
 +        LLSettingsSky::validation_list_t validations = LLSettingsSky::validationList();
 +        LLSD results = LLSettingsBase::settingValidation(default_settings, validations);
 +        if (!results["success"].asBoolean())
 +        {
 +            LL_WARNS("SETTINGS") << "Sky setting validation failed!\n" << results << LL_ENDL;
 +            LLSettingsSky::ptr_t();
 +        }
 +    }
 +
 +    LLSettingsSky::ptr_t skyp = std::make_shared<LLSettingsVOSky>(default_settings);
 +    return skyp;
 +}
 +
 +LLSettingsSky::ptr_t LLSettingsVOSky::buildClone() const
 +{
 +    LLSD settings = cloneSettings();
 +
 +    LLSettingsSky::validation_list_t validations = LLSettingsSky::validationList();
 +    LLSD results = LLSettingsBase::settingValidation(settings, validations);
 +    if (!results["success"].asBoolean())
 +    {
 +        LL_WARNS("SETTINGS") << "Sky setting validation failed!\n" << results << LL_ENDL;
 +        LLSettingsSky::ptr_t();
 +    }
 +
 +    LLSettingsSky::ptr_t skyp = std::make_shared<LLSettingsVOSky>(settings);
 +    return skyp;
 +}
 +
 +void LLSettingsVOSky::convertAtmosphericsToLegacy(LLSD& legacy, LLSD& settings)
 +{
 +    // These may need to be inferred from new settings' density profiles
 +    // if the legacy settings values are not available.
 +    if (settings.has(SETTING_LEGACY_HAZE))
 +    {
 +        LLSD legacyhaze = settings[SETTING_LEGACY_HAZE];
 +
 +        // work-around for setter formerly putting ambient values in wrong loc...
 +        if (legacyhaze.has(SETTING_AMBIENT))
 +        {
 +            legacy[SETTING_AMBIENT] = ensure_array_4(legacyhaze[SETTING_AMBIENT], 1.0f);
 +        }
 +        else if (settings.has(SETTING_AMBIENT))
 +        {
 +            legacy[SETTING_AMBIENT] = ensure_array_4(settings[SETTING_AMBIENT], 1.0f);
 +        }
 +
 +        legacy[SETTING_BLUE_DENSITY] = ensure_array_4(legacyhaze[SETTING_BLUE_DENSITY], 1.0);
 +        legacy[SETTING_BLUE_HORIZON] = ensure_array_4(legacyhaze[SETTING_BLUE_HORIZON], 1.0);
 +
 +        F32 density_multiplier = legacyhaze[SETTING_DENSITY_MULTIPLIER].asReal();
 +        density_multiplier = (density_multiplier < 0.0001f) ? 0.0001f : density_multiplier;
 +        legacy[SETTING_DENSITY_MULTIPLIER] = LLSDArray(density_multiplier)(0.0f)(0.0f)(1.0f);
 +
 +        F32 distance_multiplier = legacyhaze[SETTING_DISTANCE_MULTIPLIER].asReal();
 +        legacy[SETTING_DISTANCE_MULTIPLIER] = LLSDArray(distance_multiplier)(0.0f)(0.0f)(1.0f);
 +
 +        legacy[SETTING_HAZE_DENSITY]        = LLSDArray(legacyhaze[SETTING_HAZE_DENSITY])(0.0f)(0.0f)(1.0f);
 +        legacy[SETTING_HAZE_HORIZON]        = LLSDArray(legacyhaze[SETTING_HAZE_HORIZON])(0.0f)(0.0f)(1.0f);
 +    }
 +}
 +
 +LLSD LLSettingsVOSky::convertToLegacy(const LLSettingsSky::ptr_t &psky, bool isAdvanced)
 +{
 +    LLSD legacy(LLSD::emptyMap());
 +    LLSD settings = psky->getSettings();
 +    
 +    convertAtmosphericsToLegacy(legacy, settings);
 +
 +    legacy[SETTING_CLOUD_COLOR] = ensure_array_4(settings[SETTING_CLOUD_COLOR], 1.0);
 +    legacy[SETTING_CLOUD_POS_DENSITY1] = ensure_array_4(settings[SETTING_CLOUD_POS_DENSITY1], 1.0);
 +    legacy[SETTING_CLOUD_POS_DENSITY2] = ensure_array_4(settings[SETTING_CLOUD_POS_DENSITY2], 1.0);
 +    legacy[SETTING_CLOUD_SCALE] = LLSDArray(settings[SETTING_CLOUD_SCALE])(LLSD::Real(0.0))(LLSD::Real(0.0))(LLSD::Real(1.0));       
 +    legacy[SETTING_CLOUD_SCROLL_RATE] = settings[SETTING_CLOUD_SCROLL_RATE];
 +    legacy[SETTING_LEGACY_ENABLE_CLOUD_SCROLL] = LLSDArray(LLSD::Boolean(!is_approx_zero(settings[SETTING_CLOUD_SCROLL_RATE][0].asReal())))
 +        (LLSD::Boolean(!is_approx_zero(settings[SETTING_CLOUD_SCROLL_RATE][1].asReal())));     
 +    legacy[SETTING_CLOUD_SHADOW] = LLSDArray(settings[SETTING_CLOUD_SHADOW].asReal())(0.0f)(0.0f)(1.0f);    
 +    legacy[SETTING_GAMMA] = LLSDArray(settings[SETTING_GAMMA])(0.0f)(0.0f)(1.0f);
 +    legacy[SETTING_GLOW] = ensure_array_4(settings[SETTING_GLOW], 1.0);
 +    legacy[SETTING_LIGHT_NORMAL] = ensure_array_4(psky->getLightDirection().getValue(), 0.0f);
 +    legacy[SETTING_MAX_Y] = LLSDArray(settings[SETTING_MAX_Y])(0.0f)(0.0f)(1.0f);
 +    legacy[SETTING_STAR_BRIGHTNESS] = settings[SETTING_STAR_BRIGHTNESS];
 +    legacy[SETTING_SUNLIGHT_COLOR] = ensure_array_4(settings[SETTING_SUNLIGHT_COLOR], 1.0f);
 +    
 +    LLVector3 dir = psky->getLightDirection();
 +
 +    F32 phi     = asin(dir.mV[2]);
 +    F32 cos_phi = cosf(phi);
 +    F32 theta   = (cos_phi != 0) ? asin(dir.mV[1] / cos_phi) : 0.0f;
 +
 +    theta = -theta;
 +
 +    // get angles back into valid ranges for legacy viewer...
 +    //
 +    while (theta < 0)
 +    {
 +        theta += F_PI * 2;
 +    }
 +    
 +    if (theta > 4 * F_PI)
 +    {
 +        theta = fmod(theta, 2 * F_PI);
 +    }
 +    
 +    while (phi < -F_PI)
 +    {
 +        phi += 2 * F_PI;
 +    }
 +    
 +    if (phi > 3 * F_PI)
 +    {
 +        phi = F_PI + fmod(phi - F_PI, 2 * F_PI);
 +    }
 +
 +    legacy[SETTING_LEGACY_EAST_ANGLE] = theta;
 +    legacy[SETTING_LEGACY_SUN_ANGLE]  = phi;
 + 
 +   return legacy;    
 +}
 +
 +//-------------------------------------------------------------------------
 +void LLSettingsVOSky::updateSettings()
 +{
 +    LLSettingsSky::updateSettings();
 +    LLVector3 sun_direction  = getSunDirection();
 +    LLVector3 moon_direction = getMoonDirection();
 +
 +    F32 dp = getLightDirection() * LLVector3(0.0f, 0.0f, 1.0f);
 +	if (dp < 0)
 +	{
 +		dp = 0;
 +	}
 +    dp = llmax(dp, 0.1f);
 +
 +	// 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.
 +	F32 sun_dynamic_range = llmax(gSavedSettings.getF32("RenderSunDynamicRange"), 0.0001f);
 +    mSceneLightStrength = 2.0f * (1.0f + sun_dynamic_range * dp);
 +
 +    gSky.setSunAndMoonDirectionsCFR(sun_direction, moon_direction);
 +    gSky.setSunTextures(getSunTextureId(), getNextSunTextureId());
 +    gSky.setMoonTextures(getMoonTextureId(), getNextMoonTextureId());
 +    gSky.setCloudNoiseTextures(getCloudNoiseTextureId(), getNextCloudNoiseTextureId());
 +    gSky.setBloomTextures(getBloomTextureId(), getNextBloomTextureId());
 +
 +    gSky.setSunScale(getSunScale());
 +    gSky.setMoonScale(getMoonScale());
 +}
 +
 +void LLSettingsVOSky::applySpecial(void *ptarget)
 +{
 +    LLGLSLShader *shader = (LLGLSLShader *)ptarget;
 +
 +    LLVector4 light_direction = LLEnvironment::instance().getClampedSunNorm();
 +
 +    if (shader->mShaderGroup == LLGLSLShader::SG_DEFAULT)
 +	{        
 +        shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, light_direction.mV);
 +		shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV);
 +	} 
 +	else if (shader->mShaderGroup == LLGLSLShader::SG_SKY)
 +	{
 +        shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, light_direction.mV);        
 +
 +        LLVector4 vect_c_p_d1(mSettings[SETTING_CLOUD_POS_DENSITY1]);
 +        vect_c_p_d1 += LLVector4(LLEnvironment::instance().getCloudScrollDelta());
 +        shader->uniform4fv(LLShaderMgr::CLOUD_POS_DENSITY1, 1, vect_c_p_d1.mV);
 +	}
 +
 +    shader->uniform1f(LLShaderMgr::SCENE_LIGHT_STRENGTH, mSceneLightStrength);
 +    shader->uniform4f(LLShaderMgr::GAMMA, getGamma(), 0.0, 0.0, 1.0);
 +}
 +
 +LLSettingsSky::parammapping_t LLSettingsVOSky::getParameterMap() const
 +{
 +    static parammapping_t param_map;
 +
 +    if (param_map.empty())
 +    {
 +// LEGACY_ATMOSPHERICS
 +        param_map[SETTING_AMBIENT] = LLShaderMgr::AMBIENT;
 +        param_map[SETTING_BLUE_DENSITY] = LLShaderMgr::BLUE_DENSITY;
 +        param_map[SETTING_BLUE_HORIZON] = LLShaderMgr::BLUE_HORIZON;
 +        param_map[SETTING_HAZE_DENSITY] = LLShaderMgr::HAZE_DENSITY;
 +        param_map[SETTING_HAZE_HORIZON] = LLShaderMgr::HAZE_HORIZON;
 +        param_map[SETTING_DENSITY_MULTIPLIER] = LLShaderMgr::DENSITY_MULTIPLIER;
 +        param_map[SETTING_DISTANCE_MULTIPLIER] = LLShaderMgr::DISTANCE_MULTIPLIER;
 +
 +        param_map[SETTING_CLOUD_COLOR] = LLShaderMgr::CLOUD_COLOR;
 +        param_map[SETTING_CLOUD_POS_DENSITY2] = LLShaderMgr::CLOUD_POS_DENSITY2;
 +        param_map[SETTING_CLOUD_SCALE] = LLShaderMgr::CLOUD_SCALE;
 +        param_map[SETTING_CLOUD_SHADOW] = LLShaderMgr::CLOUD_SHADOW;       
 +        param_map[SETTING_CLOUD_VARIANCE] = LLShaderMgr::CLOUD_VARIANCE;
 +        param_map[SETTING_GLOW] = LLShaderMgr::GLOW;        
 +        param_map[SETTING_MAX_Y] = LLShaderMgr::MAX_Y;
 +        param_map[SETTING_SUNLIGHT_COLOR] = LLShaderMgr::SUNLIGHT_COLOR;
 +        param_map[SETTING_MOON_BRIGHTNESS] = LLShaderMgr::MOON_BRIGHTNESS;
 +        param_map[SETTING_SKY_MOISTURE_LEVEL] = LLShaderMgr::MOISTURE_LEVEL;
 +        param_map[SETTING_SKY_DROPLET_RADIUS] = LLShaderMgr::DROPLET_RADIUS;
 +        param_map[SETTING_SKY_ICE_LEVEL] = LLShaderMgr::ICE_LEVEL;
 +
 +// AdvancedAtmospherics TODO
 +// Provide mappings for new shader params here
 +    }
 +
 +    return param_map;
 +}
 +
 +//=========================================================================
 +const F32 LLSettingsVOWater::WATER_FOG_LIGHT_CLAMP(0.3f);
 +
 +//-------------------------------------------------------------------------
 +LLSettingsVOWater::LLSettingsVOWater(const LLSD &data) :
 +    LLSettingsWater(data)
 +{
 +
 +}
 +
 +LLSettingsVOWater::LLSettingsVOWater() :
 +    LLSettingsWater()
 +{
 +
 +}
 +
 +LLSettingsWater::ptr_t LLSettingsVOWater::buildWater(LLSD settings)
 +{
 +    LLSettingsWater::validation_list_t validations = LLSettingsWater::validationList();
 +    LLSD results = LLSettingsWater::settingValidation(settings, validations);
 +    if (!results["success"].asBoolean())
 +    {
 +        LL_WARNS("SETTINGS") << "Water setting validation failed!\n" << results << LL_ENDL;
 +        LLSettingsWater::ptr_t();
 +    }
 +
 +    return std::make_shared<LLSettingsVOWater>(settings);
 +}
 +
 +//-------------------------------------------------------------------------
 +LLSettingsWater::ptr_t LLSettingsVOWater::buildFromLegacyPreset(const std::string &name, const LLSD &legacy)
 +{
 +    LLSD newsettings(LLSettingsWater::translateLegacySettings(legacy));
 +
 +    newsettings[SETTING_NAME] = name; 
 +    LLSettingsWater::validation_list_t validations = LLSettingsWater::validationList();
 +    LLSD results = LLSettingsWater::settingValidation(newsettings, validations);
 +    if (!results["success"].asBoolean())
 +    {
 +        LL_WARNS("SETTINGS") << "Water setting validation failed!: " << results << LL_ENDL;
 +        return LLSettingsWater::ptr_t();
 +    }
 +
 +    LLSettingsWater::ptr_t waterp = std::make_shared<LLSettingsVOWater>(newsettings);
 +
 +#ifdef VERIFY_LEGACY_CONVERSION
 +    LLSD oldsettings = LLSettingsVOWater::convertToLegacy(waterp);
 +
 +    if (!llsd_equals(legacy, oldsettings))
 +    {
 +        LL_WARNS("WATER") << "Conversion to/from legacy does not match!\n"
 +            << "Old: " << legacy
 +            << "new: " << oldsettings << LL_ENDL;
 +    }
 +
 +#endif
 +    return waterp;
 +}
 +
 +LLSettingsWater::ptr_t LLSettingsVOWater::buildFromLegacyPresetFile(const std::string &name, const std::string &path)
 +{
 +    LLSD legacy_data = read_legacy_preset_data(name, path);
 +
 +    if (!legacy_data)
 +    {
 +        LL_WARNS("SETTINGS") << "Could not load legacy Windlight \"" << name << "\" from " << path << LL_ENDL;
 +        return ptr_t();
 +    }
 +
 +    return buildFromLegacyPreset(name, legacy_data);
 +}
 +
 +
 +LLSettingsWater::ptr_t LLSettingsVOWater::buildDefaultWater()
 +{
 +    static LLSD default_settings;
 +
 +    if (!default_settings.size())
 +    {
 +        default_settings = LLSettingsWater::defaults();
 +
 +        default_settings[SETTING_NAME] = std::string("_default_");
 +
 +        LLSettingsWater::validation_list_t validations = LLSettingsWater::validationList();
 +        LLSD results = LLSettingsWater::settingValidation(default_settings, validations);
 +        if (!results["success"].asBoolean())
 +        {
 +            LL_WARNS("SETTINGS") << "Water setting validation failed!: " << results << LL_ENDL;
 +            return LLSettingsWater::ptr_t();
 +        }
 +    }
 +
 +    LLSettingsWater::ptr_t waterp = std::make_shared<LLSettingsVOWater>(default_settings);
 +
 +    return waterp;
 +}
 +
 +LLSettingsWater::ptr_t LLSettingsVOWater::buildClone() const
 +{
 +    LLSD settings = cloneSettings();
 +    LLSettingsWater::validation_list_t validations = LLSettingsWater::validationList();
 +    LLSD results = LLSettingsWater::settingValidation(settings, validations);
 +    if (!results["success"].asBoolean())
 +    {
 +        LL_WARNS("SETTINGS") << "Water setting validation failed!: " << results << LL_ENDL;
 +        return LLSettingsWater::ptr_t();
 +    }
 +
 +    LLSettingsWater::ptr_t waterp = std::make_shared<LLSettingsVOWater>(settings);
 +
 +    return waterp;
 +}
 +
 +LLSD LLSettingsVOWater::convertToLegacy(const LLSettingsWater::ptr_t &pwater)
 +{
 +    LLSD legacy(LLSD::emptyMap());
 +    LLSD settings = pwater->getSettings();
 +
 +    legacy[SETTING_LEGACY_BLUR_MULTIPLIER] = settings[SETTING_BLUR_MULTIPLIER];
 +    legacy[SETTING_LEGACY_FOG_COLOR] = ensure_array_4(settings[SETTING_FOG_COLOR], 1.0f);
 +    legacy[SETTING_LEGACY_FOG_DENSITY] = settings[SETTING_FOG_DENSITY];
 +    legacy[SETTING_LEGACY_FOG_MOD] = settings[SETTING_FOG_MOD];
 +    legacy[SETTING_LEGACY_FRESNEL_OFFSET] = settings[SETTING_FRESNEL_OFFSET];
 +    legacy[SETTING_LEGACY_FRESNEL_SCALE] = settings[SETTING_FRESNEL_SCALE];
 +    legacy[SETTING_LEGACY_NORMAL_MAP] = settings[SETTING_NORMAL_MAP];
 +    legacy[SETTING_LEGACY_NORMAL_SCALE] = settings[SETTING_NORMAL_SCALE];
 +    legacy[SETTING_LEGACY_SCALE_ABOVE] = settings[SETTING_SCALE_ABOVE];
 +    legacy[SETTING_LEGACY_SCALE_BELOW] = settings[SETTING_SCALE_BELOW];
 +    legacy[SETTING_LEGACY_WAVE1_DIR] = settings[SETTING_WAVE1_DIR];
 +    legacy[SETTING_LEGACY_WAVE2_DIR] = settings[SETTING_WAVE2_DIR];
 +    
 +    //_WARNS("LAPRAS") << "Legacy water: " << legacy << LL_ENDL;
 +    return legacy;
 +}
 +//-------------------------------------------------------------------------
 +//-------------------------------------------------------------------------
 +void LLSettingsVOWater::applySpecial(void *ptarget)
 +{
 +    LLGLSLShader *shader = (LLGLSLShader *)ptarget;
 +
 +    if (shader->mShaderGroup == LLGLSLShader::SG_WATER)
 +	{
 +        //transform water plane to eye space
 +        glh::vec3f norm(0.f, 0.f, 1.f);
 +        glh::vec3f p(0.f, 0.f, LLEnvironment::instance().getWaterHeight() + 0.1f);
 +
 +        F32 modelView[16];
 +        for (U32 i = 0; i < 16; i++)
 +        {
 +            modelView[i] = (F32)gGLModelView[i];
 +        }
 +
 +        glh::matrix4f mat(modelView);
 +        glh::matrix4f invtrans = mat.inverse().transpose();
 +        glh::vec3f enorm;
 +        glh::vec3f ep;
 +        invtrans.mult_matrix_vec(norm, enorm);
 +        enorm.normalize();
 +        mat.mult_matrix_vec(p, ep);
 +
 +        LLVector4 waterPlane(enorm.v[0], enorm.v[1], enorm.v[2], -ep.dot(enorm));
 +
 +        shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, waterPlane.mV);
 +
 +        LLVector4 light_direction = LLEnvironment::instance().getClampedLightNorm();
 +
 +        F32 waterFogKS = 1.f / llmax(light_direction.mV[2], WATER_FOG_LIGHT_CLAMP);
 +
 +        shader->uniform1f(LLShaderMgr::WATER_FOGKS, waterFogKS);
 +
 +        F32 blend_factor = LLEnvironment::instance().getCurrentWater()->getBlendFactor();
 +        shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
 +
 +        LLVector4 rotated_light_direction = LLEnvironment::instance().getRotatedLightNorm();
 +        shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, rotated_light_direction.mV);
 +        shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV);
 +        shader->uniform1f(LLViewerShaderMgr::DISTANCE_MULTIPLIER, 0);
 +    }
 +}
 +
 +void LLSettingsVOWater::updateSettings()
 +{
 +    // base class clears dirty flag so as to not trigger recursive update
 +    LLSettingsBase::updateSettings();
 +
 +    LLDrawPoolWater* pwaterpool = (LLDrawPoolWater*)gPipeline.getPool(LLDrawPool::POOL_WATER);
 +    if (pwaterpool)
 +    {
 +        pwaterpool->setTransparentTextures(getTransparentTextureID(), getNextTransparentTextureID());
 +        pwaterpool->setOpaqueTexture(GetDefaultOpaqueTextureAssetId());
 +        pwaterpool->setNormalMaps(getNormalMapID(), getNextNormalMapID());
 +    }
 +}
 +
 +LLSettingsWater::parammapping_t LLSettingsVOWater::getParameterMap() const
 +{
 +    static parammapping_t param_map;
 +
 +    if (param_map.empty())
 +    {
 +        param_map[SETTING_FOG_COLOR] = LLShaderMgr::WATER_FOGCOLOR;
 +        param_map[SETTING_FOG_DENSITY] = LLShaderMgr::WATER_FOGDENSITY;
 +    }
 +    return param_map;
 +}
 +
 +//=========================================================================
 +LLSettingsVODay::LLSettingsVODay(const LLSD &data):
 +    LLSettingsDay(data)
 +{}
 +
 +LLSettingsVODay::LLSettingsVODay():
 +    LLSettingsDay()
 +{}
 +
 +LLSettingsDay::ptr_t LLSettingsVODay::buildDay(LLSD settings)
 +{
 +    LLSettingsDay::validation_list_t validations = LLSettingsDay::validationList();
 +    LLSD results = LLSettingsDay::settingValidation(settings, validations);
 +    if (!results["success"].asBoolean())
 +    {
 +        LL_WARNS("SETTINGS") << "Day setting validation failed!\n" << results << LL_ENDL;
 +        LLSettingsDay::ptr_t();
 +    }
 +
 +    LLSettingsDay::ptr_t pday = std::make_shared<LLSettingsVODay>(settings);
 +    if (pday)
 +        pday->initialize();
 +
 +    return pday;
 +}
 +
 +//-------------------------------------------------------------------------
 +LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyPreset(const std::string &name, const std::string &path, const LLSD &oldsettings)
 +{
 +    LLSD newsettings(defaults());
 +    std::set<std::string> framenames;
 +    std::set<std::string> notfound;
 +
 +    std::string base_path(gDirUtilp->getDirName(path));
 +    std::string water_path(base_path);
 +    std::string sky_path(base_path);
 +
 +    gDirUtilp->append(water_path, "water");
 +    gDirUtilp->append(sky_path, "skies");
 +
 +    newsettings[SETTING_NAME] = name;
 +
 +    LLSD watertrack = LLSDArray(
 +        LLSDMap(SETTING_KEYKFRAME, LLSD::Real(0.0f))
 +        (SETTING_KEYNAME, "water:Default"));
 +
 +    LLSD skytrack = LLSD::emptyArray();
 +
 +    for (LLSD::array_const_iterator it = oldsettings.beginArray(); it != oldsettings.endArray(); ++it)
 +    {
 +        std::string framename = (*it)[1].asString();
 +        LLSD entry = LLSDMap(SETTING_KEYKFRAME, (*it)[0].asReal())
 +            (SETTING_KEYNAME, "sky:" + framename);
 +        framenames.insert(framename);
 +        skytrack.append(entry);
 +    }
 +
 +    newsettings[SETTING_TRACKS] = LLSDArray(watertrack)(skytrack);
 +
 +    LLSD frames(LLSD::emptyMap());
 +
 +    {
 +        LLSettingsWater::ptr_t pwater = LLSettingsVOWater::buildFromLegacyPresetFile("Default", water_path);
 +        if (pwater)
 +            frames["water:Default"] = pwater->getSettings();
 +    }
 +
 +    for (std::set<std::string>::iterator itn = framenames.begin(); itn != framenames.end(); ++itn)
 +    {
 +        LLSettingsSky::ptr_t psky = LLSettingsVOSky::buildFromLegacyPresetFile((*itn), sky_path);
 +        if (psky)
 +            frames["sky:" + (*itn)] = psky->getSettings();
 +    }
 +
 +    newsettings[SETTING_FRAMES] = frames;
 +
 +    LLSettingsDay::validation_list_t validations = LLSettingsDay::validationList();
 +    LLSD results = LLSettingsDay::settingValidation(newsettings, validations);
 +    if (!results["success"].asBoolean())
 +    {
 +        LL_WARNS("SETTINGS") << "Day setting validation failed!: " << results << LL_ENDL;
 +        return LLSettingsDay::ptr_t();
 +    }
 +
 +    LLSettingsDay::ptr_t dayp = std::make_shared<LLSettingsVODay>(newsettings);
 +
 +#ifdef VERIFY_LEGACY_CONVERSION
 +    LLSD testsettings = LLSettingsVODay::convertToLegacy(dayp);
 +
 +    if (!llsd_equals(oldsettings, testsettings))
 +    {
 +        LL_WARNS("DAYCYCLE") << "Conversion to/from legacy does not match!\n" 
 +            << "Old: " << oldsettings
 +            << "new: " << testsettings << LL_ENDL;
 +    }
 +
 +#endif
 +
 +    dayp->initialize();
 +
 +    return dayp;
 +}
 +
 +LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyPresetFile(const std::string &name, const std::string &path)
 +{
 +    LLSD legacy_data = read_legacy_preset_data(name, path);
 +
 +    if (!legacy_data)
 +    {
 +        LL_WARNS("SETTINGS") << "Could not load legacy Windlight \"" << name << "\" from " << path << LL_ENDL;
 +        return ptr_t();
 +    }
 +
 +    return buildFromLegacyPreset(name, path, legacy_data);
 +}
 +
 +
 +
 +LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyMessage(const LLUUID ®ionId, LLSD daycycle, LLSD skydefs, LLSD waterdef)
 +{
 +    LLSD frames(LLSD::emptyMap());
 +
 +    for (LLSD::map_iterator itm = skydefs.beginMap(); itm != skydefs.endMap(); ++itm)
 +    {
 +        std::string newname = "sky:" + (*itm).first;
 +        LLSD newsettings = LLSettingsSky::translateLegacySettings((*itm).second);
 +        
 +        newsettings[SETTING_NAME] = newname;
 +        frames[newname] = newsettings;
 +
 +        LL_WARNS("SETTINGS") << "created region sky '" << newname << "'" << LL_ENDL;
 +    }
 +
 +    LLSD watersettings = LLSettingsWater::translateLegacySettings(waterdef);
 +    std::string watername = "water:"+ watersettings[SETTING_NAME].asString();
 +    watersettings[SETTING_NAME] = watername;
 +    frames[watername] = watersettings;
 +
 +    LLSD watertrack = LLSDArray(
 +            LLSDMap(SETTING_KEYKFRAME, LLSD::Real(0.0f))
 +            (SETTING_KEYNAME, watername));
 +
 +    LLSD skytrack(LLSD::emptyArray());
 +    for (LLSD::array_const_iterator it = daycycle.beginArray(); it != daycycle.endArray(); ++it)
 +    {
 +        LLSD entry = LLSDMap(SETTING_KEYKFRAME, (*it)[0].asReal())
 +            (SETTING_KEYNAME, "sky:" + (*it)[1].asString());
 +        skytrack.append(entry);
 +    }
 +
 +    LLSD newsettings = LLSDMap
 +        ( SETTING_NAME, "Region (legacy)" )
 +        ( SETTING_TRACKS, LLSDArray(watertrack)(skytrack))
 +        ( SETTING_FRAMES, frames )
 +        ( SETTING_TYPE, "daycycle" );
 +
 +    LL_WARNS("LAPRAS") << "newsettings=" << newsettings << LL_ENDL;
 +
 +    LLSettingsSky::validation_list_t validations = LLSettingsDay::validationList();
 +    LLSD results = LLSettingsDay::settingValidation(newsettings, validations);
 +    if (!results["success"].asBoolean())
 +    {
 +        LL_WARNS("SETTINGS") << "Day setting validation failed!:" << results << LL_ENDL;
 +        return LLSettingsDay::ptr_t();
 +    }
 +
 +    LLSettingsDay::ptr_t dayp = std::make_shared<LLSettingsVODay>(newsettings);
 +    
 +    if (dayp)
 +    {
 +        // true for validation - either validate here, or when cloning for floater.
 +        dayp->initialize(true);
 +    }
 +    return dayp;
 +}
 +
 +
 +
 +LLSettingsDay::ptr_t LLSettingsVODay::buildDefaultDayCycle()
 +{
 +    static LLSD default_settings;
 +
 +    if (!default_settings.size())
 +    {
 +        default_settings = LLSettingsDay::defaults();
 +        default_settings[SETTING_NAME] = std::string("_default_");
 +
 +        LLSettingsDay::validation_list_t validations = LLSettingsDay::validationList();
 +        LLSD results = LLSettingsDay::settingValidation(default_settings, validations);
 +        if (!results["success"].asBoolean())
 +        {
 +            LL_WARNS("SETTINGS") << "Day setting validation failed!\n" << results << LL_ENDL;
 +            LLSettingsDay::ptr_t();
 +        }
 +    }
 +
 +    LLSettingsDay::ptr_t dayp = std::make_shared<LLSettingsVODay>(default_settings);
 +
 +    dayp->initialize();
 +    return dayp;
 +}
 +
 +LLSettingsDay::ptr_t LLSettingsVODay::buildFromEnvironmentMessage(LLSD settings)
 +{
 +    LLSettingsDay::validation_list_t validations = LLSettingsDay::validationList();
 +    LLSD results = LLSettingsDay::settingValidation(settings, validations);
 +    if (!results["success"].asBoolean())
 +    {
 +        LL_WARNS("SETTINGS") << "Day setting validation failed!\n" << results << LL_ENDL;
 +        LLSettingsDay::ptr_t();
 +    }
 +
 +    LLSettingsDay::ptr_t dayp = std::make_shared<LLSettingsVODay>(settings);
 +
 +    dayp->initialize();
 +    return dayp;
 +}
 +
 +
 +void LLSettingsVODay::buildFromOtherSetting(LLSettingsBase::ptr_t settings, LLSettingsVODay::asset_built_fn cb)
 +{
 +    if (settings->getSettingsType() == "daycycle")
 +    {
 +        if (cb)
 +            cb(std::static_pointer_cast<LLSettingsDay>(settings));
 +    }
 +    else
 +    {
 +        LLSettingsVOBase::getSettingsAsset(LLSettingsDay::GetDefaultAssetId(),
 +            [settings, cb](LLUUID, LLSettingsBase::ptr_t pday, S32, LLExtStat){ combineIntoDayCycle(std::static_pointer_cast<LLSettingsDay>(pday), settings, cb); });
 +    }
 +}
 +
 +void LLSettingsVODay::combineIntoDayCycle(LLSettingsDay::ptr_t pday, LLSettingsBase::ptr_t settings, asset_built_fn cb)
 +{
 +    if (settings->getSettingsType() == "sky")
 +    {
 +        pday->setName("sky: " + settings->getName());
 +        pday->clearCycleTrack(1);
 +        pday->setSettingsAtKeyframe(settings, 0.0, 1);
 +    }
 +    else if (settings->getSettingsType() == "water")
 +    {
 +        pday->setName("water: " + settings->getName());
 +        pday->clearCycleTrack(0);
 +        pday->setSettingsAtKeyframe(settings, 0.0, 0);
 +    }
 +    else
 +    {
 +        pday.reset();
 +    }
 +
 +    if (cb)
 +        cb(pday);
 +}
 +
 +
 +LLSettingsDay::ptr_t LLSettingsVODay::buildClone() const
 +{
 +    LLSD settings = cloneSettings();
 +
 +    LLSettingsDay::validation_list_t validations = LLSettingsDay::validationList();
 +    LLSD results = LLSettingsDay::settingValidation(settings, validations);
 +    if (!results["success"].asBoolean())
 +    {
 +        LL_WARNS("SETTINGS") << "Day setting validation failed!\n" << results << LL_ENDL;
 +        LLSettingsDay::ptr_t();
 +    }
 +
 +    LLSettingsDay::ptr_t dayp = std::make_shared<LLSettingsVODay>(settings);
 +
 +    U32 flags = getFlags();
 +    if (flags)
 +        dayp->setFlags(flags);
 +
 +    dayp->initialize();
 +    return dayp;
 +}
 +
 +LLSettingsDay::ptr_t LLSettingsVODay::buildDeepCloneAndUncompress() const
 +{
 +    // no need for SETTING_TRACKS or SETTING_FRAMES, so take base LLSD
 +    LLSD settings = llsd_clone(mSettings);
 +
 +    LLSettingsDay::ptr_t day_clone = std::make_shared<LLSettingsVODay>(settings);
 +
 +    for (S32 i = 0; i < LLSettingsDay::TRACK_MAX; ++i)
 +    {
 +        const LLSettingsDay::CycleTrack_t& track = getCycleTrackConst(i);
 +        LLSettingsDay::CycleTrack_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++;
 +        }
 +    }
 +    return day_clone;
 +}
 +
 +LLSD LLSettingsVODay::convertToLegacy(const LLSettingsVODay::ptr_t &pday)
 +{
 +    CycleTrack_t &trackwater = pday->getCycleTrack(TRACK_WATER);
 +
 +    LLSettingsWater::ptr_t pwater;
 +    if (!trackwater.empty())
 +    {
 +        pwater = std::static_pointer_cast<LLSettingsWater>((*trackwater.begin()).second);
 +    }
 +
 +    if (!pwater)
 +        pwater = LLSettingsVOWater::buildDefaultWater();
 +    
 +    LLSD llsdwater = LLSettingsVOWater::convertToLegacy(pwater);
 +    
 +    CycleTrack_t &tracksky = pday->getCycleTrack(1);   // first sky track
 +    std::map<std::string, LLSettingsSky::ptr_t> skys;
 +    
 +    LLSD llsdcycle(LLSD::emptyArray());
 +    
 +    for(CycleTrack_t::iterator it = tracksky.begin(); it != tracksky.end(); ++it)
 +    {
 +        size_t hash = (*it).second->getHash();
 +        std::stringstream name;
 +        
 +        name << hash;
 +        
 +        skys[name.str()] = std::static_pointer_cast<LLSettingsSky>((*it).second);
 +        
 +        F32 frame = ((tracksky.size() == 1) && (it == tracksky.begin())) ? -1.0f : (*it).first;
 +        llsdcycle.append( LLSDArray(LLSD::Real(frame))(name.str()) );
 +    }
 +    //_WARNS("LAPRAS") << "Cycle created with " << llsdcycle.size() << "entries: " << llsdcycle << LL_ENDL;
 +
 +    LLSD llsdskylist(LLSD::emptyMap());
 +    
 +    for (std::map<std::string, LLSettingsSky::ptr_t>::iterator its = skys.begin(); its != skys.end(); ++its)
 +    {
 +        LLSD llsdsky = LLSettingsVOSky::convertToLegacy((*its).second, false);
 +        llsdsky[SETTING_NAME] = (*its).first;
 +        
 +        llsdskylist[(*its).first] = llsdsky;
 +    }
 +
 +    //_WARNS("LAPRAS") << "Sky map with " << llsdskylist.size() << " entries created: " << llsdskylist << LL_ENDL;
 +    
 +    return LLSDArray(LLSD::emptyMap())(llsdcycle)(llsdskylist)(llsdwater);
 +}
 +
 +LLSettingsSkyPtr_t  LLSettingsVODay::getDefaultSky() const
 +{
 +    return LLSettingsVOSky::buildDefaultSky();
 +}
 +
 +LLSettingsWaterPtr_t LLSettingsVODay::getDefaultWater() const
 +{
 +    return LLSettingsVOWater::buildDefaultWater();
 +}
 +
 +LLSettingsSkyPtr_t LLSettingsVODay::buildSky(LLSD settings) const
 +{
 +    LLSettingsSky::ptr_t skyp = std::make_shared<LLSettingsVOSky>(settings);
 +
 +    if (skyp->validate())
 +        return skyp;
 +
 +    return LLSettingsSky::ptr_t();
 +}
 +
 +LLSettingsWaterPtr_t LLSettingsVODay::buildWater(LLSD settings) const
 +{
 +    LLSettingsWater::ptr_t waterp = std::make_shared<LLSettingsVOWater>(settings);
 +
 +    if (waterp->validate())
 +        return waterp;
 +
 +    return LLSettingsWater::ptr_t();
 +}
 +
 +//=========================================================================
 +namespace
 +{
 +    LLSD ensure_array_4(LLSD in, F32 fill)
 +    {
 +        if (in.size() >= 4)
 +            return in;
 +
 +        LLSD out(LLSD::emptyArray());
 +
 +        for (S32 idx = 0; idx < in.size(); ++idx)
 +        {
 +            out.append(in[idx]);
 +        }
 +
 +        while (out.size() < 4)
 +        {
 +            out.append(LLSD::Real(fill));
 +        }
 +        return out;
 +    }
 +
 +    // This is a disturbing hack
 +    std::string legacy_name_to_filename(const std::string &name, bool convertdash = false)
 +    {
 +        std::string fixedname(LLURI::escape(name));
 +
 +        if (convertdash)
 +            boost::algorithm::replace_all(fixedname, "-", "%2D");
 +
 +        return fixedname;
 +    }
 +
 +    //---------------------------------------------------------------------
 +    LLSD read_legacy_preset_data(const std::string &name, const std::string& path)
 +    {
 +        llifstream xml_file;
 +
 +        std::string full_path(path);
 +        std::string full_name(name);
 +        full_name += ".xml";
 +        gDirUtilp->append(full_path, full_name);
 +
 +        xml_file.open(full_path.c_str());
 +        if (!xml_file)
 +        {
 +            std::string bad_path(full_path);
 +            full_path = path;
 +            full_name = legacy_name_to_filename(name);
 +            full_name += ".xml";
 +            gDirUtilp->append(full_path, full_name);
 +
 +            LL_INFOS("LEGACYSETTING") << "Could not open \"" << bad_path << "\" trying escaped \"" << full_path << "\"" << LL_ENDL;
 +
 +            xml_file.open(full_path.c_str());
 +            if (!xml_file)
 +            {
 +                LL_WARNS("LEGACYSETTING") << "Unable to open legacy windlight \"" << name << "\" from " << path << LL_ENDL;
 +
 +                full_path = path;
 +                full_name = legacy_name_to_filename(name, true);
 +                full_name += ".xml";
 +                gDirUtilp->append(full_path, full_name);
 +                xml_file.open(full_path.c_str());
 +                if (!xml_file)
 +                {
 +                    LL_WARNS("LEGACYSETTING") << "Unable to open legacy windlight \"" << name << "\" from " << path << LL_ENDL;
 +                    return LLSD();
 +                }
 +            }
 +        }
 +
 +        LLSD params_data;
 +        LLPointer<LLSDParser> parser = new LLSDXMLParser();
 +        parser->parse(xml_file, params_data, LLSDSerialize::SIZE_UNLIMITED);
 +        xml_file.close();
 +
 +        return params_data;
 +    }
 +}
 | 
